access_policy-1.0.x-dev/src/Form/HandlerAddForm.php
src/Form/HandlerAddForm.php
<?php namespace Drupal\access_policy\Form; use Drupal\access_policy\AccessPolicyHandlerManager; use Drupal\access_policy\Entity\AccessPolicyInterface; use Drupal\access_policy\HandlerTableUiBuilder; use Drupal\access_policy\OperationsTableUiBuilder; use Drupal\access_policy\Plugin\access_policy\AccessPolicyHandlerInterface; use Drupal\Core\DependencyInjection\ClassResolverInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * The form for adding access rules to an access policy. * * This is actually a pseudo form, it's being loaded as part of * HandlerMultistepForm. Not in the route. */ class HandlerAddForm extends HandlerFormBase { /** * The bundle information service. * * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface */ protected $bundleInfo; /** * Field map static cache. * * @var array */ protected $fieldMap = []; /** * The access policy entity object. * * @var \Drupal\access_policy\Entity\AccessPolicyInterface */ protected $accessPolicy; /** * {@inheritdoc} */ public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, ClassResolverInterface $class_resolver, AccessPolicyHandlerManager $access_rule_manager, OperationsTableUiBuilder $ui_builder, HandlerTableUiBuilder $handler_table_builder, EntityTypeBundleInfoInterface $bundle_info) { parent::__construct($entity_type_manager, $entity_field_manager, $class_resolver, $access_rule_manager, $ui_builder, $handler_table_builder); $this->bundleInfo = $bundle_info; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('entity_type.manager'), $container->get('entity_field.manager'), $container->get('class_resolver'), $container->get('plugin.manager.access_policy.access_rule'), $container->get('access_policy.operations_table_ui_builder'), $container->get('access_policy.handler_table_ui_builder'), $container->get('entity_type.bundle.info') ); } /** * {@inheritdoc} */ public function getFormId() { return 'access_policy_add_rule_form'; } /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, AccessPolicyInterface $access_policy = NULL, $type = NULL) { $this->accessPolicy = $access_policy; $this->handlerType = $type; $form['#attributes']['class'][] = 'handler-modal-form'; $form['filter'] = [ '#title' => $this->t('Search'), '#type' => 'search', '#attributes' => [ 'class' => ['js-table-filter-text'], 'data-table' => '.js-reuse-table', 'autocomplete' => 'off', ], ]; // Show access rule plugins (if available). $definitions = $this->getApplicableHandlers(); // Sort the access rules by label. $definitions = $this->sortHandlers($definitions); $options = []; foreach ($definitions as $id => $access_rule) { $options[$id] = [ 'title' => [ 'data' => [ '#markup' => $access_rule->getDefinition()->getLabel(), ], 'class' => ['filterable'], ], 'description' => $this->getDescription($access_rule), ]; } $form['access_rules'] = [ '#type' => 'tableselect', '#js_select' => FALSE, '#header' => [ 'title' => $this->t('Title'), 'description' => $this->t('Description'), ], '#element_validate' => [[static::class, 'addHandlerValidate']], '#options' => $options, '#empty' => $this->t('No handlers found.'), '#attributes' => [ 'class' => ['js-reuse-table'], ], ]; $form['#attached']['library'][] = 'access_policy/access_policy.handlers'; return $form; } /** * Get the description of the access policy handler. * * @param \Drupal\access_policy\Plugin\access_policy\AccessPolicyHandlerInterface $handler * The access policy handler plugin. * * @return string * The description. */ protected function getDescription(AccessPolicyHandlerInterface $handler) { $description = $handler->getDefinition()->getDescription(); if (!empty($description)) { return $description; } // Get the "Appears in" text if no description is provided. if ($handler->getDefinition()->getFieldName()) { $field = $handler->getDefinition()->getFieldName(); if (empty($this->fieldMap)) { $this->fieldMap = $this->entityFieldManager->getFieldMap(); } $entity_type = $handler->getDefinition()->getEntityType(); if (!empty($this->fieldMap[$entity_type][$field]['bundles'])) { $bundles = $this->fieldMap[$entity_type][$field]['bundles']; $labels = $this->getBundleLabels($entity_type, $bundles); $bundles = implode(', ', $labels); return $this->t('Appears in: @bundles', ['@bundles' => $bundles]); } } return ''; } /** * Get the bundle labels. * * @param string $entity_type * The entity type. * @param array $bundles * The array of bundle ids. * * @return array * Array of bundle labels. */ protected function getBundleLabels($entity_type, array $bundles) { $labels = []; $bundle_info = $this->bundleInfo->getBundleInfo($entity_type); foreach ($bundles as $bundle) { $labels[] = $bundle_info[$bundle]['label']; } return $labels; } /** * Validate the access rule selection. * * @param array $form * The current form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current form state. */ public static function addHandlerValidate(array $form, FormStateInterface $form_state) { $access_rules = $form_state->getValue('access_rules'); $selected_rules = array_filter($access_rules); if (empty($selected_rules)) { $form_state->setErrorByName('access_rules', 'Please select a handler.'); } if (count($selected_rules) > 1) { $form_state->setErrorByName('access_rules', 'Only one handler can be added at a time.'); } } /** * Sort the access rules by label. * * @param array $access_rules * Array of access rule plugins. * * @return array * Array of sorted access rule plugins. */ protected function sortHandlers(array $access_rules) { $key_value = []; foreach ($access_rules as $id => $rule) { $key_value[$id] = $rule->getDefinition()->getLabel(); } natsort($key_value); $sorted = []; foreach ($key_value as $id => $label) { $sorted[$id] = $access_rules[$id]; } return $sorted; } /** * Returns all applicable access rules for this policy. * * @return array * Array of applicable access rules. */ public function getApplicableHandlers() { $supported_groups = [ 'global', 'user', $this->accessPolicy->getTargetEntityTypeId(), ]; $rules = []; foreach ($supported_groups as $group) { $group_rules = $this->getHandlerManager()->getHandlersByGroup($group); $rules = array_merge($rules, $group_rules); } return $rules; } }