Skip to content
This repository has been archived by the owner on Aug 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #451 from Gizra/get-group-memberships-by-roles
Browse files Browse the repository at this point in the history
Provide a way to retrieve all group memberships by role
  • Loading branch information
amitaibu authored Dec 19, 2018
2 parents b54a74e + 8205988 commit dcb1bca
Show file tree
Hide file tree
Showing 3 changed files with 456 additions and 25 deletions.
110 changes: 101 additions & 9 deletions src/MembershipManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,13 @@ public function getUserGroups(AccountInterface $user, array $states = [OgMembers
public function getMemberships(AccountInterface $user, array $states = [OgMembershipInterface::STATE_ACTIVE]) {
// When an empty array is passed, retrieve memberships with all possible
// states.
$states = $states ?: OgMembership::ALL_STATES;

// Get a string identifier of the states, so we can retrieve it from cache.
sort($states);
$states_identifier = implode('|', array_unique($states));
$states = $this->prepareConditionArray($states, OgMembership::ALL_STATES);

$identifier = [
__METHOD__,
'user',
$user->id(),
$states_identifier,
implode('|', $states),
];
$identifier = implode(':', $identifier);

Expand All @@ -108,9 +104,7 @@ public function getMemberships(AccountInterface $user, array $states = [OgMember
$this->cache[$identifier] = $query->execute();
}

return $this->entityTypeManager
->getStorage('og_membership')
->loadMultiple($this->cache[$identifier]);
return $this->loadMemberships($this->cache[$identifier]);
}

/**
Expand All @@ -127,6 +121,59 @@ public function getMembership(EntityInterface $group, AccountInterface $user, ar
return NULL;
}

/**
* {@inheritdoc}
*/
public function getGroupMembershipsByRoleNames(EntityInterface $group, array $role_names, array $states = [OgMembershipInterface::STATE_ACTIVE]) {
if (empty($role_names)) {
throw new \InvalidArgumentException('The array of role names should not be empty.');
}

// In case the 'member' role is one of the requested roles, we just need to
// return all memberships. We can safely ignore all other roles.
$retrieve_all_memberships = FALSE;
if (in_array(OgRoleInterface::AUTHENTICATED, $role_names)) {
$retrieve_all_memberships = TRUE;
$role_names = [OgRoleInterface::AUTHENTICATED];
}

$role_names = $this->prepareConditionArray($role_names);
$states = $this->prepareConditionArray($states, OgMembership::ALL_STATES);

$identifier = [
__METHOD__,
$group->id(),
implode('|', $role_names),
implode('|', $states),
];
$identifier = implode(':', $identifier);

// Only query the database if no cached result exists.
if (!isset($this->cache[$identifier])) {
$entity_type_id = $group->getEntityTypeId();

$query = $this->entityTypeManager
->getStorage('og_membership')
->getQuery()
->condition('entity_type', $entity_type_id)
->condition('entity_id', $group->id())
->condition('state', $states, 'IN');

if (!$retrieve_all_memberships) {
$bundle_id = $group->bundle();
$role_ids = array_map(function ($role_name) use ($entity_type_id, $bundle_id) {
return implode('-', [$entity_type_id, $bundle_id, $role_name]);
}, $role_names);

$query->condition('roles', $role_ids, 'IN');
}

$this->cache[$identifier] = $query->execute();
}

return $this->loadMemberships($this->cache[$identifier]);
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -318,4 +365,49 @@ public function reset() {
$this->cache = [];
}

/**
* Prepares a conditional array for use in a cache identifier and query.
*
* This will filter out any duplicate values from the array and sort the
* values so that a consistent cache identifier can be generated. Optionally
* it can substitute an empty array with a default value.
*
* @param array $value
* The array to prepare.
* @param array|null $default
* An optional default value to use in case the passed in value is empty. If
* set to NULL this will be ignored.
*
* @return array
* The prepared array.
*/
protected function prepareConditionArray(array $value, array $default = NULL) {
// Fall back to the default value if the passed in value is empty and a
// default value is given.
if (empty($value) && $default !== NULL) {
$value = $default;
}
sort($value);
return array_unique($value);
}

/**
* Returns the full membership entities with the given memberships IDs.
*
* @param array $ids
* The IDs of the memberships to load.
*
* @return \Drupal\Core\Entity\EntityInterface[]
* The membership entities.
*/
protected function loadMemberships(array $ids) {
if (empty($ids)) {
return [];
}

return $this->entityTypeManager
->getStorage('og_membership')
->loadMultiple($ids);
}

}
17 changes: 17 additions & 0 deletions src/MembershipManagerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,23 @@ public function getMemberships(AccountInterface $user, array $states = [OgMember
*/
public function getMembership(EntityInterface $group, AccountInterface $user, array $states = [OgMembershipInterface::STATE_ACTIVE]);

/**
* Returns the memberships of the given group filtered by role name.
*
* @param \Drupal\Core\Entity\EntityInterface $group
* The group entity for which to return the memberships.
* @param array $role_names
* An array of role names to filter by.
* @param array $states
* (optional) Array with the states to return. Defaults to only returning
* active memberships. In order to retrieve all memberships regardless of
* state, pass `OgMembershipInterface::ALL_STATES`.
*
* @return \Drupal\Core\Entity\EntityInterface[]
* The membership entities.
*/
public function getGroupMembershipsByRoleNames(EntityInterface $group, array $role_names, array $states = [OgMembershipInterface::STATE_ACTIVE]);

/**
* Creates an OG membership.
*
Expand Down
Loading

0 comments on commit dcb1bca

Please sign in to comment.