access_policy-1.0.x-dev/src/Plugin/access_policy/SelectionRule/EntityFieldBase.php

src/Plugin/access_policy/SelectionRule/EntityFieldBase.php
<?php

namespace Drupal\access_policy\Plugin\access_policy\SelectionRule;

use Drupal\access_policy\Plugin\access_policy\OperatorValidationTrait;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\PermissionHandlerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * The entity field base for selection rules.
 */
class EntityFieldBase extends SelectionRuleBase {

  use OperatorValidationTrait;

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The entity field manager.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected $entityFieldManager;

  /**
   * The field type plugin manager.
   *
   * @var \Drupal\Core\Field\FieldTypePluginManagerInterface
   */
  protected $fieldTypeManager;

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

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

  /**
   * Constructs a EntityFieldBase object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
   *   The entity field manager.
   * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager
   *   The field type plugin manager.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\user\PermissionHandlerInterface $permission_handler
   *   The permission handler.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler, EntityFieldManagerInterface $entity_field_manager, FieldTypePluginManagerInterface $field_type_manager, EntityTypeManagerInterface $entity_type_manager, PermissionHandlerInterface $permission_handler) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->moduleHandler = $module_handler;
    $this->entityFieldManager = $entity_field_manager;
    $this->fieldTypeManager = $field_type_manager;
    $this->entityTypeManager = $entity_type_manager;
    $this->permissionHandler = $permission_handler;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('module_handler'),
      $container->get('entity_field.manager'),
      $container->get('plugin.manager.field.field_type'),
      $container->get('entity_type.manager'),
      $container->get('user.permissions'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function defaultSettings() {
    return [
      'value' => '',
      'field_access' => [
        'type' => 'none',
      ],
    ] + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function isApplicable(EntityInterface $entity) {
    $field_name = $this->definition->getFieldName();
    if ($entity->hasField($field_name)) {
      return TRUE;
    }
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function validate(EntityInterface $entity, AccountInterface $account) {
    return $this->validateCallback($entity, $account);
  }

  /**
   * Validate method callback.
   *
   * For multi-value fields, validation callbacks operate on each value. This
   * is to align with how queries match content with conditions.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The current entity.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The current user.
   *
   * @return bool
   *   TRUE if valid; FALSE otherwise.
   */
  public function validateCallback(EntityInterface $entity, AccountInterface $account) {
    $operator = $this->getOperator();
    $info = $this->operators();

    // If the values should not be passed then pass in the original entity and
    // account.
    if (isset($info[$operator]['values']) && $info[$operator]['values'] === FALSE) {
      $valid = $this->{$info[$operator]['method']}($entity, $account);
      if ($valid) {
        return TRUE;
      }
      return FALSE;
    }

    $field_name = $this->definition->getFieldName();
    $field_values = $this->getEntityFieldValues($entity, $field_name);
    $options = $this->getValue();

    if (!empty($info[$operator]['method'])) {
      // If field values are empty we should still validate against it.
      if (empty($field_values)) {
        foreach ($options as $option) {
          $valid = $this->{$info[$operator]['method']}($option, $field_values);
          if ($valid) {
            return TRUE;
          }
        }
      }
      else {
        // If any of the field values match then return true.
        foreach ($field_values as $value) {
          foreach ($options as $option) {
            $valid = $this->{$info[$operator]['method']}($option, $value);
            if ($valid) {
              return TRUE;
            }
          }
        }
      }
    }

    return FALSE;
  }

  /**
   * Validate is applicable.
   *
   * In some cases a simple field exists validation is enough. This is
   * particularly true for manual selection workflow.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The current entity.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The current user.
   *
   * @return bool
   *   TRUE if the entity is applicable; FALSE otherwise.
   */
  public function validateIsApplicable(EntityInterface $entity, AccountInterface $account) {
    return $this->isApplicable($entity);
  }

  /**
   * {@inheritdoc}
   */
  protected function valueForm(array &$form, FormStateInterface $form_state) {
    $form['value'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Value'),
      '#default_value' => $this->settings['value'],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildSettingsForm(array $form, FormStateInterface $form_state) {
    $this->operatorForm($form, $form_state);
    $this->valueForm($form, $form_state);
    $this->hideValueFormWithStates($form, $form_state);

    $form['field_access'] = [
      '#type' => 'details',
      '#title' => $this->t('Field access'),
      '#tree' => TRUE,
    ];
    $form['field_access']['help'] = [
      '#type' => 'markup',
      '#markup' => $this->t('<strong>Warning:</strong> This is a global setting. All instances of this field will be affected regardless of policy assigned.'),
    ];
    $form['field_access']['type'] = [
      '#type' => 'radios',
      '#title' => $this->t('Access'),
      '#options' => [
        'none' => $this->t('Unrestricted'),
        'permission' => $this->t('Permission'),
      ],
      '#default_value' => $this->settings['field_access']['type'],
    ];
    $form['field_access']['permission'] = [
      '#type' => 'select',
      '#title' => $this->t('Permission'),
      '#options' => $this->getPermissionsOptions(),
      '#description' => $this->t('Only users with the selected permission will be able to access this field.'),
      '#states' => [
        'visible' => [':input[name="field_access[type]"]' => ['value' => 'permission']],
      ],
      '#default_value' => $this->settings['field_access']['permission'] ?? $this->getDefaultPermission(),
    ];

    $form['admin_label'] = [
      '#type' => 'details',
      '#title' => $this->t('Administrative title'),
      '#open' => FALSE,
    ];

    $form['admin_label']['admin_label'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Administrative title'),
      '#default_value' => $this->settings['admin_label'],
      '#description' => $this->t('This will be displayed on the rules list. This is useful when you have the same access rule used twice.'),
    ];

    return $form;
  }

  /**
   * Optionally hide the value form with states as defined by the operators.
   *
   * @param array $form
   *   The current form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  protected function hideValueFormWithStates(array &$form, FormStateInterface $form_state) {
    $hide_value = FALSE;
    foreach ($this->operators() as $operator) {
      if (!empty($operator['hide_value'])) {
        $hide_value = TRUE;
        break;
      }
    }

    if ($hide_value) {
      $fields = [];
      foreach ($this->operators() as $key => $operator) {
        if (!empty($operator['hide_value'])) {
          $fields[] = ['value' => $key];
        }
      }

      $form['value']['#states'] = [
        'invisible' => [
          'select[name="operator"]' => $fields,
        ],
      ];
    }
  }

  /**
   * Determine whether the value is hidden.
   *
   * @return bool
   *   TRUE if the value is hidden; FALSE otherwise.
   */
  protected function isValueHidden() {
    $operators = $this->operators();
    $operator = $this->getOperator();
    if (!empty($operators[$operator]['hide_value'])) {
      return TRUE;
    }

    return FALSE;
  }

  /**
   * Get all permission options grouped by module.
   *
   * @return array
   *   Array of permissions.
   */
  protected function getPermissionsOptions() {
    $permissions = $this->permissionHandler->getPermissions();
    $perms = [];
    foreach ($permissions as $perm => $perm_item) {
      $provider = $perm_item['provider'];
      $display_name = $this->moduleHandler->getName($provider);
      $perms[$display_name][$perm] = strip_tags($perm_item['title']);
    }
    return $perms;
  }

  /**
   * Get the default permission.
   *
   * @return string
   *   The default permission.
   */
  protected function getDefaultPermission() {
    $policy = $this->definition->getAccessPolicy();
    return 'assign ' . $policy . ' access policy';
  }

  /**
   * Get the values from a field.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The current entity.
   * @param string $field_name
   *   The field name.
   *
   * @return array
   *   Index array of field values.
   */
  public function getEntityFieldValues(EntityInterface $entity, $field_name) {
    if (!$entity->hasField($field_name)) {
      return [];
    }
    $field = $entity->get($field_name);
    $field_definition = $field->getFieldDefinition();

    // Get the main property name.
    $storage = $field_definition->getFieldStorageDefinition();
    $column_name = $storage->getMainPropertyName();

    $values = $entity->get($field_name)->getValue();
    return array_map(function ($value) use ($column_name) {
      if (isset($value[$column_name])) {
        return $value[$column_name];
      }
    }, $values);
  }

  /**
   * Get the values to compare against.
   *
   * @return array
   *   The indexed array of values to compare against.
   */
  public function getValue() {
    $value = parent::getValue();

    // If the value is an array check to see if it's a field value.
    if (is_array($value)) {
      $column_name = $this->getMainPropertyName($this->definition->getFieldType());
      return array_map(function ($value) use ($column_name) {
        // If the column name exists then return that. Otherwise just return
        // the value.
        if (isset($value[$column_name])) {
          return $value[$column_name];
        }
        return $value;
      }, $value);
    }
    return $value;

  }

  /**
   * Get the main property name of a field.
   *
   * @param string $field_type
   *   The field type.
   *
   * @return string
   *   The main property name.
   */
  public function getMainPropertyName($field_type) {
    $definition = $this->fieldTypeManager->getDefinition($field_type);
    $class = $definition['class'];
    return $class::mainPropertyName();
  }

  /**
   * {@inheritdoc}
   */
  public function adminSummary() {
    if ($this->isValueHidden()) {
      return $this->getOperator();
    }
    return $this->getOperator() . ' ' . $this->settings['value'];
  }

}

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

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