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

Commit dcb1bca

Browse files
authored
Merge pull request #451 from Gizra/get-group-memberships-by-roles
Provide a way to retrieve all group memberships by role
2 parents b54a74e + 8205988 commit dcb1bca

File tree

3 files changed

+456
-25
lines changed

3 files changed

+456
-25
lines changed

src/MembershipManager.php

Lines changed: 101 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,13 @@ public function getUserGroups(AccountInterface $user, array $states = [OgMembers
8383
public function getMemberships(AccountInterface $user, array $states = [OgMembershipInterface::STATE_ACTIVE]) {
8484
// When an empty array is passed, retrieve memberships with all possible
8585
// states.
86-
$states = $states ?: OgMembership::ALL_STATES;
87-
88-
// Get a string identifier of the states, so we can retrieve it from cache.
89-
sort($states);
90-
$states_identifier = implode('|', array_unique($states));
86+
$states = $this->prepareConditionArray($states, OgMembership::ALL_STATES);
9187

9288
$identifier = [
9389
__METHOD__,
9490
'user',
9591
$user->id(),
96-
$states_identifier,
92+
implode('|', $states),
9793
];
9894
$identifier = implode(':', $identifier);
9995

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

111-
return $this->entityTypeManager
112-
->getStorage('og_membership')
113-
->loadMultiple($this->cache[$identifier]);
107+
return $this->loadMemberships($this->cache[$identifier]);
114108
}
115109

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

124+
/**
125+
* {@inheritdoc}
126+
*/
127+
public function getGroupMembershipsByRoleNames(EntityInterface $group, array $role_names, array $states = [OgMembershipInterface::STATE_ACTIVE]) {
128+
if (empty($role_names)) {
129+
throw new \InvalidArgumentException('The array of role names should not be empty.');
130+
}
131+
132+
// In case the 'member' role is one of the requested roles, we just need to
133+
// return all memberships. We can safely ignore all other roles.
134+
$retrieve_all_memberships = FALSE;
135+
if (in_array(OgRoleInterface::AUTHENTICATED, $role_names)) {
136+
$retrieve_all_memberships = TRUE;
137+
$role_names = [OgRoleInterface::AUTHENTICATED];
138+
}
139+
140+
$role_names = $this->prepareConditionArray($role_names);
141+
$states = $this->prepareConditionArray($states, OgMembership::ALL_STATES);
142+
143+
$identifier = [
144+
__METHOD__,
145+
$group->id(),
146+
implode('|', $role_names),
147+
implode('|', $states),
148+
];
149+
$identifier = implode(':', $identifier);
150+
151+
// Only query the database if no cached result exists.
152+
if (!isset($this->cache[$identifier])) {
153+
$entity_type_id = $group->getEntityTypeId();
154+
155+
$query = $this->entityTypeManager
156+
->getStorage('og_membership')
157+
->getQuery()
158+
->condition('entity_type', $entity_type_id)
159+
->condition('entity_id', $group->id())
160+
->condition('state', $states, 'IN');
161+
162+
if (!$retrieve_all_memberships) {
163+
$bundle_id = $group->bundle();
164+
$role_ids = array_map(function ($role_name) use ($entity_type_id, $bundle_id) {
165+
return implode('-', [$entity_type_id, $bundle_id, $role_name]);
166+
}, $role_names);
167+
168+
$query->condition('roles', $role_ids, 'IN');
169+
}
170+
171+
$this->cache[$identifier] = $query->execute();
172+
}
173+
174+
return $this->loadMemberships($this->cache[$identifier]);
175+
}
176+
130177
/**
131178
* {@inheritdoc}
132179
*/
@@ -318,4 +365,49 @@ public function reset() {
318365
$this->cache = [];
319366
}
320367

368+
/**
369+
* Prepares a conditional array for use in a cache identifier and query.
370+
*
371+
* This will filter out any duplicate values from the array and sort the
372+
* values so that a consistent cache identifier can be generated. Optionally
373+
* it can substitute an empty array with a default value.
374+
*
375+
* @param array $value
376+
* The array to prepare.
377+
* @param array|null $default
378+
* An optional default value to use in case the passed in value is empty. If
379+
* set to NULL this will be ignored.
380+
*
381+
* @return array
382+
* The prepared array.
383+
*/
384+
protected function prepareConditionArray(array $value, array $default = NULL) {
385+
// Fall back to the default value if the passed in value is empty and a
386+
// default value is given.
387+
if (empty($value) && $default !== NULL) {
388+
$value = $default;
389+
}
390+
sort($value);
391+
return array_unique($value);
392+
}
393+
394+
/**
395+
* Returns the full membership entities with the given memberships IDs.
396+
*
397+
* @param array $ids
398+
* The IDs of the memberships to load.
399+
*
400+
* @return \Drupal\Core\Entity\EntityInterface[]
401+
* The membership entities.
402+
*/
403+
protected function loadMemberships(array $ids) {
404+
if (empty($ids)) {
405+
return [];
406+
}
407+
408+
return $this->entityTypeManager
409+
->getStorage('og_membership')
410+
->loadMultiple($ids);
411+
}
412+
321413
}

src/MembershipManagerInterface.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,23 @@ public function getMemberships(AccountInterface $user, array $states = [OgMember
8888
*/
8989
public function getMembership(EntityInterface $group, AccountInterface $user, array $states = [OgMembershipInterface::STATE_ACTIVE]);
9090

91+
/**
92+
* Returns the memberships of the given group filtered by role name.
93+
*
94+
* @param \Drupal\Core\Entity\EntityInterface $group
95+
* The group entity for which to return the memberships.
96+
* @param array $role_names
97+
* An array of role names to filter by.
98+
* @param array $states
99+
* (optional) Array with the states to return. Defaults to only returning
100+
* active memberships. In order to retrieve all memberships regardless of
101+
* state, pass `OgMembershipInterface::ALL_STATES`.
102+
*
103+
* @return \Drupal\Core\Entity\EntityInterface[]
104+
* The membership entities.
105+
*/
106+
public function getGroupMembershipsByRoleNames(EntityInterface $group, array $role_names, array $states = [OgMembershipInterface::STATE_ACTIVE]);
107+
91108
/**
92109
* Creates an OG membership.
93110
*

0 commit comments

Comments
 (0)