access_policy-1.0.x-dev/src/Plugin/access_policy/AccessRule/EntityFieldList.php

src/Plugin/access_policy/AccessRule/EntityFieldList.php
<?php

namespace Drupal\access_policy\Plugin\access_policy\AccessRule;

use Drupal\access_policy\LabelHelper;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;

/**
 * Restrict content by comparing field on the entity.
 *
 * @AccessRule(
 *   id = "entity_field_list",
 *   handlers = {
 *     "query_alter" = "\Drupal\access_policy\AccessRuleQueryHandler\EntityField"
 *   }
 * )
 */
class EntityFieldList extends EntityFieldBase {

  /**
   * {@inheritdoc}
   */
  public function defaultSettings() {
    return [
      'value' => [],
      "operator" => 'or',
      'filter_allowed_values' => FALSE,
    ] + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function accessRuleFormSubmit(array &$form, FormStateInterface $form_state) {
    parent::accessRuleFormSubmit($form, $form_state);
    $values = $form_state->getValues();
    $this->settings['value'] = $values['value'] ?? [];
    $this->settings['filter_allowed_values'] = $values['filter_allowed_values'] ?? FALSE;
  }

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

  /**
   * {@inheritdoc}
   */
  public function extraOptionsForm(array &$form, FormStateInterface $form_state) {
    if ($this->isComparingWithUser()) {
      $form['filter_allowed_values'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Filter allowed values'),
        '#description' => $this->t("Filter options in the field widget based on the author's current values. This prevents authors from choosing options that they should not have access to.<br>Warning: This is a global setting. All instances of this field will be affected regardless of policy assigned."),
        '#default_value' => $this->settings['filter_allowed_values'],
      ];
    }
  }

  /**
   * Determine whether the entity field list is being compared against the user.
   *
   * @return bool
   *   TRUE if we're comparing against the user; FALSE otherwise.
   */
  protected function isComparingWithUser() {
    $has_user_argument = ($this->getArgument() && $this->getArgument()->getPluginId() == 'current_user');
    if ($has_user_argument) {
      return TRUE;
    }

    return FALSE;
  }

  /**
   * Get allowed field value options.
   *
   * @return array
   *   Array of allowed values.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  protected function getAllowedValues() {
    $field_definition = $this->getFieldDefinition();
    $settings = $field_definition->getSettings();
    return $settings['allowed_values'] ?? [];
  }

  /**
   * Get the current field definition.
   *
   * @return \Drupal\Core\Field\FieldDefinitionInterface|false
   *   The field definition.
   */
  protected function getFieldDefinition() {
    $field_map = $this->entityFieldManager->getFieldMapByFieldType($this->definition->getFieldType());
    $entity_fields = $field_map[$this->definition->getEntityType()];
    $current_field = $entity_fields[$this->definition->getFieldName()] ?? [];

    $bundle = reset($current_field['bundles']);
    $definitions = $this->entityFieldManager->getFieldDefinitions($this->definition->getEntityType(), $bundle);
    if (isset($definitions[$this->definition->getFieldName()])) {
      return $definitions[$this->definition->getFieldName()];
    }

    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function operators() {
    $operators = [
      'or' => [
        'title' => $this->t('Is one of'),
        'method' => 'validateSimple',
      ],
      'not' => [
        'title' => $this->t('Is none of'),
        'method' => 'validateSimple',
      ],
    ];

    return $operators;
  }

  /**
   * Validate operators.
   *
   * @param array $options
   *   The array of options.
   * @param array $values
   *   The array of values.
   *
   * @return bool
   *   TRUE if operator passes; FALSE otherwise.
   */
  public function validateSimple(array $options, array $values) {
    $op = $this->getOperator();

    switch ($op) {
      case 'or':
        foreach ($values as $value) {
          if ($this->isOneOf($options, $value)) {
            return TRUE;
          }
        }
        break;

      case 'not':
        foreach ($values as $value) {
          if ($this->isOneOf($options, $value)) {
            return FALSE;
          }
        }
        return TRUE;
    }

    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function validateCallback(EntityInterface $entity, AccountInterface $account) {
    $operator = $this->getOperator();
    $info = $this->operators();

    $field_values = $this->getEntityValues($entity, $account);
    $options = $this->getValue();

    $options = array_values($options);

    if (!empty($info[$operator]['method'])) {
      // If any of the field values match then return true.
      $valid = $this->{$info[$operator]['method']}($options, $field_values);
      if ($valid) {
        return TRUE;
      }
    }

    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function adminSummary() {
    if (!$this->getArgument()) {
      $allowed_values = $this->getAllowedValues();
      $labels = [];
      $selected = $this->settings['value'];
      foreach ($allowed_values as $key => $label) {
        if (in_array($key, $selected)) {
          $labels[] = $label;
        }
      }

      return $this->getOperator() . ' ' . LabelHelper::render($labels, [
        'limit' => 1,
        'empty_value' => $this->t('Unknown'),
      ]);
    }
  }

}

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

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