@@ -83,17 +83,13 @@ public function getUserGroups(AccountInterface $user, array $states = [OgMembers
83
83
public function getMemberships (AccountInterface $ user , array $ states = [OgMembershipInterface::STATE_ACTIVE ]) {
84
84
// When an empty array is passed, retrieve memberships with all possible
85
85
// 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 );
91
87
92
88
$ identifier = [
93
89
__METHOD__ ,
94
90
'user ' ,
95
91
$ user ->id (),
96
- $ states_identifier ,
92
+ implode ( ' | ' , $ states ) ,
97
93
];
98
94
$ identifier = implode (': ' , $ identifier );
99
95
@@ -108,9 +104,7 @@ public function getMemberships(AccountInterface $user, array $states = [OgMember
108
104
$ this ->cache [$ identifier ] = $ query ->execute ();
109
105
}
110
106
111
- return $ this ->entityTypeManager
112
- ->getStorage ('og_membership ' )
113
- ->loadMultiple ($ this ->cache [$ identifier ]);
107
+ return $ this ->loadMemberships ($ this ->cache [$ identifier ]);
114
108
}
115
109
116
110
/**
@@ -127,6 +121,59 @@ public function getMembership(EntityInterface $group, AccountInterface $user, ar
127
121
return NULL ;
128
122
}
129
123
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
+
130
177
/**
131
178
* {@inheritdoc}
132
179
*/
@@ -318,4 +365,49 @@ public function reset() {
318
365
$ this ->cache = [];
319
366
}
320
367
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
+
321
413
}
0 commit comments