You are here

class GroupPermissionsHashGenerator in Group 8

Same name and namespace in other branches
  1. 2.0.x src/Access/GroupPermissionsHashGenerator.php \Drupal\group\Access\GroupPermissionsHashGenerator

Generates and caches the permissions hash for a group membership.

Hierarchy

Expanded class hierarchy of GroupPermissionsHashGenerator

1 file declares its use of GroupPermissionsHashGenerator
GroupPermissionHashGeneratorTest.php in tests/src/Unit/GroupPermissionHashGeneratorTest.php
1 string reference to 'GroupPermissionsHashGenerator'
group.services.yml in ./group.services.yml
group.services.yml
1 service uses GroupPermissionsHashGenerator
group.permissions_hash_generator in ./group.services.yml
Drupal\group\Access\GroupPermissionsHashGenerator

File

src/Access/GroupPermissionsHashGenerator.php, line 15

Namespace

Drupal\group\Access
View source
class GroupPermissionsHashGenerator implements GroupPermissionsHashGeneratorInterface {

  /**
   * The private key service.
   *
   * @var \Drupal\Core\PrivateKey
   */
  protected $privateKey;

  /**
   * The cache backend interface to use for the static cache.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface
   */
  protected $static;

  /**
   * The group permission calculator.
   *
   * @var \Drupal\group\Access\GroupPermissionCalculatorInterface
   */
  protected $groupPermissionCalculator;

  /**
   * Constructs a GroupPermissionsHashGenerator object.
   *
   * @param \Drupal\Core\PrivateKey $private_key
   *   The private key service.
   * @param \Drupal\Core\Cache\CacheBackendInterface $static
   *   The cache backend interface to use for the static cache.
   * @param \Drupal\group\Access\GroupPermissionCalculatorInterface $permission_calculator
   *   The group permission calculator.
   */
  public function __construct(PrivateKey $private_key, CacheBackendInterface $static, GroupPermissionCalculatorInterface $permission_calculator) {
    $this->privateKey = $private_key;
    $this->static = $static;
    $this->groupPermissionCalculator = $permission_calculator;
  }

  /**
   * {@inheritdoc}
   */
  public function generateHash(AccountInterface $account) {

    // We can use a simple per-user static cache here because we already cache
    // the permissions more efficiently in the group permission calculator. On
    // top of that, there is only a tiny chance of a hash being generated for
    // more than one account during a single request.
    $cid = 'group_permissions_hash_' . $account
      ->id();

    // Retrieve the hash from the static cache if available.
    if ($static_cache = $this->static
      ->get($cid)) {
      return $static_cache->data;
    }
    else {
      $calculated_permissions = $this->groupPermissionCalculator
        ->calculatePermissions($account);
      $permissions = [];
      foreach ($calculated_permissions
        ->getItems() as $item) {

        // If the calculated permissions item grants admin rights, we can
        // simplify the entry by setting it to 'is-admin' rather than a list of
        // permissions. This will ensure admins for the given scope item always
        // match even if their list of permissions differs.
        if ($item
          ->isAdmin()) {
          $item_permissions = 'is-admin';
        }
        else {
          $item_permissions = $item
            ->getPermissions();

          // Sort the permissions by name to ensure we don't get mismatching
          // hashes for people with the same permissions, just because the order
          // of the permissions happened to differ.
          sort($item_permissions);
        }
        $permissions[$item
          ->getIdentifier()] = $item_permissions;
      }

      // Sort the result by key to ensure we don't get mismatching hashes for
      // people with the same permissions, just because the order of the keys
      // happened to differ.
      ksort($permissions);
      $hash = $this
        ->hash(serialize($permissions));
      $this->static
        ->set($cid, $hash, Cache::PERMANENT, $calculated_permissions
        ->getCacheTags());
      return $hash;
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheableMetadata(AccountInterface $account) {
    return CacheableMetadata::createFromObject($this->groupPermissionCalculator
      ->calculatePermissions($account));
  }

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

}

Members

Namesort descending Modifiers Type Description Overrides
GroupPermissionsHashGenerator::$groupPermissionCalculator protected property The group permission calculator.
GroupPermissionsHashGenerator::$privateKey protected property The private key service.
GroupPermissionsHashGenerator::$static protected property The cache backend interface to use for the static cache.
GroupPermissionsHashGenerator::generateHash public function Generates a hash for an account's complete group permissions. Overrides GroupPermissionsHashGeneratorInterface::generateHash
GroupPermissionsHashGenerator::getCacheableMetadata public function Gets the cacheability metadata for the generated hash. Overrides GroupPermissionsHashGeneratorInterface::getCacheableMetadata
GroupPermissionsHashGenerator::hash protected function Hashes the given string.
GroupPermissionsHashGenerator::__construct public function Constructs a GroupPermissionsHashGenerator object.