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

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

namespace Drupal\access_policy_ui\Form;

use Drupal\access_policy\AccessPolicyOperationPluginManager;
use Drupal\access_policy\Entity\AccessPolicyInterface;
use Drupal\access_policy\Plugin\access_policy\AccessPolicyOperation\AccessPolicyOperationInterface;
use Drupal\access_policy_ui\OperationsTableUiBuilder;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseDialogCommand;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\PermissionHandlerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides a form for enabling/disabling operations.
 *
 * @package Drupal\access_policy\Form
 */
class AccessPolicyOperationsForm extends EntityForm {

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

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

  /**
   * The operation plugin manager.
   *
   * @var \Drupal\access_policy\AccessPolicyOperationPluginManager
   */
  protected $operationPluginManager;

  /**
   * Constructs a new AccessPolicyPermissionsForm.
   *
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager service.
   * @param \Drupal\user\PermissionHandlerInterface $permission_handler
   *   The user permission handler.
   * @param \Drupal\access_policy_ui\OperationsTableUiBuilder $ui_builder
   *   The operations table ui builder.
   * @param \Drupal\access_policy\AccessPolicyOperationPluginManager $operation_plugin_manager
   *   The operation plugin manager.
   */
  public function __construct(ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_type_manager, PermissionHandlerInterface $permission_handler, OperationsTableUiBuilder $ui_builder, AccessPolicyOperationPluginManager $operation_plugin_manager) {
    $this->moduleHandler = $module_handler;
    $this->entityTypeManager = $entity_type_manager;
    $this->permissionHandler = $permission_handler;
    $this->operationsTableUiBuilder = $ui_builder;
    $this->operationPluginManager = $operation_plugin_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('module_handler'),
      $container->get('entity_type.manager'),
      $container->get('user.permissions'),
      $container->get('access_policy.operations_table_ui_builder'),
      $container->get('plugin.manager.access_policy_operation')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {
    $form = parent::form($form, $form_state);

    $form['help'] = [
      '#type' => 'markup',
      '#markup' => '<p>' . $this->t('Choose which operations you want this access policy to control and how. Select permission to create a new a permission, select access rules for more fine-grained access control. Note that disabling a permission will automatically remove it from all roles.') . '</p>',
    ];

    $form['operations'] = [
      '#type' => 'table',
      '#header' => [
        $this->t('Operations'),
        $this->t('Permission'),
        $this->t('Access rules'),
        $this->t('Show column'),
      ],
    ];

    foreach ($this->getOperations() as $op => $operation) {
      $form['operations'][$op]['label'] = [
        '#type' => 'markup',
        '#markup' => $operation->getLabel(),
      ];
      $form['operations'][$op]['permission'] = [
        '#type' => 'checkbox',
        '#default_value' => $this->entity->getOperationsHandler()->shouldValidatePermission($op),
        '#disabled' => !$operation->supportsPermissions() || $this->isPermissionDefinedElsewhere($operation, $this->entity),
      ];
      $form['operations'][$op]['access_rules'] = [
        '#type' => 'checkbox',
        '#default_value' => $this->entity->getOperationsHandler()->shouldValidateAccessRules($op),
        '#disabled' => !$operation->supportsAccessRules(),
      ];
      $form['operations'][$op]['show_column'] = [
        '#type' => 'checkbox',
        '#default_value' => $this->entity->getOperationsHandler()->showColumn($op),
      ];
    }

    return $form;
  }

  /**
   * Determine whether operation supports permissions but does not define it.
   *
   * If the permission is defined elsewhere then it needs to be required
   * because we have no control over it.
   *
   * @param \Drupal\access_policy\Plugin\access_policy\AccessPolicyOperation\AccessPolicyOperationInterface $operation
   *   The operation plugin.
   * @param \Drupal\access_policy\Entity\AccessPolicyInterface $access_policy
   *   The access policy.
   *
   * @return bool
   *   TRUE if the permission is defined elsewhere; FALSE otherwise.
   */
  protected function isPermissionDefinedElsewhere(AccessPolicyOperationInterface $operation, AccessPolicyInterface $access_policy) {
    if ($operation->supportsPermissions() && !$operation->isPermissionOwner($access_policy)) {
      return TRUE;
    }

    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  protected function actions(array $form, FormStateInterface $form_state) {
    $actions['actions'] = ['#type' => 'actions'];
    $actions['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Save operations'),
      '#button_type' => 'primary',
      '#submit' => ['::submitForm', '::save'],
      '#ajax' => [
        'callback' => [$this, 'ajaxSubmitCallback'],
        'disable-refocus' => TRUE,
      ],
    ];

    return $actions;
  }

  /**
   * Get the operations.
   *
   * @return \Drupal\access_policy\Plugin\access_policy\AccessPolicyOperation\AccessPolicyOperationInterface[]
   *   Array of operations plugins.
   */
  public function getOperations() {
    $plugins = $this->operationPluginManager->getApplicable($this->entity->getTargetEntityType());

    $options = [];
    foreach ($plugins as $id => $plugin) {
      $options[$id] = $plugin;
    }

    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    $entity = $this->entity;
    $values = $form_state->getValues();

    $operations = $form_state->getValue('operations');
    $handlers = $this->filterInvalidAccessRuleOperations($entity->getHandlers('access_rule'), $operations);
    $entity->setHandlers('access_rule', $handlers);

    $entity->setOperations($values['operations']);
    $status = $entity->save();

    $this->removeInvalidPermissions();

    return $status;
  }

  /**
   * Remove any invalid permissions on all user roles.
   */
  protected function removeInvalidPermissions() {
    $permission_definitions = $this->permissionHandler->getPermissions();
    $roles = $this->entityTypeManager->getStorage('user_role')->loadMultiple();
    foreach ($roles as $role) {
      $permissions = $role->getPermissions();
      $valid_permissions = array_intersect($permissions, array_keys($permission_definitions));
      $invalid_permissions = array_diff($permissions, $valid_permissions);
      if (!empty($invalid_permissions)) {
        user_role_revoke_permissions($role->id(), $invalid_permissions);
      }
    }
  }

  /**
   * Remove any invalid access rule operation overrides.
   *
   * Remove any operations on access rules that are no longer supported. If no
   * access rules are supported then it will remove all the access rules.
   *
   * @return array
   *   Array of handlers with operations filtered.
   */
  protected function filterInvalidAccessRuleOperations(array $handlers, array $operations) {
    $allowed_operations = [];
    foreach ($operations as $op => $operation) {
      if ($operation['access_rules']) {
        $allowed_operations[] = $op;
      }
    }

    // If access rule are not supported then we should remove all the access
    // rules.
    if (empty($allowed_operations)) {
      return [];
    }

    foreach ($handlers as &$handler) {
      // If operations are defined then remove that operation from the array
      // If applicable.
      if (isset($handler['settings']['operations'])) {
        $handler['settings']['operations'] = array_values(array_intersect($allowed_operations, $handler['settings']['operations']));
      }
    }

    return $handlers;
  }

  /**
   * 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->entity->id());
      $role_operations = $this->operationsTableUiBuilder->build($access_policy);
      $response->addCommand(new CloseDialogCommand());
      $response->addCommand(new HtmlCommand('#role-operations', $role_operations));
    }
    return $response;
  }

}

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

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