You are here

public function OgAccess::userAccessEntityOperation in Organic groups 8

Checks whether a user can perform an operation on a given entity.

This does an exhaustive, but slow, check to discover whether the operation can be performed. It works both with groups and group content entities. It will iterate over all groups that are associated with the entity and check if the user is allowed to perform the entity operation on the group content entity according to their role within each group.

For access to be granted, at least one of the groups with which the entity is associated should allow access, and none of the associated groups should deny access. Access is denied if one or more groups deny access, regardless of how many groups grant access. A neutral result is returned if the passed in entity is not associated with any groups, or if all the associated groups return a neutral result.

If a passed in entity is both a group and group content, it will first check if the user has permission to perform the operation on the entity itself. Only if this returns a neutral result the access check will be performed on its parent group(s).

In case you know the specific group you want to check access for then it is recommended to use the faster ::userAccessGroupContentEntityOperation().

Parameters

string $operation: The entity operation, such as "create", "update" or "delete".

\Drupal\Core\Entity\EntityInterface $entity: The entity object. This can be either a group or group content entity.

\Drupal\Core\Session\AccountInterface|null $user: (optional) The user object. If empty the current user will be used.

Return value

\Drupal\Core\Access\AccessResultInterface An access result object.

Overrides OgAccessInterface::userAccessEntityOperation

See also

\Drupal\og\userAccessGroupContentEntityOperation();

File

src/OgAccess.php, line 265

Class

OgAccess
The service that determines if users have access to groups and group content.

Namespace

Drupal\og

Code

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)) {

    // We are performing an entity operation on a group entity. Map the
    // operation to the corresponding group level permission.
    if (array_key_exists($operation, self::OPERATION_GROUP_PERMISSION_MAPPING)) {
      $permission = self::OPERATION_GROUP_PERMISSION_MAPPING[$operation];

      // An entity can be a group and group content in the same time. If the
      // group returns a neutral result the user still might have access to
      // the permission in group content context. So if we get a neutral
      // result we will continue with the group content access check below.
      $result = $this
        ->userAccess($entity, $permission, $user);
      if (!$result
        ->isNeutral()) {
        return $result;
      }
    }
  }
  if ($this->groupTypeManager
    ->isGroupContent($entity_type_id, $bundle)) {
    $result
      ->addCacheTags($entity_type
      ->getListCacheTags());

    // The entity might be a user or a non-user entity.
    $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;
}