og-8.x-1.x-dev/src/Cache/Context/OgPermissionsCacheContext.php

src/Cache/Context/OgPermissionsCacheContext.php
<?php

declare(strict_types=1);

namespace Drupal\og\Cache\Context;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Cache\Context\CacheContextInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\user\EntityOwnerInterface;
use Drupal\Core\PrivateKey;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Site\Settings;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\og\MembershipManagerInterface;
use Drupal\og\OgContextInterface;
use Drupal\og\OgMembershipInterface;
use Drupal\og\OgRoleInterface;

/**
 * Defines a cache context service for the OG permissions of the current user.
 *
 * Cache context ID: 'og_permissions'.
 */
class OgPermissionsCacheContext implements CacheContextInterface {

  /**
   * The string to return when no context is found.
   */
  const NO_CONTEXT = 'none';

  /**
   * Key used when the user has administrative permissions in a group.
   */
  const ADMIN_PERMISSION = 'is-admin';

  /**
   * An array of cached cache context key hashes.
   *
   * @var string[]
   */
  protected array $hashes = [];

  public function __construct(
    protected readonly AccountInterface $user,
    protected readonly OgContextInterface $ogContext,
    protected readonly MembershipManagerInterface $membershipManager,
    protected readonly EntityTypeManagerInterface $entityTypeManager,
    protected readonly PrivateKey $privateKey,
    protected readonly ConfigFactoryInterface $configFactory,
  ) {}

  /**
   * {@inheritdoc}
   */
  public static function getLabel() {
    return new TranslatableMarkup('OG permissions');
  }

  /**
   * {@inheritdoc}
   */
  public function getContext() {
    // Do not provide a cache context if there is no group in the current
    // context.
    $group = $this->ogContext->getGroup();
    if (!$group instanceof ContentEntityInterface) {
      return self::NO_CONTEXT;
    }

    $cache_id = implode(':', [$this->user->id(), $group->getEntityTypeId(), $group->bundle(), $group->id()]);
    if (!isset($this->hashes[$cache_id])) {
      $permissions = $this->getPermissions($group);
      if (empty($permissions)) {
        $this->hashes[$cache_id] = self::NO_CONTEXT;
      }
      else {
        sort($permissions);
        $this->hashes[$cache_id] = $this->hash(serialize($permissions));
      }
    }

    return $this->hashes[$cache_id];
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheableMetadata() {
    return CacheableMetadata::createFromObject($this->configFactory->get('og.settings'));
  }

  /**
   * Returns the OG permissions for the current user in the given group.
   */
  protected function getPermissions(ContentEntityInterface $group): array {
    // Anonymous users have no OG permissions.
    if (!$this->user->isAuthenticated()) {
      return [];
    }

    if ($this->user->hasPermission('administer organic groups')) {
      // Global OG admin.
      return [self::ADMIN_PERMISSION];
    }

    $config = $this->configFactory->get('og.settings');
    // Group owners can receive full permissions if configured.
    if ($config->get('group_manager_full_access') && $group instanceof EntityOwnerInterface && $group->getOwnerId() == $this->user->id()) {
      return [self::ADMIN_PERMISSION];
    }

    // If the user is blocked they have no permissions.
    if ($this->membershipManager->isMember($group, $this->user->id(), [OgMembershipInterface::STATE_BLOCKED])) {
      return [];
    }

    // Gather permissions from the user's membership.
    $membership = $this->membershipManager->getMembership($group, $this->user->id());
    if (!empty($membership)) {
      $permissions = [];
      foreach ($membership->getRoles() as $role) {
        if ($role->isAdmin()) {
          // Role is admin, so we can return early.
          return [self::ADMIN_PERMISSION];
        }
        $permissions = array_merge($permissions, $role->getPermissions());
      }

      return array_unique($permissions);
    }

    // Authenticated non-members inherit permissions from the group's
    // non-member role.
    $role_id = "{$group->getEntityTypeId()}-{$group->bundle()}-" . OgRoleInterface::ANONYMOUS;
    $role = $this->entityTypeManager->getStorage('og_role')->load($role_id);
    return $role?->getPermissions() ?? [];
  }

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

}

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

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