access_policy-1.0.x-dev/src/UserFieldAccessPolicyData.php

src/UserFieldAccessPolicyData.php
<?php

namespace Drupal\access_policy;

use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\field\FieldStorageConfigInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Class to manage and lazy load cached access policy data.
 */
class UserFieldAccessPolicyData implements ContainerInjectionInterface {

  use StringTranslationTrait;

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

  /**
   * Constructs the user field access rule data set.
   *
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
   *   The entity field manager.
   */
  public function __construct(EntityFieldManagerInterface $entity_field_manager) {
    $this->entityFieldManager = $entity_field_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_field.manager'),
    );
  }

  /**
   * Defines the default access rule data.
   *
   * @see hook_access_policy_data()
   */
  public function accessPolicyData() {
    $data = [];
    $this->createBaseFieldAccessRules($data);
    $this->createDerivedAccessRules($data);
    return $data;
  }

  /**
   * Create the base field access rules.
   *
   * @param array $data
   *   The current access rule data.
   */
  protected function createBaseFieldAccessRules(array &$data) {
    $data['user']['uid'] = [
      'label' => $this->t('Current user: @field', ['@field' => 'The user ID']),
      'description' => $this->t('The raw numeric user ID.'),
      'plugin_id' => 'entity_field_numeric',
      'field' => 'uid',
      'entity_type' => 'user',
    ];
    $data['user']['name'] = [
      'label' => $this->t('Current user: @field', ['@field' => 'Name']),
      'description' => $this->t("The current user's name"),
      'plugin_id' => 'entity_field_string',
      'field' => 'name',
      'entity_type' => 'user',
    ];
    $data['user']['mail'] = [
      'label' => $this->t('Current user: @field', ['@field' => 'Email']),
      'description' => $this->t("The current user's email address."),
      'plugin_id' => 'entity_field_string',
      'field' => 'mail',
      'entity_type' => 'user',
    ];
    $data['user']['init'] = [
      'label' => $this->t('Current user: @field', ['@field' => 'Initial email']),
      'description' => $this->t('The email address used for initial account creation.'),
      'plugin_id' => 'entity_field_string',
      'field' => 'init',
      'entity_type' => 'user',
    ];
    $data['user']['status'] = [
      'label' => $this->t('Current user: @field', ['@field' => 'User status']),
      'description' => $this->t('Whether the current user is active or blocked.'),
      'plugin_id' => 'entity_field_boolean',
      'field' => 'status',
      'entity_type' => 'user',
    ];
    $data['user']['roles'] = [
      'label' => $this->t('Current user: @field', ['@field' => 'Roles']),
      'description' => $this->t('The roles the current user has.'),
      'plugin_id' => 'user_field_role',
      'field' => 'roles',
      'entity_type' => 'user',
    ];
    $data['user']['created'] = [
      'label' => $this->t('Current user: @field', ['@field' => 'Created']),
      'description' => $this->t('The time that the current user was created.'),
      'plugin_id' => 'entity_field_date',
      'field' => 'created',
      'entity_type' => 'user',
    ];
    $data['user']['login'] = [
      'label' => $this->t('Current user: @field', ['@field' => 'Last login']),
      'description' => $this->t('The time that the current user last logged in.'),
      'plugin_id' => 'entity_field_date',
      'field' => 'login',
      'entity_type' => 'user',
    ];
    $data['user']['access'] = [
      'label' => $this->t('Current user: @field', ['@field' => 'Last access']),
      'description' => $this->t('The time that the current user last accessed the site.'),
      'plugin_id' => 'entity_field_date',
      'field' => 'access',
      'entity_type' => 'user',
    ];
  }

  /**
   * Create user entity reference access rules.
   *
   * @param array $data
   *   The current access rule data.
   */
  protected function createDerivedAccessRules(array &$data) {
    $user_fields = $this->getUserFieldDefinitions();
    foreach ($user_fields as $field_name => $definition) {
      $data['user'][$field_name] = $this->createUserFieldAccessRule($definition);

      // Add additional access rules for specific field types.
      $type = $definition->getType();
      switch ($type) {
        case 'list_integer':
        case 'list_float':
          $data['user']['numeric_' . $field_name] = $this->createFieldListNumericFieldValueAccessRule($definition);
          break;

        case 'entity_reference':
          $storage = $definition->getFieldStorageDefinition();
          if ($storage->getSetting('target_type') == 'taxonomy_term') {
            $data['user']['term_depth_' . $definition->getName()] = $this->createTermReferenceWithDepthAccessRule($definition);
          }
          break;
      }

    }
  }

  /**
   * Create user field access rule data definition.
   *
   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
   *   The field definition.
   *
   * @return array
   *   The user reference access rule data definition.
   */
  protected function createUserFieldAccessRule(FieldDefinitionInterface $field_definition) {
    return [
      'label' => $this->t('Current user: @field', ['@field' => $field_definition->getLabel()]),
      'description' => $this->t('Grant access to user with a particular value in this field.'),
      'plugin_id' => $this->getUserFieldPluginId($field_definition),
      'field' => $field_definition->getName(),
      'entity_type' => 'user',
    ];
  }

  /**
   * Create numeric list field access rule.
   *
   * This access rule compares values in list_integer and list_float fields
   * numerically. This allows for features like mandatory access control.
   *
   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
   *   The field definition.
   *
   * @return array
   *   The numeric list field access rule data definition.
   */
  protected function createFieldListNumericFieldValueAccessRule(FieldDefinitionInterface $field_definition) {
    return [
      'label' => $this->t('Current user: @field (numeric)', ['@field' => $field_definition->getLabel()]),
      'description' => $this->t('Grant access to user with a particular value in this field.'),
      'plugin_id' => 'entity_field_list_numeric',
      'field' => $field_definition->getName(),
      'entity_type' => 'user',
    ];
  }

  /**
   * Create the term reference with depth access rule.
   *
   * This access rule compares taxonomy terms while respecting the hierarchy.
   *
   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
   *   The field definition.
   *
   * @return array
   *   The term reference field access rule data definition.
   */
  protected function createTermReferenceWithDepthAccessRule(FieldDefinitionInterface $field_definition) {
    return [
      'label' => $this->t('Current user: @field (with depth)', ['@field' => $field_definition->getLabel()]),
      'description' => $this->t('Grant access to user with specific terms or children of selected terms.'),
      'plugin_id' => 'term_reference_depth',
      'field' => $field_definition->getName(),
      'entity_type' => 'user',
      'operator' => 'in',
    ];
  }

  /**
   * Get default user field plugin ids based on field type.
   *
   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
   *   The field definition.
   *
   * @return string
   *   The default plugin id.
   */
  protected function getUserFieldPluginId(FieldDefinitionInterface $field_definition) {

    switch ($field_definition->getType()) {
      case 'integer':
      case 'float':
      case 'decimal':
      case 'timestamp':
        return 'entity_field_numeric';

      case 'changed':
      case 'created':
      case 'datetime':
        // @todo come back to daterange.
      case 'daterange':
        return 'entity_field_date';

      case 'list_string':
      case 'list_integer':
      case 'list_float':
        return 'entity_field_list';

      case 'string':
      case 'string_long':
      case 'text':
      case 'text_long':
      case 'text_with_summary':
      case 'email':
        return 'entity_field_string';

      case 'boolean':
        return 'entity_field_boolean';

      case 'entity_reference':
        return 'entity_field_entity_reference';

      default:
        return 'entity_field_standard';
    }
  }

  /**
   * Get the user field definitions.
   *
   * @return \Drupal\Core\Field\FieldDefinitionInterface[]
   *   The user field definitions.
   *
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  protected function getUserFieldDefinitions() {
    $field_definitions = $this->entityFieldManager->getFieldDefinitions('user', 'user');

    // Add configurable fields.
    return $this->filterByApplicableFieldStorage('user', $field_definitions);
  }

  /**
   * Array of applicable entity reference fields found on an entity type.
   *
   * @param string $entity_type_id
   *   The entity type id.
   * @param \Drupal\Core\Field\FieldDefinitionInterface[] $field_definitions
   *   Array of field definitions.
   *
   * @return \Drupal\Core\Field\FieldDefinitionInterface[]
   *   Array of filtered field definitions.
   */
  private function filterByApplicableFieldStorage($entity_type_id, array $field_definitions) {
    $options = [];
    foreach ($this->entityFieldManager->getFieldStorageDefinitions($entity_type_id) as $field_name => $field_storage) {
      if ($field_storage instanceof FieldStorageConfigInterface
        && !$field_storage->isLocked()) {
        if (isset($field_definitions[$field_name])) {
          $options[$field_name] = $field_definitions[$field_name];
        }
      }
    }
    return $options;
  }

}

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

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