og-8.x-1.x-dev/src/OgMembershipAccessControlHandler.php

src/OgMembershipAccessControlHandler.php
<?php

declare(strict_types=1);

namespace Drupal\og;

use Drupal\og\ContextProvider\OgContext;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityHandlerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\EntityOwnerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Defines the OG membership implementation for entity access control handler.
 */
class OgMembershipAccessControlHandler extends EntityAccessControlHandler implements EntityHandlerInterface {

  /**
   * The OG access service.
   */
  protected OgAccess $ogAccess;

  /**
   * The OG Membership Manager service.
   */
  protected MembershipManagerInterface $membershipManager;

  /**
   * Instance of the OgContext service.
   */
  protected OgContext $ogContext;

  public function __construct(EntityTypeInterface $entity_type, OgAccessInterface $og_access, MembershipManagerInterface $membership_manager, OgContextInterface $ogContext) {
    parent::__construct($entity_type);
    $this->ogAccess = $og_access;
    $this->membershipManager = $membership_manager;
    $this->ogContext = $ogContext;
  }

  /**
   * {@inheritdoc}
   */
  public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
    return new static(
      $entity_type,
      $container->get('og.access'),
      $container->get('og.membership_manager'),
      $container->get('og.context')
    );
  }

  /**
   * {@inheritdoc}
   */
  protected function checkAccess(EntityInterface $membership, $operation, AccountInterface $account) {
    $group = $membership->getGroup();

    // Do not allow deleting the group owner's membership.
    if ($operation === 'delete' && ($group instanceof EntityOwnerInterface) && ($group->getOwnerId() == $membership->getOwner()->id())) {
      return AccessResult::forbidden();
    }

    // Ensure that there's at least one active membership in the group.
    if ($operation === 'delete' && $this->membershipManager->getGroupMembershipCount($group) === 1) {
      return AccessResult::forbidden();
    }

    // If the user has permission to administer all groups, allow access.
    if ($account->hasPermission('administer organic groups')) {
      return AccessResult::allowed();
    }

    $permissions = [OgAccess::ADMINISTER_GROUP_PERMISSION, 'manage members'];
    foreach ($permissions as $permission) {
      $result = $this->ogAccess->userAccess($group, $permission, $account);
      if ($result->isAllowed()) {
        return $result;
      }
    }

    return AccessResult::neutral();
  }

  /**
   * {@inheritdoc}
   */
  public function createAccess($entity_bundle = NULL, ?AccountInterface $account = NULL, array $context = [], $return_as_object = FALSE) {
    $account = $this->prepareUser($account);
    $context += [
      'entity_type_id' => $this->entityTypeId,
      'langcode' => LanguageInterface::LANGCODE_DEFAULT,
      'group' => NULL,
    ];
    if (empty($context['group'])) {
      $context['group'] = $this->ogContext->getGroup();
    }

    // Invoke hook_entity_create_access() and hook_ENTITY_TYPE_create_access().
    // Hook results take precedence over overridden implementations of
    // EntityAccessControlHandler::checkCreateAccess(). Entities that have
    // checks that need to be done before the hook is invoked should do so by
    // overriding this method.
    // We grant access to the entity if both of these conditions are met:
    // - No modules say to deny access.
    // - At least one module says to grant access.
    $args = [$account, $context, $entity_bundle];
    $access = array_merge(
      $this->moduleHandler()->invokeAll('entity_create_access', $args),
      $this->moduleHandler()->invokeAll($this->entityTypeId . '_create_access', $args)
    );

    $return = $this->processAccessHookResults($access);

    // Also execute the default access check except when the access result is
    // already forbidden, as in that case, it can not be anything else.
    if (!$return->isForbidden()) {
      $return = $return->orIf($this->checkCreateAccess($account, $context, $entity_bundle));
    }
    return $return_as_object ? $return : $return->isAllowed();
  }

  /**
   * {@inheritdoc}
   */
  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
    // If the user has permission to administer all groups, allow access.
    if ($account->hasPermission('administer organic groups')) {
      return AccessResult::allowed();
    }

    $group = $context['group'];

    // If we don't have a group, we can't really determine access other than
    // checking global account permissions.
    if ($group === NULL) {
      return AccessResult::neutral();
    }

    $permissions = [
      OgAccess::ADMINISTER_GROUP_PERMISSION,
      'add user',
      'manage members',
    ];
    foreach ($permissions as $permission) {
      $result = $this->ogAccess->userAccess($group, $permission, $account);
      if ($result->isAllowed()) {
        return $result;
      }
    }

    return AccessResult::neutral();
  }

  /**
   * {@inheritdoc}
   */
  protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, ?FieldItemListInterface $items = NULL) {
    /** @var \Drupal\og\OgMembershipInterface $membership */
    $membership = $items ? $items->getEntity() : NULL;

    $administrative_fields = ['uid', 'state', 'roles'];
    if ($operation === 'edit' && in_array($field_definition->getName(), $administrative_fields, TRUE)) {
      $access = AccessResult::allowedIfHasPermission($account, 'administer organic groups')->addCacheableDependency($membership);
      if (!$membership || $access->isAllowed()) {
        return $access;
      }
      $permissions = [
        OgAccess::ADMINISTER_GROUP_PERMISSION,
        'manage members',
      ];
      $group = $membership->getGroup();
      foreach ($permissions as $permission) {
        $result = $this->ogAccess->userAccess($group, $permission, $account);
        if ($result instanceof RefinableCacheableDependencyInterface) {
          $result->addCacheableDependency($membership);
        }
        if ($result->isAllowed()) {
          return $result;
        }
      }
      // Return the last result, which must be denied.
      return $result;
    }

    if ($membership && $membership->isActive() && $field_definition->getName() === OgMembershipInterface::REQUEST_FIELD) {
      return AccessResult::forbidden()->addCacheableDependency($membership);
    }
    return AccessResult::allowed()->addCacheableDependency($membership);
  }

}

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

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