public function AccessControl::entityAccess in Group 2.0.x
Checks access to an operation on the entity.
Parameters
\Drupal\Core\Entity\EntityInterface $entity: The entity for which to check access.
string $operation: The operation access should be checked for. Usually one of "view", "update" or "delete".
\Drupal\Core\Session\AccountInterface $account: The user session for which to check access.
bool $return_as_object: (optional) Defaults to FALSE.
Return value
bool|\Drupal\Core\Access\AccessResultInterface The access result. Returns a boolean if $return_as_object is FALSE (this is the default) and otherwise an AccessResultInterface object. When a boolean is returned, the result of AccessInterface::isAllowed() is returned, i.e. TRUE means access is explicitly allowed, FALSE means access is either explicitly forbidden or "no opinion".
Overrides AccessControlTrait::entityAccess
File
- src/
Plugin/ Group/ RelationHandlerDefault/ AccessControl.php, line 83
Class
- AccessControl
- Provides access control for group relation plugins.
Namespace
Drupal\group\Plugin\Group\RelationHandlerDefaultCode
public function entityAccess(EntityInterface $entity, $operation, AccountInterface $account, $return_as_object = FALSE) {
/** @var \Drupal\group\Entity\Storage\GroupContentStorageInterface $storage */
$storage = $this
->entityTypeManager()
->getStorage('group_content');
$group_contents = $storage
->loadByEntity($entity);
// Filter out the content that does not use this plugin.
foreach ($group_contents as $id => $group_content) {
// @todo Shows the need for a plugin ID base field.
$plugin_id = $group_content
->getRelationPlugin()
->getPluginId();
if ($plugin_id !== $this->pluginId) {
unset($group_contents[$id]);
}
}
// If this plugin is not being used by the entity, we have nothing to say.
if (empty($group_contents)) {
return AccessResult::neutral();
}
// We only check unpublished vs published for "view" right now. If we ever
// start supporting other operations, we need to remove the "view" check.
$check_published = $operation === 'view' && $entity
->getEntityType()
->entityClassImplements(EntityPublishedInterface::class);
// Check if the account is the owner and an owner permission is supported.
$is_owner = FALSE;
if ($entity
->getEntityType()
->entityClassImplements(EntityOwnerInterface::class)) {
$is_owner = $entity
->getOwnerId() === $account
->id();
}
// Add in the admin permission and filter out the unsupported permissions.
$permissions = [
$this->permissionProvider
->getAdminPermission(),
];
if (!$check_published || $entity
->isPublished()) {
$permissions[] = $this->permissionProvider
->getPermission($operation, 'entity', 'any');
$own_permission = $this->permissionProvider
->getPermission($operation, 'entity', 'own');
if ($is_owner) {
$permissions[] = $own_permission;
}
}
elseif ($check_published && !$entity
->isPublished()) {
$permissions[] = $this->permissionProvider
->getPermission("{$operation} unpublished", 'entity', 'any');
$own_permission = $this->permissionProvider
->getPermission("{$operation} unpublished", 'entity', 'own');
if ($is_owner) {
$permissions[] = $own_permission;
}
}
$permissions = array_filter($permissions);
foreach ($group_contents as $group_content) {
$result = GroupAccessResult::allowedIfHasGroupPermissions($group_content
->getGroup(), $account, $permissions, 'OR');
if ($result
->isAllowed()) {
break;
}
}
// If we did not allow access, we need to explicitly forbid access to avoid
// other modules from granting access where Group promised the entity would
// be inaccessible.
if (!$result
->isAllowed()) {
$result = AccessResult::forbidden()
->addCacheContexts([
'user.group_permissions',
]);
}
// If there was an owner permission to check, the result needs to vary per
// user. We also need to add the entity as a dependency because if its owner
// changes, someone might suddenly gain or lose access.
if (!empty($own_permission)) {
// @todo Not necessary if admin, could boost performance here.
$result
->cachePerUser();
}
// If we needed to check for the owner permission or published access, we
// need to add the entity as a dependency because the owner or publication
// status might change.
if (!empty($own_permission) || $check_published) {
// @todo Not necessary if admin, could boost performance here.
$result
->addCacheableDependency($entity);
}
return $return_as_object ? $result : $result
->isAllowed();
}