array( 'render element' => 'form', 'file' => 'fpa.theme.inc', ), ); } /** * Theme function to pre-mark rows with FPA attributes. * * Based on Drupal Core's permissions form theme function. * * @see theme_user_admin_permissions(). */ function theme_fpa_user_admin_permissions($variables) { $form = $variables['form']; $nameless_checkbox = array( '#type' => 'html_tag', '#tag' => 'input', '#attributes' => array( 'type' => 'checkbox', 'class' => array( 'rid-1', // Prevents Drupal core Drupal.behaviors.permissions.toggle from applying. 'form-checkbox', 'fpa-checkboxes-toggle', ), ), ); $nameless_checkbox_output = drupal_render($nameless_checkbox); $dummy_checkbox = array( '#type' => 'html_tag', '#tag' => 'input', '#attributes' => array( 'type' => 'checkbox', 'disabled' => 'disabled', 'checked' => 'checked', 'title' => t('This permission is inherited from the authenticated user role.'), 'class' => array( 'dummy-checkbox', ), ), ); $dummy_checkbox_output = drupal_render($dummy_checkbox); $permission_col_template = array( '#type' => 'container', '#attributes' => array( 'class' => array( 'fpa-permission-container', ), ), 'description' => array( '#markup' => '', ), 'checkbox_cell' => array( '#type' => 'container', '#attributes' => array( 'class' => array( 'fpa-row-toggle-container', ), ), 'checkbox_form_item' => array( '#type' => 'container', '#attributes' => array( 'title' => t('Toggle visible checkboxes in this row.'), 'class' => array( 'form-item', 'form-type-checkbox', ), ), 'label' => array( '#type' => 'html_tag', '#tag' => 'label', '#attributes' => array( 'class' => array( 'element-invisible', ), ), '#value' => 'test', ), 'checkbox' => array( '#markup' => $nameless_checkbox_output, ), ), ), ); $checkboxes_children = element_children($form['checkboxes']); // Prepare role names processed by drupal_html_class() ahead of time. $roles_attr_values = array(); foreach ($checkboxes_children as $rid) { $roles_attr_values[$rid] = drupal_html_class($form['role_names'][$rid]['#markup']); } $first_role_index = array_shift($checkboxes_children); // Lists for wrapper. $modules = array(); $user_roles = array(); // Index of current module row. $module = NULL; // Row counter. $i = 0; $rows = array(); // Iterate over rows in form table. foreach (element_children($form['permission']) as $key) { // Row template. $row = array( 'data' => array(), // Array of table cells. 'title' => array(), // HTML attribute on table row tag. FPA_ATTR_MODULE => array(), // HTML attribute on table row tag. FPA_ATTR_PERMISSION => array(), // HTML attribute on table row tag. FPA_ATTR_CHECKED => array(), FPA_ATTR_NOT_CHECKED => array(), ); // Determine if row is module or permission. if (is_numeric($key)) { // Module row. $row['class'][] = 'fpa-module-row'; // Mark current row with escaped module name. $row[FPA_ATTR_MODULE] = array( // System name 0 => $form['permission'][$key]['#id'], // Readable name 1 => strip_tags($form['permission'][$key]['#markup']), ); // Readable $row['data'][] = array( 'data' => drupal_render($form['permission'][$key]), 'class' => array('module'), 'id' => 'module-' . $form['permission'][$key]['#id'], 'colspan' => count($form['role_names']['#value']) + 1, ); $row['title'] = array($form['permission'][$key]['#id']); $row[FPA_ATTR_SYSTEM_NAME] = $row[FPA_ATTR_MODULE][0]; $row[FPA_ATTR_MODULE] = array_unique(array_map('drupal_html_class', $row[FPA_ATTR_MODULE])); // Add modules to left-side modules list. $modules[$row[FPA_ATTR_MODULE][0]] = array( 'text' => strip_tags($form['permission'][$key]['#markup']), 'title' => array($form['permission'][$key]['#id']), FPA_ATTR_MODULE => $row[FPA_ATTR_MODULE], FPA_ATTR_PERMISSION => array(), ); // Save row number for current module. $module = $i; } else { // Permission row. $row['class'][] = 'fpa-permission-row'; $permission_system_name = ''; // Might be empty if no modules are displayed in Permissions Filter module. if (!empty($form['checkboxes'][$first_role_index])) { $permission_system_name = $form['checkboxes'][$first_role_index][$key]['#return_value']; } $label = $permission_col_template; $label['description']['#markup'] = drupal_render($form['permission'][$key]); // Permissions filter might cause no Roles to display. if (count(element_children($form['checkboxes'])) == 0) { unset($label['checkbox_cell']); } // Readable $row['data'][] = array( 'data' => drupal_render($label), 'class' => array('permission'), ); foreach (element_children($form['checkboxes']) as $rid) { $form['checkboxes'][$rid][$key]['#title'] = $form['role_names'][$rid]['#markup'] . ': ' . $form['permission'][$key]['#markup']; $form['checkboxes'][$rid][$key]['#title_display'] = 'invisible'; // Filter permissions strips role id class from checkbox. Used by Drupal core functionality. $form['checkboxes'][$rid][$key]['#attributes']['class'][] = 'rid-' . $rid; // Set authenticated role behavior class on page load. if ($rid == 2 && $form['checkboxes'][$rid][$key]['#checked'] === TRUE) { $row['class'][] = 'fpa-authenticated-role-behavior'; } // For all roles that inherit permissions from 'authenticated user' role, add in dummy checkbox for authenticated role behavior. if ($rid > 2) { $form['checkboxes'][$rid][$key]['#suffix'] = $dummy_checkbox_output; // '#suffix' doesn't have wrapping HTML like '#field_suffix'. } // Add rid's to row attribute for checked status filter. if ($form['checkboxes'][$rid][$key]['#checked'] === TRUE) { $row[FPA_ATTR_CHECKED][] = $rid; } else { $row[FPA_ATTR_NOT_CHECKED][] = $rid; } $row['data'][] = array( 'data' => drupal_render($form['checkboxes'][$rid][$key]), 'class' => array( 'checkbox', ), 'title' => array( $form['role_names'][$rid]['#markup'], ), // For role filter FPA_ATTR_ROLE => array( $rid, ), ); } if (!empty($rid)) { $row['title'] = array( $form['checkboxes'][$rid][$key]['#return_value'], ); $row[FPA_ATTR_SYSTEM_NAME] = array( $form['checkboxes'][$rid][$key]['#return_value'], ); } // Mark current row with escaped permission name. $row[FPA_ATTR_PERMISSION] = array( // Permission system name. 0 => $permission_system_name, // Readable description. 1 => strip_tags($form['permission'][$key]['#markup']), ); // Mark current row with current module. $row[FPA_ATTR_MODULE] = $rows[$module][FPA_ATTR_MODULE]; $row[FPA_ATTR_PERMISSION] = array_unique(array_map('drupal_html_class', $row[FPA_ATTR_PERMISSION])); // Add current permission to current module row. $rows[$module][FPA_ATTR_PERMISSION] = array_merge($rows[$module][FPA_ATTR_PERMISSION], $row[FPA_ATTR_PERMISSION]); $rows[$module][FPA_ATTR_CHECKED] = array_unique(array_merge($rows[$module][FPA_ATTR_CHECKED], $row[FPA_ATTR_CHECKED])); $rows[$module][FPA_ATTR_NOT_CHECKED] = array_unique(array_merge($rows[$module][FPA_ATTR_NOT_CHECKED], $row[FPA_ATTR_NOT_CHECKED])); $modules[$rows[$module][FPA_ATTR_MODULE][0]][FPA_ATTR_PERMISSION][] = $row[FPA_ATTR_PERMISSION]; } $rows[$i++] = $row; } $reset_button = array( '#type' => 'html_tag', '#tag' => 'input', '#attributes' => array( 'type' => 'reset', 'class' => 'form-submit', 'value' => t('Reset changes'), ), ); // If there is no submit button, don't add the reset button. if (count(element_children($form['actions'])) > 0) { // Have the reset button appear before the submit button. array_unshift($form['actions'], $reset_button); } $actions_output = drupal_render_children($form['actions']); $header = array(); $header[] = array( 'data' => t('Permission') . $actions_output, ); foreach (element_children($form['role_names']) as $rid) { $header[] = array( 'data' => drupal_render($form['role_names'][$rid]) . $nameless_checkbox_output, 'class' => array( 'checkbox', ), 'title' => array( $form['role_names'][$rid]['#markup'], ), FPA_ATTR_ROLE => array( $rid, ), ); $user_roles[$rid] = $form['role_names'][$rid]['#markup']; } $table = array( 'header' => $header, 'rows' => $rows, ); $output = _fpa_wrapper($table, $modules, $user_roles, $actions_output); $output .= drupal_render_children($form); return $output; } /** * Wraps table output in the FPA filter. */ function _fpa_wrapper($permissions_table, $modules, $user_roles, $actions_output) { $same_page = trim(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_PATH), '/') == $_GET['q']; $render = array( '#type' => 'container', '#attributes' => array( 'class' => array( 'fpa-container', ), ), ); $hiders = array( 'fpa-hide-descriptions' => array( 'hide' => t('Hide descriptions'), 'show' => t('Show descriptions'), ), 'fpa-hide-system-names' => array( 'hide' => t('Hide system names'), 'show' => t('Show system names'), ), ); $render['#attributes']['class'][] = 'fpa-hide-system-names'; $hide_container = array( '#type' => 'container', '#attributes' => array( 'class' => array( 'fpa-toggle-container', ), ), ); foreach ($hiders as $hide_class => $labels) { $hide_container[$hide_class] = array( '#theme' => 'link', '#text' => '', '#path' => '', '#options' => array( 'attributes' => array_merge($labels, array( 'fpa-toggle-class' => $hide_class, )), 'html' => TRUE, 'fragment' => ' ', 'external' => TRUE, // Prevent base path from being added to link. ), ); } $render['hide_container'] = $hide_container; $wrapper = array( '#type' => 'container', '#attributes' => array( 'class' => array( 'fpa-wrapper', ), ), ); $render['wrapper'] = &$wrapper; /** *