You are here

function group_entity_access in Group 8

Same name and namespace in other branches
  1. 7 group.entity.inc \group_entity_access()
  2. 2.0.x group.module \group_entity_access()

Implements hook_entity_access().

File

./group.module, line 294
Allows you to group users, content and other entities.

Code

function group_entity_access(EntityInterface $entity, $operation, AccountInterface $account) {

  // Some modules, including the code in \Drupal\node\NodeForm::access() may
  // check for 'view', 'update' or 'delete' access on new entities, even though
  // that makes little sense. We need to account for it to avoid crashes because
  // we would otherwise query the DB with a non-existent node ID.
  if ($entity
    ->isNew()) {
    return AccessResult::neutral();
  }

  /** @var \Drupal\group\Plugin\GroupContentEnablerManagerInterface $plugin_manager */
  $plugin_manager = \Drupal::service('plugin.manager.group_content_enabler');

  // Find all of the group content plugins that define access.
  $plugin_ids = $plugin_manager
    ->getPluginIdsByEntityTypeAccess($entity
    ->getEntityTypeId());
  if (empty($plugin_ids)) {
    return AccessResult::neutral();
  }

  // If any new group content entity is added using any of the retrieved
  // plugins, it might change access.
  $plugin_cache_tags = [];
  foreach ($plugin_ids as $plugin_id) {
    $plugin_cache_tags[] = "group_content_list:plugin:{$plugin_id}";
  }

  // Load all of the group content for this entity.
  $group_contents = \Drupal::entityTypeManager()
    ->getStorage('group_content')
    ->loadByEntity($entity);

  // If the entity does not belong to any group, we have nothing to say.
  //
  // @todo There is a slight performance boost to be had here. If we have a
  // plugin that adds content without access and one that adds the same content
  // with access, then this check would fail for content that is only added
  // using the non-access plugin. The loop over the plugin IDs below would then
  // not return anything and we would still end up with a neutral result, albeit
  // with the user.group_permissions context and slightly worse performance. We
  // can fix this by only loading those group content entities that use the
  // plugins retrieved above.
  if (empty($group_contents)) {
    return AccessResult::neutral()
      ->addCacheTags($plugin_cache_tags);
  }
  $access = AccessResult::neutral();
  foreach ($plugin_ids as $plugin_id) {

    // For backwards compatibility reasons, if the group content enabler plugin
    // used by the group content type does not specify an access handler, we do
    // not check access for that group content type. In 8.2.x all group content
    // enabler plugins will get a permission handler by default, so this check
    // can be safely removed then.
    if (!$plugin_manager
      ->hasHandler($plugin_id, 'access')) {
      continue;
    }
    $handler = $plugin_manager
      ->getAccessControlHandler($plugin_id);
    $access = $access
      ->orIf($handler
      ->entityAccess($entity, $operation, $account, TRUE));
  }
  return $access
    ->addCacheTags($plugin_cache_tags)
    ->addCacheContexts([
    'user.group_permissions',
  ]);
}