class GroupContentQueryAccessHandler in Group 2.0.x
Same name and namespace in other branches
- 8 src/Entity/Access/GroupContentQueryAccessHandler.php \Drupal\group\Entity\Access\GroupContentQueryAccessHandler
Controls query access for group_content entities.
Hierarchy
- class \Drupal\group\Entity\Access\QueryAccessHandlerBase implements \Drupal\entity\QueryAccess\QueryAccessHandlerInterface, EntityHandlerInterface
- class \Drupal\group\Entity\Access\GroupContentQueryAccessHandler
Expanded class hierarchy of GroupContentQueryAccessHandler
See also
\Drupal\entity\QueryAccess\QueryAccessHandler
1 file declares its use of GroupContentQueryAccessHandler
- GroupContentQueryAccessHandlerTest.php in tests/
src/ Kernel/ GroupContentQueryAccessHandlerTest.php
File
- src/
Entity/ Access/ GroupContentQueryAccessHandler.php, line 16
Namespace
Drupal\group\Entity\AccessView source
class GroupContentQueryAccessHandler extends QueryAccessHandlerBase {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The group relation manager.
*
* @var \Drupal\group\Plugin\Group\Relation\GroupRelationManagerInterface
*/
protected $groupRelationManager;
/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
/** @var static $instance */
$instance = parent::createInstance($container, $entity_type);
$instance->entityTypeManager = $container
->get('entity_type.manager');
$instance->groupRelationManager = $container
->get('plugin.manager.group_relation');
return $instance;
}
/**
* {@inheritdoc}
*/
protected function buildConditions($operation, AccountInterface $account) {
$conditions = new ConditionGroup('OR');
// @todo Remove these lines once we kill the bypass permission.
// If the account can bypass group access, we do not alter the query at all.
$conditions
->addCacheContexts([
'user.permissions',
]);
if ($account
->hasPermission('bypass group access')) {
return $conditions;
}
$conditions
->addCacheContexts([
'user.group_permissions',
]);
$calculated_permissions = $this->groupPermissionCalculator
->calculatePermissions($account);
$group_permissions = $calculated_permissions
->getItemsByScope(CGPII::SCOPE_GROUP);
/** @var \Drupal\group\Entity\GroupContentTypeInterface[] $group_content_types */
$group_content_types = $this->entityTypeManager
->getStorage('group_content_type')
->loadMultiple();
$allowed_any_ids = $allowed_own_ids = $all_ids = [];
foreach ($group_content_types as $group_content_type_id => $group_content_type) {
$plugin_id = $group_content_type
->getRelationPluginId();
$handler = $this->groupRelationManager
->getPermissionProvider($plugin_id);
$admin_permission = $handler
->getAdminPermission();
$any_permission = $handler
->getPermission($operation, 'relation', 'any');
$own_permission = $handler
->getPermission($operation, 'relation', 'own');
// For each iteration, we can check all group items because it's still
// faster than checking the DB for which Group ID belongs to which group
// content type. We will add in the group-type scope per group content type.
$applicable_permissions = array_merge($group_permissions, [
$calculated_permissions
->getItem(CGPII::SCOPE_GROUP_TYPE, $group_content_type
->getGroupTypeId()),
]);
foreach ($applicable_permissions as $item) {
$all_ids[$item
->getScope()][] = $item
->getIdentifier();
// For groups, we need to get the group ID, but for group types, we need
// to use the group content type ID rather than the group type ID.
$identifier = $item
->getScope() === CGPII::SCOPE_GROUP ? $item
->getIdentifier() : $group_content_type_id;
if ($admin_permission !== FALSE && $item
->hasPermission($admin_permission)) {
$allowed_any_ids[$item
->getScope()][] = $identifier;
}
elseif ($any_permission !== FALSE && $item
->hasPermission($any_permission)) {
$allowed_any_ids[$item
->getScope()][] = $identifier;
}
elseif ($own_permission !== FALSE && $item
->hasPermission($own_permission)) {
$allowed_own_ids[$item
->getScope()][] = $identifier;
}
}
}
// If no group type or group gave access, we deny access altogether.
if (empty($allowed_any_ids) && empty($allowed_own_ids)) {
$conditions
->alwaysFalse();
return $conditions;
}
// We might see multiple values in the $all_ids variable because we looped
// over all calculated permissions multiple times.
if (!empty($all_ids[CGPII::SCOPE_GROUP])) {
$all_ids[CGPII::SCOPE_GROUP] = array_unique($all_ids[CGPII::SCOPE_GROUP]);
}
// Add the allowed group types to the query (if any).
if (!empty($allowed_any_ids[CGPII::SCOPE_GROUP_TYPE])) {
$sub_condition = new ConditionGroup();
$sub_condition
->addCondition('type', $allowed_any_ids[CGPII::SCOPE_GROUP_TYPE]);
// If the user had memberships, we need to make sure they are excluded
// from group type based matches as the memberships' permissions take
// precedence.
if (!empty($all_ids[CGPII::SCOPE_GROUP])) {
$sub_condition
->addCondition('gid', $all_ids[CGPII::SCOPE_GROUP], 'NOT IN');
}
$conditions
->addCondition($sub_condition);
}
// Add the allowed owner group types to the query (if any).
if (!empty($allowed_own_ids[CGPII::SCOPE_GROUP_TYPE])) {
$sub_condition = new ConditionGroup();
$sub_condition
->addCondition('uid', $account
->id());
$sub_condition
->addCondition('type', $allowed_own_ids[CGPII::SCOPE_GROUP_TYPE]);
// If the user had memberships, we need to make sure they are excluded
// from group type based matches as the memberships' permissions take
// precedence.
if (!empty($all_ids[CGPII::SCOPE_GROUP])) {
$sub_condition
->addCondition('gid', $all_ids[CGPII::SCOPE_GROUP], 'NOT IN');
}
$conditions
->addCacheContexts([
'user',
]);
$conditions
->addCondition($sub_condition);
}
// Add the memberships with access to the query (if any).
if (!empty($allowed_any_ids[CGPII::SCOPE_GROUP])) {
$conditions
->addCondition('gid', array_unique($allowed_any_ids[CGPII::SCOPE_GROUP]));
}
// Add the owner memberships with access to the query (if any).
if (!empty($allowed_own_ids[CGPII::SCOPE_GROUP])) {
$sub_condition = new ConditionGroup();
$sub_condition
->addCondition('uid', $account
->id());
$sub_condition
->addCondition('gid', array_unique($allowed_own_ids[CGPII::SCOPE_GROUP]));
$conditions
->addCacheContexts([
'user',
]);
$conditions
->addCondition($sub_condition);
}
return $conditions;
}
}