You are here

protected static function FPAFormBuilder::buildTable in Fast Permissions Administration 3.0.x

Same name and namespace in other branches
  1. 8.2 src/FPAFormBuilder.php \Drupal\fpa\FPAFormBuilder::buildTable()

Builds the permissions table.

Parameters

array $form: Form element.

Return value

mixed Returns render array.

1 call to FPAFormBuilder::buildTable()
FPAFormBuilder::buildFPAPage in src/FPAFormBuilder.php
Builds the FPA pages.

File

src/FPAFormBuilder.php, line 94

Class

FPAFormBuilder
Class FPAFormBuilder.

Namespace

Drupal\fpa

Code

protected static function buildTable($form) {
  $renderer = \Drupal::service('renderer');
  $nameless_checkbox = [
    '#type' => 'html_tag',
    '#tag' => 'input',
    '#attributes' => [
      'type' => 'checkbox',
      'class' => [
        // Prevents Drupal core Drupal.behaviors.permissions.toggle from applying.
        'rid-anonymous',
        'form-checkbox',
        'fpa-checkboxes-toggle',
      ],
    ],
  ];
  $dummy_checkbox = [
    '#type' => 'html_tag',
    '#tag' => 'input',
    '#attributes' => [
      'type' => 'checkbox',
      'disabled' => 'disabled',
      'checked' => 'checked',
      'title' => t('This permission is inherited from the authenticated user role.'),
      'class' => [
        'dummy-checkbox',
      ],
    ],
  ];
  $dummy_checkbox_output = $renderer
    ->render($dummy_checkbox);
  $permission_col_template = [
    '#type' => 'container',
    '#attributes' => [
      'class' => [
        'fpa-permission-container',
      ],
    ],
    'description' => [],
    'checkbox_cell' => [
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'fpa-row-toggle-container',
        ],
      ],
      'checkbox_form_item' => [
        '#type' => 'container',
        '#attributes' => [
          'title' => t('Toggle visible checkboxes in this row.'),
          'class' => [
            'form-item',
            'form-type-checkbox',
          ],
        ],
        'label' => [
          '#type' => 'html_tag',
          '#tag' => 'label',
          '#attributes' => [
            'class' => [
              'visually-hidden',
            ],
          ],
          '#value' => 'test',
        ],
        'checkbox' => $nameless_checkbox,
      ],
    ],
  ];
  $roles = \Drupal::service('entity_type.manager')
    ->getStorage('user_role')
    ->loadMultiple();

  // Prepare role names processed by Html::getClass() ahead of time.
  $roles_attr_values = [];
  foreach ($roles as $role) {
    $roles_attr_values[$role
      ->get('id')] = Html::getClass($role
      ->get('label'));
  }

  // Lists for wrapper.
  $modules = [];
  $user_roles = [];

  // Index of current module row.
  $module = NULL;

  // Row counter.
  $i = 0;
  $rows = [];
  foreach (Element::children($form['permissions']) as $key) {

    // Row template.
    $row = [
      // Array of table cells.
      'data' => [],
      // HTML attribute on table row tag.
      'title' => [],
      // HTML attribute on table row tag.
      FPA_ATTR_MODULE => [],
      // HTML attribute on table row tag.
      FPA_ATTR_PERMISSION => [],
      FPA_ATTR_CHECKED => [],
      FPA_ATTR_NOT_CHECKED => [],
    ];
    $current_element = $form['permissions'][$key];
    hide($form['permissions'][$key]);
    $sub_children = Element::children($current_element);

    // Determine if row is module or permission.
    if (is_numeric($sub_children[0])) {

      // Module row.
      $row['class'][] = 'fpa-module-row';

      // Mark current row with escaped module name.
      $row[FPA_ATTR_MODULE] = [
        // System name.
        0 => $key,
        // Readable name.
        1 => strip_tags($current_element[0]['#markup']),
      ];

      // Readable.
      hide($form['permissions'][$key][0]);
      $row['data'][] = [
        'data' => $form['permissions'][$key][0],
        'class' => [
          'module',
        ],
        'id' => 'module-' . $key,
        'colspan' => count($form['role_names']['#value']) + 1,
      ];
      $row['title'] = [
        $key,
      ];
      $row[FPA_ATTR_SYSTEM_NAME] = $row[FPA_ATTR_MODULE][0];
      $classes = [];
      foreach ($row[FPA_ATTR_MODULE] as $item) {
        $classes[] = Html::getClass($item);
      }
      $row[FPA_ATTR_MODULE] = array_unique($classes);

      // Add modules to left-side modules list.
      $modules[$row[FPA_ATTR_MODULE][0]] = [
        'text' => strip_tags($current_element[0]['#markup']),
        'title' => [
          $key,
        ],
        FPA_ATTR_MODULE => $row[FPA_ATTR_MODULE],
        FPA_ATTR_PERMISSION => [],
      ];

      // Save row number for current module.
      $module = $i;
    }
    else {

      // Permission row.
      $row['class'][] = 'fpa-permission-row';
      $roles_keys = array_keys($roles_attr_values);
      $permission_system_name = (string) $form['permissions'][$key]['description']['#context']['title'];

      /*
      @todo Find out why this was done in D7
      $permission_system_name = '';
      // Might be empty if no modules are displayed in Permissions Filter module.
      if (!empty($sub_children[$roles_keys[0]])) {
        $permission_system_name = $sub_children[$roles_keys[0]['#return_value'];
      }
      */
      $label = $permission_col_template;
      $label['description'] = $current_element['description'];

      /*
      @todo Work on integration with permission filter module
      // Permissions filter might cause no Roles to display.
      if (count(element_children($form['checkboxes'])) == 0) {
        unset($label['checkbox_cell']);
      }
      */

      // Readable.
      $row['data'][] = [
        'data' => $label,
        'class' => [
          'permission',
        ],
      ];
      foreach ($roles_keys as $rid) {
        $checkbox = $form['permissions'][$key][$rid];
        hide($form['permissions'][$key][$rid]);
        $checkbox['#title'] = $roles[$rid]
          ->get('label') . ': ' . $checkbox['#title'];
        $checkbox['#title_display'] = 'invisible';

        // Filter permissions strips role id class from checkbox. Used by Drupal core functionality.
        $checkbox['#attributes']['class'][] = 'rid-' . $rid;

        // Set authenticated role behavior class on page load.
        if ($rid == 'authenticated' && $checkbox['#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.
        // @todo Needs further testing.
        if ($rid != 'anonymous' && $rid != 'authenticated') {

          // '#suffix' doesn't have wrapping HTML like '#field_suffix'.
          $checkbox['#suffix'] = $dummy_checkbox_output;
        }

        // Add rid's to row attribute for checked status filter.
        if ($checkbox['#checked'] === TRUE) {
          $row[FPA_ATTR_CHECKED][] = $rid;
        }
        else {
          $row[FPA_ATTR_NOT_CHECKED][] = $rid;
        }
        $row['data'][] = [
          'data' => $checkbox,
          'class' => [
            'checkbox',
          ],
          'title' => [
            $roles[$rid]
              ->get('label'),
          ],
          // For role filter.
          FPA_ATTR_ROLE => [
            $rid,
          ],
        ];
      }
      if (!empty($rid)) {
        $row['title'] = [
          $key,
        ];
        $row[FPA_ATTR_SYSTEM_NAME] = [
          $key,
        ];
      }

      // Mark current row with escaped permission name.
      $row[FPA_ATTR_PERMISSION] = [
        // Permission system name.
        0 => $permission_system_name,
        // Readable description.
        1 => (string) $form['permissions'][$key]['description']['#context']['title'],
      ];

      // Mark current row with current module.
      $row[FPA_ATTR_MODULE] = $rows[$module][FPA_ATTR_MODULE];
      $classes = [];
      foreach ($row[FPA_ATTR_PERMISSION] as $item) {
        $classes[] = Html::getClass($item);
      }
      $row[FPA_ATTR_PERMISSION] = array_unique($classes);

      // 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 = [
    '#type' => 'html_tag',
    '#tag' => 'input',
    '#attributes' => [
      '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 = [];
  foreach (Element::children($form['actions']) as $key) {
    $actions_output[] = $form['actions'][$key];
  }
  $header = [];
  $header[] = [
    'data' => [
      'label' => [
        '#type' => 'markup',
        '#markup' => t('Permission'),
      ],
      'actions' => $actions_output,
    ],
  ];
  foreach ($form['role_names']['#value'] as $rid => $label) {
    $header[] = [
      'data' => [
        'label' => [
          '#type' => 'markup',
          '#markup' => $label,
        ],
        'checkbox' => $nameless_checkbox,
      ],
      'class' => [
        'checkbox',
      ],
      'title' => [
        $label,
      ],
      FPA_ATTR_ROLE => [
        $rid,
      ],
    ];
    $user_roles[$rid] = $label;
  }
  $table = [
    'header' => $header,
    'rows' => $rows,
  ];
  $table_wrapper = static::buildTableWrapper($table, $modules, $user_roles, $actions_output);
  foreach (Element::children($form) as $key) {
    if ($key == 'actions' || $key == 'permissions') {
      continue;
    }
    $table_wrapper[$key] = $form[$key];
  }
  unset($form['role_names']);
  unset($form['permissions']);
  unset($form['actions']);
  $form['fpa_container'] = $table_wrapper;
  return $form;
}