access_policy-1.0.x-dev/modules/access_policy_ui/src/Form/AccessPolicyPermissionsForm.php

modules/access_policy_ui/src/Form/AccessPolicyPermissionsForm.php
<?php

namespace Drupal\access_policy_ui\Form;

use Drupal\access_policy\Entity\AccessPolicyInterface;
use Drupal\access_policy_ui\OperationsTableUiBuilder;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseDialogCommand;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Config\ConfigManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleExtensionList;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\user\PermissionHandlerInterface;
use Drupal\user\RoleInterface;
use Drupal\user\RoleStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\Route;

/**
 * Provides the permissions administration form for an access policy.
 *
 * This uses most of the code found in UserPermissionsForm and adds support
 * for ajax submission. Note that this does not extend that class because that
 * is marked as internal.
 *
 * @see \Drupal\user\Form\UserPermissionsForm
 */
class AccessPolicyPermissionsForm extends FormBase {

  /**
   * The permission handler.
   *
   * @var \Drupal\user\PermissionHandlerInterface
   */
  protected $permissionHandler;

  /**
   * The role storage.
   *
   * @var \Drupal\user\RoleStorageInterface
   */
  protected $roleStorage;

  /**
   * The module extension list.
   *
   * @var \Drupal\Core\Extension\ModuleExtensionList
   */
  protected $moduleList;

  /**
   * The configuration entity manager.
   *
   * @var \Drupal\Core\Config\ConfigManagerInterface
   */
  protected $configManager;

  /**
   * The entity type manager service.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The operations table ui builder.
   *
   * @var \Drupal\access_policy_ui\OperationsTableUiBuilder
   */
  protected $operationsTableUiBuilder;

  /**
   * The access policy object.
   *
   * @var \Drupal\Core\Entity\EntityInterface
   */
  protected $accessPolicy;

  /**
   * The user role.
   *
   * @var \Drupal\user\RoleInterface
   */
  protected $userRole;

  /**
   * Constructs a new AccessPolicyPermissionsForm.
   *
   * @param \Drupal\user\PermissionHandlerInterface $permission_handler
   *   The permission handler.
   * @param \Drupal\user\RoleStorageInterface $role_storage
   *   The role storage.
   * @param \Drupal\Core\Extension\ModuleExtensionList $module_list
   *   The module extension list.
   * @param \Drupal\Core\Config\ConfigManagerInterface $config_manager
   *   The configuration entity manager.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager service.
   * @param \Drupal\access_policy_ui\OperationsTableUiBuilder $ui_builder
   *   The operations table ui builder.
   */
  public function __construct(PermissionHandlerInterface $permission_handler, RoleStorageInterface $role_storage, ModuleExtensionList $module_list, ConfigManagerInterface $config_manager, EntityTypeManagerInterface $entity_type_manager, OperationsTableUiBuilder $ui_builder) {
    $this->permissionHandler = $permission_handler;
    $this->roleStorage = $role_storage;
    $this->moduleList = $module_list;
    $this->configManager = $config_manager;
    $this->entityTypeManager = $entity_type_manager;
    $this->operationsTableUiBuilder = $ui_builder;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('user.permissions'),
      $container->get('entity_type.manager')->getStorage('user_role'),
      $container->get('extension.list.module'),
      $container->get('config.manager'),
      $container->get('entity_type.manager'),
      $container->get('access_policy.operations_table_ui_builder')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'access_policy_user_permissions';
  }

  /**
   * {@inheritdoc}
   */
  protected function permissionsByProvider(): array {
    $config_name = $this->accessPolicy->getConfigDependencyName();
    $config_entities = $this->configManager
      ->getConfigEntitiesToChangeOnDependencyRemoval('config', [$config_name]);
    $config_names = array_map(
      function ($dependent_config) {
        return $dependent_config->getConfigDependencyName();
      }, $config_entities['delete'] ?? []
    );
    $config_names[] = $config_name;

    // Find all the permissions that depend on $this->bundle.
    $permissions = $this->permissionHandler->getPermissions();
    $permissions_by_provider = [];
    foreach ($permissions as $permission_name => $permission) {
      $required_configs = $permission['dependencies']['config'] ?? [];
      if (array_intersect($required_configs, $config_names)) {
        $provider = $permission['provider'];
        $permissions_by_provider[$provider][$permission_name] = $permission;
      }
    }

    return $permissions_by_provider;
  }

  /**
   * Gets the roles to display in this form.
   *
   * @return \Drupal\user\RoleInterface[]
   *   An array of role objects.
   */
  protected function getRoles() {
    return [$this->userRole->id() => $this->userRole];
  }

  /**
   * Builds the user permissions administration form for an access policy.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   * @param \Drupal\access_policy\Entity\AccessPolicyInterface $access_policy
   *   The access policy entity.
   * @param \Drupal\user\RoleInterface|null $user_role
   *   The user role.
   */
  public function buildForm(array $form, FormStateInterface $form_state, AccessPolicyInterface|null $access_policy = NULL, RoleInterface|null $user_role = NULL): array {
    $this->accessPolicy = $access_policy;
    $this->userRole = $user_role;

    $role_names = [];
    $role_permissions = [];
    $admin_roles = [];
    foreach ($this->getRoles() as $role_name => $role) {
      // Retrieve role names for columns.
      $role_names[$role_name] = $role->label();
      // Fetch permissions for the roles.
      $role_permissions[$role_name] = $role->getPermissions();
      $admin_roles[$role_name] = $role->isAdmin();
    }

    // Store $role_names for use when saving the data.
    $form['role_names'] = [
      '#type' => 'value',
      '#value' => $role_names,
    ];
    // Render role/permission overview:
    $hide_descriptions = system_admin_compact_mode();

    $form['permissions'] = [
      '#type' => 'table',
      '#header' => [$this->t('Permission')],
      '#id' => 'permissions',
      '#attributes' => ['class' => ['permissions', 'js-permissions']],
    ];
    foreach ($role_names as $name) {
      $form['permissions']['#header'][] = [
        'data' => $name,
        'class' => ['checkbox'],
      ];
    }

    foreach ($this->permissionsByProvider() as $provider => $permissions) {
      // Module name.
      $form['permissions'][$provider] = [
        [
          '#wrapper_attributes' => [
            'colspan' => count($role_names) + 1,
            'class' => ['module'],
            'id' => 'module-' . $provider,
          ],
          '#markup' => $this->moduleList->getName($provider),
        ],
      ];
      foreach ($permissions as $perm => $perm_item) {
        // Fill in default values for the permission.
        $perm_item += [
          'description' => '',
          'restrict access' => FALSE,
          'warning' => !empty($perm_item['restrict access']) ? $this->t('Warning: Give to trusted roles only; this permission has security implications.') : '',
        ];
        $form['permissions'][$perm]['description'] = [
          '#type' => 'inline_template',
          '#template' => '<div class="permission"><span class="title">{{ title }}</span>{% if description or warning %}<div class="description">{% if warning %}<em class="permission-warning">{{ warning }}</em> {% endif %}{{ description }}</div>{% endif %}</div>',
          '#context' => [
            'title' => $perm_item['title'],
          ],
        ];
        // Show the permission description.
        if (!$hide_descriptions) {
          $form['permissions'][$perm]['description']['#context']['description'] = $perm_item['description'];
          $form['permissions'][$perm]['description']['#context']['warning'] = $perm_item['warning'];
        }
        foreach ($role_names as $rid => $name) {
          $form['permissions'][$perm][$rid] = [
            '#title' => $name . ': ' . $perm_item['title'],
            '#title_display' => 'invisible',
            '#wrapper_attributes' => [
              'class' => ['checkbox'],
            ],
            '#type' => 'checkbox',
            '#default_value' => in_array($perm, $role_permissions[$rid]) ? 1 : 0,
            '#attributes' => ['class' => ['rid-' . $rid, 'js-rid-' . $rid]],
            '#parents' => [$rid, $perm],
          ];
          // Show a column of disabled but checked checkboxes.
          if ($admin_roles[$rid]) {
            $form['permissions'][$perm][$rid]['#disabled'] = TRUE;
            $form['permissions'][$perm][$rid]['#default_value'] = TRUE;
          }
        }
      }
    }

    $form['actions'] = ['#type' => 'actions'];
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Save permissions'),
      '#button_type' => 'primary',
      '#submit' => ['::submitForm'],
      '#ajax' => [
        'callback' => [$this, 'ajaxSubmitCallback'],
        'disable-refocus' => TRUE,
      ],
    ];

    $form['#attached']['library'][] = 'user/drupal.user.permissions';

    return $form;
  }

  /**
   * Ajax callback to close the modal and update the selected rules.
   *
   * @param array $form
   *   The form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current form state.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   An ajax response object.
   */
  public function ajaxSubmitCallback(array $form, FormStateInterface $form_state) {
    $response = new AjaxResponse();

    if (!$form_state::hasAnyErrors()) {
      // Make sure that the access policy is up-to-date before rebuilding.
      $access_policy = $this->entityTypeManager->getStorage('access_policy')->load($this->accessPolicy->id());
      $role_operations = $this->operationsTableUiBuilder->build($access_policy);
      $response->addCommand(new CloseDialogCommand());
      $response->addCommand(new HtmlCommand('#role-operations', $role_operations));
    }
    return $response;
  }

  /**
   * Checks that there are permissions to be managed.
   *
   * @param \Symfony\Component\Routing\Route $route
   *   The route to check against.
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The parametrized route.
   * @param \Drupal\access_policy\Entity\AccessPolicyInterface|null $access_policy
   *   The access policy.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   The access result.
   */
  public function access(Route $route, RouteMatchInterface $route_match, AccessPolicyInterface|null $access_policy = NULL): AccessResultInterface {
    if ($access_policy instanceof EntityInterface) {
      $this->accessPolicy = $access_policy;
    }

    if (empty($this->accessPolicy)) {
      // A typo in the request path can lead to this case.
      return AccessResult::forbidden();
    }

    return AccessResult::allowedIf((bool) $this->permissionsByProvider());
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Added in order to remove the status message.
    foreach ($form_state->getValue('role_names') as $role_name => $name) {
      user_role_change_permissions($role_name, (array) $form_state->getValue($role_name));
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc