View source
<?php
declare (strict_types=1);
namespace Drupal\og;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\og\Entity\OgRole;
use Drupal\og\Event\GroupContentEntityOperationAccessEvent;
use Drupal\user\EntityOwnerInterface;
use Drupal\user\UserInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class OgAccess implements OgAccessInterface {
const ADMINISTER_GROUP_PERMISSION = 'administer group';
const DELETE_GROUP_PERMISSION = 'delete group';
const UPDATE_GROUP_PERMISSION = 'update group';
const OPERATION_GROUP_PERMISSION_MAPPING = [
'delete' => self::DELETE_GROUP_PERMISSION,
'update' => self::UPDATE_GROUP_PERMISSION,
];
protected $configFactory;
protected $accountProxy;
protected $moduleHandler;
protected $groupTypeManager;
protected $permissionManager;
protected $membershipManager;
protected $dispatcher;
public function __construct(ConfigFactoryInterface $config_factory, AccountProxyInterface $account_proxy, ModuleHandlerInterface $module_handler, GroupTypeManagerInterface $group_manager, PermissionManagerInterface $permission_manager, MembershipManagerInterface $membership_manager, EventDispatcherInterface $dispatcher) {
$this->configFactory = $config_factory;
$this->accountProxy = $account_proxy;
$this->moduleHandler = $module_handler;
$this->groupTypeManager = $group_manager;
$this->permissionManager = $permission_manager;
$this->membershipManager = $membership_manager;
$this->dispatcher = $dispatcher;
}
public function userAccess(EntityInterface $group, string $permission, ?AccountInterface $user = NULL, bool $skip_alter = FALSE) : AccessResultInterface {
$group_type_id = $group
->getEntityTypeId();
$bundle = $group
->bundle();
$config = $this->configFactory
->get('og.settings');
$cacheable_metadata = (new CacheableMetadata())
->addCacheableDependency($config);
if (!$this->groupTypeManager
->isGroup($group_type_id, $bundle)) {
return AccessResult::neutral()
->addCacheableDependency($cacheable_metadata);
}
if (!isset($user)) {
$user = $this->accountProxy
->getAccount();
}
if ($user
->id() == $this->accountProxy
->id()) {
$cacheable_metadata
->addCacheContexts([
'user',
]);
}
if ($user
->id() == 1) {
return AccessResult::allowed()
->addCacheableDependency($cacheable_metadata);
}
$user_access = AccessResult::allowedIfHasPermission($user, 'administer organic groups');
if ($user_access
->isAllowed()) {
return $user_access
->addCacheableDependency($cacheable_metadata);
}
if ($config
->get('group_manager_full_access') && $user
->isAuthenticated() && $group instanceof EntityOwnerInterface) {
$cacheable_metadata
->addCacheableDependency($group);
if ($group
->getOwnerId() == $user
->id()) {
return AccessResult::allowed()
->addCacheableDependency($cacheable_metadata);
}
}
$permissions = [];
$user_is_group_admin = FALSE;
if ($membership = $this->membershipManager
->getMembership($group, $user
->id())) {
foreach ($membership
->getRoles() as $role) {
if ($role
->isAdmin()) {
$user_is_group_admin = TRUE;
break;
}
$permissions = array_merge($permissions, $role
->getPermissions());
}
}
elseif (!$this->membershipManager
->isMember($group, $user
->id(), [
OgMembershipInterface::STATE_BLOCKED,
])) {
$role = OgRole::loadByGroupAndName($group, OgRoleInterface::ANONYMOUS);
$permissions = $role
->getPermissions();
}
$permissions = array_unique($permissions);
if (!$skip_alter && !in_array($permission, $permissions)) {
$context = [
'permission' => $permission,
'group' => $group,
'user' => $user,
];
$this->moduleHandler
->alter('og_user_access', $permissions, $cacheable_metadata, $context);
}
if ($user_is_group_admin || in_array($permission, $permissions)) {
return AccessResult::allowed()
->addCacheableDependency($cacheable_metadata);
}
return AccessResult::neutral()
->addCacheableDependency($cacheable_metadata);
}
public function userAccessEntity(string $permission, EntityInterface $entity, ?AccountInterface $user = NULL) : AccessResultInterface {
$result = AccessResult::neutral();
$entity_type = $entity
->getEntityType();
$entity_type_id = $entity_type
->id();
$bundle = $entity
->bundle();
if ($this->groupTypeManager
->isGroup($entity_type_id, $bundle)) {
$result = $this
->userAccess($entity, $permission, $user);
if (!$result
->isNeutral()) {
return $result;
}
}
if ($this->groupTypeManager
->isGroupContent($entity_type_id, $bundle)) {
$result
->addCacheTags($entity_type
->getListCacheTags());
$groups = $entity instanceof UserInterface ? $this->membershipManager
->getUserGroups($entity
->id()) : $this->membershipManager
->getGroups($entity);
if ($groups) {
foreach ($groups as $entity_groups) {
foreach ($entity_groups as $group) {
$result = $result
->orIf($this
->userAccess($group, $permission, $user));
}
}
}
}
return $result;
}
public function userAccessEntityOperation(string $operation, EntityInterface $entity, ?AccountInterface $user = NULL) : AccessResultInterface {
$result = AccessResult::neutral();
$entity_type = $entity
->getEntityType();
$entity_type_id = $entity_type
->id();
$bundle = $entity
->bundle();
if ($this->groupTypeManager
->isGroup($entity_type_id, $bundle)) {
if (array_key_exists($operation, self::OPERATION_GROUP_PERMISSION_MAPPING)) {
$permission = self::OPERATION_GROUP_PERMISSION_MAPPING[$operation];
$result = $this
->userAccess($entity, $permission, $user);
if (!$result
->isNeutral()) {
return $result;
}
}
}
if ($this->groupTypeManager
->isGroupContent($entity_type_id, $bundle)) {
$result
->addCacheTags($entity_type
->getListCacheTags());
$groups = $entity instanceof UserInterface ? $this->membershipManager
->getUserGroups($entity
->id()) : $this->membershipManager
->getGroups($entity);
if ($groups) {
foreach ($groups as $entity_groups) {
foreach ($entity_groups as $group) {
$result = $result
->orIf($this
->userAccessGroupContentEntityOperation($operation, $group, $entity, $user));
}
}
}
}
return $result;
}
public function userAccessGroupContentEntityOperation(string $operation, EntityInterface $group_entity, EntityInterface $group_content_entity, ?AccountInterface $user = NULL) : AccessResultInterface {
$user = $user ?: $this->accountProxy
->getAccount();
$event = new GroupContentEntityOperationAccessEvent($operation, $group_entity, $group_content_entity, $user);
$event
->addCacheableDependency($group_content_entity);
if ($user
->id() == $this->accountProxy
->id()) {
$event
->addCacheContexts([
'user',
]);
}
$this->dispatcher
->dispatch(GroupContentEntityOperationAccessEvent::EVENT_NAME, $event);
return $event
->getAccessResult();
}
public function reset() : void {
trigger_error('OgAccessInterface::reset() is deprecated in og:8.1.0-alpha6 and is removed from og:8.1.0-beta1. The static cache has been removed and this method no longer serves any purpose. Any calls to this method can safely be removed. See https://github.com/Gizra/og/issues/654', E_USER_DEPRECATED);
}
}