access_policy-1.0.x-dev/src/Session/UserFieldValuesHashGenerator.php

src/Session/UserFieldValuesHashGenerator.php
<?php

namespace Drupal\access_policy\Session;

use Drupal\access_policy\AccessPolicyHandlerManager;
use Drupal\access_policy\AccessPolicyInformation;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Site\Settings;

/**
 * Defines the UserFieldValuesHashGenerator service.
 */
class UserFieldValuesHashGenerator implements UserFieldValuesHashGeneratorInterface {

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

  /**
   * The access rule manager.
   *
   * @var \Drupal\access_policy\AccessPolicyHandlerManager
   */
  protected $accessRuleManager;

  /**
   * The access policy information service.
   *
   * @var \Drupal\access_policy\AccessPolicyInformation
   */
  protected $accessPolicyInfo;

  /**
   * The user field values static cache.
   *
   * @var array
   */
  protected $cache;

  /**
   * Constructs a new UserFieldValuesHashGenerator class.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\access_policy\AccessPolicyHandlerManager $access_rule_manager
   *   The access rule manager.
   * @param \Drupal\access_policy\AccessPolicyInformation $access_policy_info
   *   The access policy information service.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, AccessPolicyHandlerManager $access_rule_manager, AccessPolicyInformation $access_policy_info) {
    $this->entityTypeManager = $entity_type_manager;
    $this->accessRuleManager = $access_rule_manager;
    $this->accessPolicyInfo = $access_policy_info;
  }

  /**
   * {@inheritdoc}
   */
  public function generate(AccountInterface $account, $field_name = NULL) {
    $cid = $this->getCid($account, $field_name);
    if ($this->cacheExists($cid)) {
      return $this->getCache($cid);
    }
    else {
      $user = $this->entityTypeManager->getStorage('user')->load($account->id());
      $hash = $this->hash(serialize($this->getFieldValues($user, $field_name)));
      $this->setCache($cid, $hash);
      return $hash;
    }
  }

  /**
   * Get the field values for a user.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The current user.
   * @param string $field_name
   *   (Optional) the field name. If empty, it will retrieve all fields observed
   *   by all access policies.
   *
   * @return array
   *   The array of field values.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function getFieldValues(AccountInterface $account, $field_name = NULL) {
    if ($field_name) {
      $fields = explode(',', $field_name);
    }
    else {
      $fields = $this->getUserFieldsObservedByAccessRules();
    }

    // Get all the field values from the user.
    $values = [];
    foreach ($fields as $field_name) {
      if ($account->hasField($field_name)) {
        $values[$field_name] = $account->get($field_name)->getValue();
      }
    }

    return $values;
  }

  /**
   * Fetch all user fields being observed by access policies.
   *
   * @return array
   *   The array of field names observed by access rules.
   */
  protected function getUserFieldsObservedByAccessRules() {
    $entity_types = $this->accessPolicyInfo->getAllEnabledEntityTypes();
    $entity_type_ids = array_map(function ($entity_type) {
      return $entity_type->id();
    }, $entity_types);

    $handlers = [];
    foreach ($entity_type_ids as $entity_type) {
      $access_rules = $this->accessRuleManager->getHandlersFromPolicies($entity_type, function ($handler) {
        if ($handler->getDefinition()->getEntityType() == 'user') {
          return TRUE;
        }
        elseif ($handler->getArgument() && $handler->getArgument()->getPluginId() == 'current_user') {
          return TRUE;
        }
        return FALSE;
      });
      $handlers = array_merge($handlers, $access_rules);
    }

    $fields = array_map(function ($handler) {
      if ($handler->getArgument()) {
        return $handler->getArgument()->getField();
      }
      else {
        return $handler->getDefinition()->getFieldName();
      }
    }, $handlers);

    return array_unique($fields);
  }

  /**
   * Hashes the given string.
   *
   * @param string $identifier
   *   The string to be hashed.
   *
   * @return string
   *   The hash.
   */
  protected function hash($identifier) {
    return hash('sha256', Settings::getHashSalt() . $identifier);
  }

  /**
   * Get the cid.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The current user.
   * @param string $field_name
   *   The field name.
   *
   * @return string
   *   The cache id.
   */
  protected function getCid(AccountInterface $account, $field_name = NULL) {
    $field_name = $field_name ?? 'all';
    return $account->id() . ':' . $field_name;
  }

  /**
   * Determine whether a cache exists.
   *
   * @param string $cid
   *   Teh cache id.
   *
   * @return bool
   *   TRUE if a cache entry exists; FALSE otherwise.
   */
  protected function cacheExists($cid) {
    return isset($this->cache[$cid]);
  }

  /**
   * Get the hashed field values from the cache.
   *
   * @param string $cid
   *   The cache id.
   *
   * @return string|null
   *   The hashed field values or NULL if none found.
   */
  protected function getCache($cid) {
    if (isset($this->cache[$cid])) {
      return $this->cache[$cid];
    }
  }

  /**
   * Set the cached field values hash.
   *
   * @param string $cid
   *   The cache id.
   * @param string $hash
   *   The hashed field values.
   */
  protected function setCache($cid, $hash) {
    $this->cache[$cid] = $hash;
  }

}

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

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