1 | <?php |
||
2 | |||
3 | /** |
||
4 | * This file contains functions regarding manipulation of and information about membergroups. |
||
5 | * |
||
6 | * Simple Machines Forum (SMF) |
||
7 | * |
||
8 | * @package SMF |
||
9 | * @author Simple Machines https://www.simplemachines.org |
||
10 | * @copyright 2022 Simple Machines and individual contributors |
||
11 | * @license https://www.simplemachines.org/about/smf/license.php BSD |
||
12 | * |
||
13 | * @version 2.1.0 |
||
14 | */ |
||
15 | |||
16 | if (!defined('SMF')) |
||
17 | die('No direct access...'); |
||
18 | |||
19 | /** |
||
20 | * Delete one of more membergroups. |
||
21 | * Requires the manage_membergroups permission. |
||
22 | * Returns true on success or false on failure. |
||
23 | * Has protection against deletion of protected membergroups. |
||
24 | * Deletes the permissions linked to the membergroup. |
||
25 | * Takes members out of the deleted membergroups. |
||
26 | * |
||
27 | * @param int|array $groups The ID of the group to delete or an array of IDs of groups to delete |
||
28 | * @return bool|string True for success, otherwise an identifier as to reason for failure |
||
29 | */ |
||
30 | function deleteMembergroups($groups) |
||
31 | { |
||
32 | global $smcFunc, $modSettings, $txt; |
||
33 | |||
34 | // Make sure it's an array. |
||
35 | if (!is_array($groups)) |
||
36 | $groups = array((int) $groups); |
||
37 | else |
||
38 | { |
||
39 | $groups = array_unique($groups); |
||
40 | |||
41 | // Make sure all groups are integer. |
||
42 | foreach ($groups as $key => $value) |
||
43 | $groups[$key] = (int) $value; |
||
44 | } |
||
45 | |||
46 | // Some groups are protected (guests, administrators, moderators, newbies). |
||
47 | $protected_groups = array(-1, 0, 1, 3, 4); |
||
48 | |||
49 | // There maybe some others as well. |
||
50 | if (!allowedTo('admin_forum')) |
||
51 | { |
||
52 | $request = $smcFunc['db_query']('', ' |
||
53 | SELECT id_group |
||
54 | FROM {db_prefix}membergroups |
||
55 | WHERE group_type = {int:is_protected}', |
||
56 | array( |
||
57 | 'is_protected' => 1, |
||
58 | ) |
||
59 | ); |
||
60 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
61 | $protected_groups[] = $row['id_group']; |
||
62 | $smcFunc['db_free_result']($request); |
||
63 | } |
||
64 | |||
65 | // Make sure they don't delete protected groups! |
||
66 | $groups = array_diff($groups, array_unique($protected_groups)); |
||
67 | if (empty($groups)) |
||
68 | return 'no_group_found'; |
||
69 | |||
70 | // Make sure they don't try to delete a group attached to a paid subscription. |
||
71 | $subscriptions = array(); |
||
72 | $request = $smcFunc['db_query']('', ' |
||
73 | SELECT id_subscribe, name, id_group, add_groups |
||
74 | FROM {db_prefix}subscriptions |
||
75 | ORDER BY name'); |
||
76 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
77 | { |
||
78 | if (in_array($row['id_group'], $groups)) |
||
79 | $subscriptions[] = $row['name']; |
||
80 | else |
||
81 | { |
||
82 | $add_groups = explode(',', $row['add_groups']); |
||
83 | if (count(array_intersect($add_groups, $groups)) != 0) |
||
84 | $subscriptions[] = $row['name']; |
||
85 | } |
||
86 | } |
||
87 | $smcFunc['db_free_result']($request); |
||
88 | if (!empty($subscriptions)) |
||
89 | { |
||
90 | // Uh oh. But before we return, we need to update a language string because we want the names of the groups. |
||
91 | loadLanguage('ManageMembers'); |
||
92 | $txt['membergroups_cannot_delete_paid'] = sprintf($txt['membergroups_cannot_delete_paid'], implode(', ', $subscriptions)); |
||
93 | return 'group_cannot_delete_sub'; |
||
94 | } |
||
95 | |||
96 | // Log the deletion. |
||
97 | $request = $smcFunc['db_query']('', ' |
||
98 | SELECT group_name |
||
99 | FROM {db_prefix}membergroups |
||
100 | WHERE id_group IN ({array_int:group_list})', |
||
101 | array( |
||
102 | 'group_list' => $groups, |
||
103 | ) |
||
104 | ); |
||
105 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
106 | logAction('delete_group', array('group' => $row['group_name']), 'admin'); |
||
107 | $smcFunc['db_free_result']($request); |
||
108 | |||
109 | call_integration_hook('integrate_delete_membergroups', array($groups)); |
||
110 | |||
111 | // Remove the membergroups themselves. |
||
112 | $smcFunc['db_query']('', ' |
||
113 | DELETE FROM {db_prefix}membergroups |
||
114 | WHERE id_group IN ({array_int:group_list})', |
||
115 | array( |
||
116 | 'group_list' => $groups, |
||
117 | ) |
||
118 | ); |
||
119 | |||
120 | // Remove the permissions of the membergroups. |
||
121 | $smcFunc['db_query']('', ' |
||
122 | DELETE FROM {db_prefix}permissions |
||
123 | WHERE id_group IN ({array_int:group_list})', |
||
124 | array( |
||
125 | 'group_list' => $groups, |
||
126 | ) |
||
127 | ); |
||
128 | $smcFunc['db_query']('', ' |
||
129 | DELETE FROM {db_prefix}board_permissions |
||
130 | WHERE id_group IN ({array_int:group_list})', |
||
131 | array( |
||
132 | 'group_list' => $groups, |
||
133 | ) |
||
134 | ); |
||
135 | $smcFunc['db_query']('', ' |
||
136 | DELETE FROM {db_prefix}group_moderators |
||
137 | WHERE id_group IN ({array_int:group_list})', |
||
138 | array( |
||
139 | 'group_list' => $groups, |
||
140 | ) |
||
141 | ); |
||
142 | $smcFunc['db_query']('', ' |
||
143 | DELETE FROM {db_prefix}moderator_groups |
||
144 | WHERE id_group IN ({array_int:group_list})', |
||
145 | array( |
||
146 | 'group_list' => $groups, |
||
147 | ) |
||
148 | ); |
||
149 | |||
150 | // Delete any outstanding requests. |
||
151 | $smcFunc['db_query']('', ' |
||
152 | DELETE FROM {db_prefix}log_group_requests |
||
153 | WHERE id_group IN ({array_int:group_list})', |
||
154 | array( |
||
155 | 'group_list' => $groups, |
||
156 | ) |
||
157 | ); |
||
158 | |||
159 | // Update the primary groups of members. |
||
160 | $smcFunc['db_query']('', ' |
||
161 | UPDATE {db_prefix}members |
||
162 | SET id_group = {int:regular_group} |
||
163 | WHERE id_group IN ({array_int:group_list})', |
||
164 | array( |
||
165 | 'group_list' => $groups, |
||
166 | 'regular_group' => 0, |
||
167 | ) |
||
168 | ); |
||
169 | |||
170 | // Update any inherited groups (Lose inheritance). |
||
171 | $smcFunc['db_query']('', ' |
||
172 | UPDATE {db_prefix}membergroups |
||
173 | SET id_parent = {int:uninherited} |
||
174 | WHERE id_parent IN ({array_int:group_list})', |
||
175 | array( |
||
176 | 'group_list' => $groups, |
||
177 | 'uninherited' => -2, |
||
178 | ) |
||
179 | ); |
||
180 | |||
181 | // Update the additional groups of members. |
||
182 | $request = $smcFunc['db_query']('', ' |
||
183 | SELECT id_member, additional_groups |
||
184 | FROM {db_prefix}members |
||
185 | WHERE FIND_IN_SET({raw:additional_groups_explode}, additional_groups) != 0', |
||
186 | array( |
||
187 | 'additional_groups_explode' => implode(', additional_groups) != 0 OR FIND_IN_SET(', $groups), |
||
188 | ) |
||
189 | ); |
||
190 | $updates = array(); |
||
191 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
192 | $updates[$row['additional_groups']][] = $row['id_member']; |
||
193 | $smcFunc['db_free_result']($request); |
||
194 | |||
195 | foreach ($updates as $additional_groups => $memberArray) |
||
196 | updateMemberData($memberArray, array('additional_groups' => implode(',', array_diff(explode(',', $additional_groups), $groups)))); |
||
197 | |||
198 | // No boards can provide access to these membergroups anymore. |
||
199 | $request = $smcFunc['db_query']('', ' |
||
200 | SELECT id_board, member_groups |
||
201 | FROM {db_prefix}boards |
||
202 | WHERE FIND_IN_SET({raw:member_groups_explode}, member_groups) != 0', |
||
203 | array( |
||
204 | 'member_groups_explode' => implode(', member_groups) != 0 OR FIND_IN_SET(', $groups), |
||
205 | ) |
||
206 | ); |
||
207 | $updates = array(); |
||
208 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
209 | $updates[$row['member_groups']][] = $row['id_board']; |
||
210 | $smcFunc['db_free_result']($request); |
||
211 | |||
212 | foreach ($updates as $member_groups => $boardArray) |
||
213 | $smcFunc['db_query']('', ' |
||
214 | UPDATE {db_prefix}boards |
||
215 | SET member_groups = {string:member_groups} |
||
216 | WHERE id_board IN ({array_int:board_lists})', |
||
217 | array( |
||
218 | 'board_lists' => $boardArray, |
||
219 | 'member_groups' => implode(',', array_diff(explode(',', $member_groups), $groups)), |
||
220 | ) |
||
221 | ); |
||
222 | |||
223 | // Recalculate the post groups, as they likely changed. |
||
224 | updateStats('postgroups'); |
||
225 | |||
226 | // Make a note of the fact that the cache may be wrong. |
||
227 | $settings_update = array('settings_updated' => time()); |
||
228 | // Have we deleted the spider group? |
||
229 | if (isset($modSettings['spider_group']) && in_array($modSettings['spider_group'], $groups)) |
||
230 | $settings_update['spider_group'] = 0; |
||
231 | |||
232 | updateSettings($settings_update); |
||
233 | |||
234 | // It was a success. |
||
235 | return true; |
||
236 | } |
||
237 | |||
238 | /** |
||
239 | * Remove one or more members from one or more membergroups. |
||
240 | * Requires the manage_membergroups permission. |
||
241 | * Function includes a protection against removing from implicit groups. |
||
242 | * Non-admins are not able to remove members from the admin group. |
||
243 | * |
||
244 | * @param int|array $members The ID of a member or an array of member IDs |
||
245 | * @param null|array The groups to remove the member(s) from. If null, the specified members are stripped from all their membergroups. |
||
0 ignored issues
–
show
|
|||
246 | * @param bool $permissionCheckDone Whether we've already checked permissions prior to calling this function |
||
247 | * @param bool $ignoreProtected Whether to ignore protected groups |
||
248 | * @return bool Whether the operation was successful |
||
249 | */ |
||
250 | function removeMembersFromGroups($members, $groups = null, $permissionCheckDone = false, $ignoreProtected = false) |
||
251 | { |
||
252 | global $smcFunc, $modSettings, $sourcedir; |
||
253 | |||
254 | // You're getting nowhere without this permission, unless of course you are the group's moderator. |
||
255 | if (!$permissionCheckDone) |
||
256 | isAllowedTo('manage_membergroups'); |
||
257 | |||
258 | // Assume something will happen. |
||
259 | updateSettings(array('settings_updated' => time())); |
||
260 | |||
261 | // Cleaning the input. |
||
262 | if (!is_array($members)) |
||
263 | $members = array((int) $members); |
||
264 | else |
||
265 | { |
||
266 | $members = array_unique($members); |
||
267 | |||
268 | // Cast the members to integer. |
||
269 | foreach ($members as $key => $value) |
||
270 | $members[$key] = (int) $value; |
||
271 | } |
||
272 | |||
273 | // Before we get started, let's check we won't leave the admin group empty! |
||
274 | if ($groups === null || $groups == 1 || (is_array($groups) && in_array(1, $groups))) |
||
275 | { |
||
276 | $admins = array(); |
||
277 | listMembergroupMembers_Href($admins, 1); |
||
278 | |||
279 | // Remove any admins if there are too many. |
||
280 | $non_changing_admins = array_diff(array_keys($admins), $members); |
||
281 | |||
282 | if (empty($non_changing_admins)) |
||
283 | $members = array_diff($members, array_keys($admins)); |
||
284 | } |
||
285 | |||
286 | // Just in case. |
||
287 | if (empty($members)) |
||
288 | return false; |
||
289 | elseif ($groups === null) |
||
290 | { |
||
291 | // Wanna remove all groups from these members? That's easy. |
||
292 | $smcFunc['db_query']('', ' |
||
293 | UPDATE {db_prefix}members |
||
294 | SET |
||
295 | id_group = {int:regular_member}, |
||
296 | additional_groups = {string:blank_string} |
||
297 | WHERE id_member IN ({array_int:member_list})' . (allowedTo('admin_forum') ? '' : ' |
||
298 | AND id_group != {int:admin_group} |
||
299 | AND FIND_IN_SET({int:admin_group}, additional_groups) = 0'), |
||
300 | array( |
||
301 | 'member_list' => $members, |
||
302 | 'regular_member' => 0, |
||
303 | 'admin_group' => 1, |
||
304 | 'blank_string' => '', |
||
305 | ) |
||
306 | ); |
||
307 | |||
308 | updateStats('postgroups', $members); |
||
309 | |||
310 | // Log what just happened. |
||
311 | foreach ($members as $member) |
||
312 | logAction('removed_all_groups', array('member' => $member), 'admin'); |
||
313 | |||
314 | return true; |
||
315 | } |
||
316 | elseif (!is_array($groups)) |
||
317 | $groups = array((int) $groups); |
||
318 | else |
||
319 | { |
||
320 | $groups = array_unique($groups); |
||
321 | |||
322 | // Make sure all groups are integer. |
||
323 | foreach ($groups as $key => $value) |
||
324 | $groups[$key] = (int) $value; |
||
325 | } |
||
326 | |||
327 | // Fetch a list of groups members cannot be assigned to explicitly, and the group names of the ones we want. |
||
328 | $implicitGroups = array(-1, 0, 3); |
||
329 | $request = $smcFunc['db_query']('', ' |
||
330 | SELECT id_group, group_name, min_posts |
||
331 | FROM {db_prefix}membergroups |
||
332 | WHERE id_group IN ({array_int:group_list})', |
||
333 | array( |
||
334 | 'group_list' => $groups, |
||
335 | ) |
||
336 | ); |
||
337 | $group_names = array(); |
||
338 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
339 | { |
||
340 | if ($row['min_posts'] != -1) |
||
341 | $implicitGroups[] = $row['id_group']; |
||
342 | else |
||
343 | $group_names[$row['id_group']] = $row['group_name']; |
||
344 | } |
||
345 | $smcFunc['db_free_result']($request); |
||
346 | |||
347 | // Now get rid of those groups. |
||
348 | $groups = array_diff($groups, $implicitGroups); |
||
349 | |||
350 | // Don't forget the protected groups. |
||
351 | if (!allowedTo('admin_forum') && !$ignoreProtected) |
||
352 | { |
||
353 | $request = $smcFunc['db_query']('', ' |
||
354 | SELECT id_group |
||
355 | FROM {db_prefix}membergroups |
||
356 | WHERE group_type = {int:is_protected}', |
||
357 | array( |
||
358 | 'is_protected' => 1, |
||
359 | ) |
||
360 | ); |
||
361 | $protected_groups = array(1); |
||
362 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
363 | $protected_groups[] = $row['id_group']; |
||
364 | $smcFunc['db_free_result']($request); |
||
365 | |||
366 | // If you're not an admin yourself, you can't touch protected groups! |
||
367 | $groups = array_diff($groups, array_unique($protected_groups)); |
||
368 | } |
||
369 | |||
370 | // Only continue if there are still groups and members left. |
||
371 | if (empty($groups) || empty($members)) |
||
372 | return false; |
||
373 | |||
374 | // First, reset those who have this as their primary group - this is the easy one. |
||
375 | $log_inserts = array(); |
||
376 | $request = $smcFunc['db_query']('', ' |
||
377 | SELECT id_member, id_group |
||
378 | FROM {db_prefix}members AS members |
||
379 | WHERE id_group IN ({array_int:group_list}) |
||
380 | AND id_member IN ({array_int:member_list})', |
||
381 | array( |
||
382 | 'group_list' => $groups, |
||
383 | 'member_list' => $members, |
||
384 | ) |
||
385 | ); |
||
386 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
387 | $log_inserts[] = array('group' => $group_names[$row['id_group']], 'member' => $row['id_member']); |
||
388 | $smcFunc['db_free_result']($request); |
||
389 | |||
390 | $smcFunc['db_query']('', ' |
||
391 | UPDATE {db_prefix}members |
||
392 | SET id_group = {int:regular_member} |
||
393 | WHERE id_group IN ({array_int:group_list}) |
||
394 | AND id_member IN ({array_int:member_list})', |
||
395 | array( |
||
396 | 'group_list' => $groups, |
||
397 | 'member_list' => $members, |
||
398 | 'regular_member' => 0, |
||
399 | ) |
||
400 | ); |
||
401 | |||
402 | // Those who have it as part of their additional group must be updated the long way... sadly. |
||
403 | $request = $smcFunc['db_query']('', ' |
||
404 | SELECT id_member, additional_groups |
||
405 | FROM {db_prefix}members |
||
406 | WHERE (FIND_IN_SET({raw:additional_groups_implode}, additional_groups) != 0) |
||
407 | AND id_member IN ({array_int:member_list}) |
||
408 | LIMIT {int:limit}', |
||
409 | array( |
||
410 | 'member_list' => $members, |
||
411 | 'additional_groups_implode' => implode(', additional_groups) != 0 OR FIND_IN_SET(', $groups), |
||
412 | 'limit' => count($members), |
||
413 | ) |
||
414 | ); |
||
415 | $updates = array(); |
||
416 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
417 | { |
||
418 | // What log entries must we make for this one, eh? |
||
419 | foreach (explode(',', $row['additional_groups']) as $group) |
||
420 | if (in_array($group, $groups)) |
||
421 | $log_inserts[] = array('group' => $group_names[$group], 'member' => $row['id_member']); |
||
422 | |||
423 | $updates[$row['additional_groups']][] = $row['id_member']; |
||
424 | } |
||
425 | $smcFunc['db_free_result']($request); |
||
426 | |||
427 | foreach ($updates as $additional_groups => $memberArray) |
||
428 | $smcFunc['db_query']('', ' |
||
429 | UPDATE {db_prefix}members |
||
430 | SET additional_groups = {string:additional_groups} |
||
431 | WHERE id_member IN ({array_int:member_list})', |
||
432 | array( |
||
433 | 'member_list' => $memberArray, |
||
434 | 'additional_groups' => implode(',', array_diff(explode(',', $additional_groups), $groups)), |
||
435 | ) |
||
436 | ); |
||
437 | |||
438 | // Their post groups may have changed now... |
||
439 | updateStats('postgroups', $members); |
||
440 | |||
441 | // Do the log. |
||
442 | if (!empty($log_inserts) && !empty($modSettings['modlog_enabled'])) |
||
443 | { |
||
444 | require_once($sourcedir . '/Logging.php'); |
||
445 | foreach ($log_inserts as $extra) |
||
446 | logAction('removed_from_group', $extra, 'admin'); |
||
447 | } |
||
448 | |||
449 | // Mission successful. |
||
450 | return true; |
||
451 | } |
||
452 | |||
453 | /** |
||
454 | * Add one or more members to a membergroup |
||
455 | * |
||
456 | * Requires the manage_membergroups permission. |
||
457 | * Function has protection against adding members to implicit groups. |
||
458 | * Non-admins are not able to add members to the admin group. |
||
459 | * |
||
460 | * @param int|array $members A single member or an array containing the IDs of members |
||
461 | * @param int $group The group to add them to |
||
462 | * @param string $type Specifies whether the group is added as primary or as additional group. |
||
463 | * Supported types: |
||
464 | * - only_primary - Assigns a membergroup as primary membergroup, but only |
||
465 | * if a member has not yet a primary membergroup assigned, |
||
466 | * unless the member is already part of the membergroup. |
||
467 | * - only_additional - Assigns a membergroup to the additional membergroups, |
||
468 | * unless the member is already part of the membergroup. |
||
469 | * - force_primary - Assigns a membergroup as primary membergroup no matter |
||
470 | * what the previous primary membergroup was. |
||
471 | * - auto - Assigns a membergroup to the primary group if it's still |
||
472 | * available. If not, assign it to the additional group. |
||
473 | * @param bool $permissionCheckDone Whether we've already done a permission check |
||
474 | * @param bool $ignoreProtected Whether to ignore protected groups |
||
475 | * @return bool Whether the operation was successful |
||
476 | */ |
||
477 | function addMembersToGroup($members, $group, $type = 'auto', $permissionCheckDone = false, $ignoreProtected = false) |
||
478 | { |
||
479 | global $smcFunc, $sourcedir, $txt; |
||
480 | |||
481 | // Show your licence, but only if it hasn't been done yet. |
||
482 | if (!$permissionCheckDone) |
||
483 | isAllowedTo('manage_membergroups'); |
||
484 | |||
485 | // Make sure we don't keep old stuff cached. |
||
486 | updateSettings(array('settings_updated' => time())); |
||
487 | |||
488 | if (!is_array($members)) |
||
489 | $members = array((int) $members); |
||
490 | else |
||
491 | { |
||
492 | $members = array_unique($members); |
||
493 | |||
494 | // Make sure all members are integer. |
||
495 | foreach ($members as $key => $value) |
||
496 | $members[$key] = (int) $value; |
||
497 | } |
||
498 | $group = (int) $group; |
||
499 | |||
500 | // Some groups just don't like explicitly having members. |
||
501 | $implicitGroups = array(-1, 0, 3); |
||
502 | $request = $smcFunc['db_query']('', ' |
||
503 | SELECT id_group, group_name, min_posts |
||
504 | FROM {db_prefix}membergroups |
||
505 | WHERE id_group = {int:current_group}', |
||
506 | array( |
||
507 | 'current_group' => $group, |
||
508 | ) |
||
509 | ); |
||
510 | $group_names = array(); |
||
511 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
512 | { |
||
513 | if ($row['min_posts'] != -1) |
||
514 | $implicitGroups[] = $row['id_group']; |
||
515 | else |
||
516 | $group_names[$row['id_group']] = $row['group_name']; |
||
517 | } |
||
518 | $smcFunc['db_free_result']($request); |
||
519 | |||
520 | // Sorry, you can't join an implicit group. |
||
521 | if (in_array($group, $implicitGroups) || empty($members)) |
||
522 | return false; |
||
523 | |||
524 | // Only admins can add admins... |
||
525 | if (!allowedTo('admin_forum') && $group == 1) |
||
526 | return false; |
||
527 | // ... and assign protected groups! |
||
528 | elseif (!allowedTo('admin_forum') && !$ignoreProtected) |
||
529 | { |
||
530 | $request = $smcFunc['db_query']('', ' |
||
531 | SELECT group_type |
||
532 | FROM {db_prefix}membergroups |
||
533 | WHERE id_group = {int:current_group} |
||
534 | LIMIT {int:limit}', |
||
535 | array( |
||
536 | 'current_group' => $group, |
||
537 | 'limit' => 1, |
||
538 | ) |
||
539 | ); |
||
540 | list ($is_protected) = $smcFunc['db_fetch_row']($request); |
||
541 | $smcFunc['db_free_result']($request); |
||
542 | |||
543 | // Is it protected? |
||
544 | if ($is_protected == 1) |
||
545 | return false; |
||
546 | } |
||
547 | |||
548 | // Do the actual updates. |
||
549 | if ($type == 'only_additional') |
||
550 | $smcFunc['db_query']('', ' |
||
551 | UPDATE {db_prefix}members |
||
552 | SET additional_groups = CASE WHEN additional_groups = {string:blank_string} THEN {string:id_group_string} ELSE CONCAT(additional_groups, {string:id_group_string_extend}) END |
||
553 | WHERE id_member IN ({array_int:member_list}) |
||
554 | AND id_group != {int:id_group} |
||
555 | AND FIND_IN_SET({int:id_group}, additional_groups) = 0', |
||
556 | array( |
||
557 | 'member_list' => $members, |
||
558 | 'id_group' => $group, |
||
559 | 'id_group_string' => (string) $group, |
||
560 | 'id_group_string_extend' => ',' . $group, |
||
561 | 'blank_string' => '', |
||
562 | ) |
||
563 | ); |
||
564 | elseif ($type == 'only_primary' || $type == 'force_primary') |
||
565 | $smcFunc['db_query']('', ' |
||
566 | UPDATE {db_prefix}members |
||
567 | SET id_group = {int:id_group} |
||
568 | WHERE id_member IN ({array_int:member_list})' . ($type == 'force_primary' ? '' : ' |
||
569 | AND id_group = {int:regular_group} |
||
570 | AND FIND_IN_SET({int:id_group}, additional_groups) = 0'), |
||
571 | array( |
||
572 | 'member_list' => $members, |
||
573 | 'id_group' => $group, |
||
574 | 'regular_group' => 0, |
||
575 | ) |
||
576 | ); |
||
577 | elseif ($type == 'auto') |
||
578 | $smcFunc['db_query']('', ' |
||
579 | UPDATE {db_prefix}members |
||
580 | SET |
||
581 | id_group = CASE WHEN id_group = {int:regular_group} THEN {int:id_group} ELSE id_group END, |
||
582 | additional_groups = CASE WHEN id_group = {int:id_group} THEN additional_groups |
||
583 | WHEN additional_groups = {string:blank_string} THEN {string:id_group_string} |
||
584 | ELSE CONCAT(additional_groups, {string:id_group_string_extend}) END |
||
585 | WHERE id_member IN ({array_int:member_list}) |
||
586 | AND id_group != {int:id_group} |
||
587 | AND FIND_IN_SET({int:id_group}, additional_groups) = 0', |
||
588 | array( |
||
589 | 'member_list' => $members, |
||
590 | 'regular_group' => 0, |
||
591 | 'id_group' => $group, |
||
592 | 'blank_string' => '', |
||
593 | 'id_group_string' => (string) $group, |
||
594 | 'id_group_string_extend' => ',' . $group, |
||
595 | ) |
||
596 | ); |
||
597 | // Ack!!? What happened? |
||
598 | else |
||
599 | { |
||
600 | loadLanguage('Errors'); |
||
601 | trigger_error(sprintf($txt['add_members_to_group_invalid_type'], $type), E_USER_WARNING); |
||
602 | } |
||
603 | |||
604 | call_integration_hook('integrate_add_members_to_group', array($members, $group, &$group_names)); |
||
605 | |||
606 | // Update their postgroup statistics. |
||
607 | updateStats('postgroups', $members); |
||
608 | |||
609 | // Log the data. |
||
610 | require_once($sourcedir . '/Logging.php'); |
||
611 | foreach ($members as $member) |
||
612 | logAction('added_to_group', array('group' => $group_names[$group], 'member_affected' => $member), 'admin'); |
||
613 | |||
614 | return true; |
||
615 | } |
||
616 | |||
617 | /** |
||
618 | * Gets the members of a supplied membergroup |
||
619 | * Returns them as a link for display |
||
620 | * |
||
621 | * @param array &$members The IDs of the members |
||
622 | * @param int $membergroup The ID of the group |
||
623 | * @param int $limit How many members to show (null for no limit) |
||
624 | * @return bool True if there are more members to display, false otherwise |
||
625 | */ |
||
626 | function listMembergroupMembers_Href(&$members, $membergroup, $limit = null) |
||
627 | { |
||
628 | global $scripturl, $smcFunc; |
||
629 | |||
630 | $request = $smcFunc['db_query']('', ' |
||
631 | SELECT id_member, real_name |
||
632 | FROM {db_prefix}members |
||
633 | WHERE id_group = {int:id_group} OR FIND_IN_SET({int:id_group}, additional_groups) != 0' . ($limit === null ? '' : ' |
||
634 | LIMIT ' . ($limit + 1)), |
||
635 | array( |
||
636 | 'id_group' => $membergroup, |
||
637 | ) |
||
638 | ); |
||
639 | $members = array(); |
||
640 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
641 | $members[$row['id_member']] = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>'; |
||
642 | $smcFunc['db_free_result']($request); |
||
643 | |||
644 | // If there are more than $limit members, add a 'more' link. |
||
645 | if ($limit !== null && count($members) > $limit) |
||
646 | { |
||
647 | array_pop($members); |
||
648 | return true; |
||
649 | } |
||
650 | else |
||
651 | return false; |
||
652 | } |
||
653 | |||
654 | /** |
||
655 | * Retrieve a list of (visible) membergroups used by the cache. |
||
656 | * |
||
657 | * @return array An array of information about the cache |
||
658 | */ |
||
659 | function cache_getMembergroupList() |
||
660 | { |
||
661 | global $scripturl, $smcFunc; |
||
662 | |||
663 | $request = $smcFunc['db_query']('', ' |
||
664 | SELECT id_group, group_name, online_color |
||
665 | FROM {db_prefix}membergroups |
||
666 | WHERE min_posts = {int:min_posts} |
||
667 | AND hidden = {int:not_hidden} |
||
668 | AND id_group != {int:mod_group} |
||
669 | ORDER BY group_name', |
||
670 | array( |
||
671 | 'min_posts' => -1, |
||
672 | 'not_hidden' => 0, |
||
673 | 'mod_group' => 3, |
||
674 | ) |
||
675 | ); |
||
676 | $groupCache = array(); |
||
677 | $group = array(); |
||
678 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
679 | { |
||
680 | $group[$row['id_group']] = $row; |
||
681 | $groupCache[$row['id_group']] = '<a href="' . $scripturl . '?action=groups;sa=members;group=' . $row['id_group'] . '" ' . ($row['online_color'] ? 'style="color: ' . $row['online_color'] . '"' : '') . '>' . $row['group_name'] . '</a>'; |
||
682 | } |
||
683 | $smcFunc['db_free_result']($request); |
||
684 | |||
685 | call_integration_hook('integrate_getMembergroupList', array(&$groupCache, $group)); |
||
686 | |||
687 | return array( |
||
688 | 'data' => $groupCache, |
||
689 | 'expires' => time() + 3600, |
||
690 | 'refresh_eval' => 'return $GLOBALS[\'modSettings\'][\'settings_updated\'] > ' . time() . ';', |
||
691 | ); |
||
692 | } |
||
693 | |||
694 | /** |
||
695 | * Helper function to generate a list of membergroups for display |
||
696 | * |
||
697 | * @param int $start What item to start with (not used here) |
||
698 | * @param int $items_per_page How many items to show on each page (not used here) |
||
699 | * @param string $sort An SQL query indicating how to sort the results |
||
700 | * @param string $membergroup_type Should be 'post_count' for post groups or anything else for regular groups |
||
701 | * @return array An array of group member info for the list |
||
702 | */ |
||
703 | function list_getMembergroups($start, $items_per_page, $sort, $membergroup_type) |
||
704 | { |
||
705 | global $scripturl, $context, $settings, $smcFunc, $user_info; |
||
706 | |||
707 | $request = $smcFunc['db_query']('substring_membergroups', ' |
||
708 | SELECT mg.id_group, mg.group_name, mg.min_posts, mg.description, mg.group_type, mg.online_color, mg.hidden, |
||
709 | mg.icons, COALESCE(gm.id_member, 0) AS can_moderate, 0 AS num_members |
||
710 | FROM {db_prefix}membergroups AS mg |
||
711 | LEFT JOIN {db_prefix}group_moderators AS gm ON (gm.id_group = mg.id_group AND gm.id_member = {int:current_member}) |
||
712 | WHERE mg.min_posts {raw:min_posts}' . (allowedTo('admin_forum') ? '' : ' |
||
713 | AND mg.id_group != {int:mod_group}') . ' |
||
714 | ORDER BY {raw:sort}', |
||
715 | array( |
||
716 | 'current_member' => $user_info['id'], |
||
717 | 'min_posts' => ($membergroup_type === 'post_count' ? '!= ' : '= ') . -1, |
||
718 | 'mod_group' => 3, |
||
719 | 'sort' => $sort, |
||
720 | ) |
||
721 | ); |
||
722 | |||
723 | // Start collecting the data. |
||
724 | $groups = array(); |
||
725 | $group_ids = array(); |
||
726 | $context['can_moderate'] = allowedTo('manage_membergroups'); |
||
727 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
728 | { |
||
729 | // We only list the groups they can see. |
||
730 | if ($row['hidden'] && !$row['can_moderate'] && !allowedTo('manage_membergroups')) |
||
731 | continue; |
||
732 | |||
733 | $row['icons'] = explode('#', $row['icons']); |
||
734 | |||
735 | $groups[$row['id_group']] = array( |
||
736 | 'id_group' => $row['id_group'], |
||
737 | 'group_name' => $row['group_name'], |
||
738 | 'min_posts' => $row['min_posts'], |
||
739 | 'desc' => parse_bbc($row['description'], false, '', $context['description_allowed_tags']), |
||
740 | 'online_color' => $row['online_color'], |
||
741 | 'type' => $row['group_type'], |
||
742 | 'num_members' => $row['num_members'], |
||
743 | 'moderators' => array(), |
||
744 | 'icons' => !empty($row['icons'][0]) && !empty($row['icons'][1]) ? str_repeat('<img src="' . $settings['images_url'] . '/membericons/' . $row['icons'][1] . '" alt="*">', $row['icons'][0]) : '', |
||
745 | ); |
||
746 | |||
747 | $context['can_moderate'] |= $row['can_moderate']; |
||
748 | $group_ids[] = $row['id_group']; |
||
749 | } |
||
750 | $smcFunc['db_free_result']($request); |
||
751 | |||
752 | // If we found any membergroups, get the amount of members in them. |
||
753 | if (!empty($group_ids)) |
||
754 | { |
||
755 | if ($membergroup_type === 'post_count') |
||
756 | { |
||
757 | $query = $smcFunc['db_query']('', ' |
||
758 | SELECT id_post_group AS id_group, COUNT(*) AS num_members |
||
759 | FROM {db_prefix}members |
||
760 | WHERE id_post_group IN ({array_int:group_list}) |
||
761 | GROUP BY id_post_group', |
||
762 | array( |
||
763 | 'group_list' => $group_ids, |
||
764 | ) |
||
765 | ); |
||
766 | while ($row = $smcFunc['db_fetch_assoc']($query)) |
||
767 | $groups[$row['id_group']]['num_members'] += $row['num_members']; |
||
768 | $smcFunc['db_free_result']($query); |
||
769 | } |
||
770 | |||
771 | else |
||
772 | { |
||
773 | $query = $smcFunc['db_query']('', ' |
||
774 | SELECT id_group, COUNT(*) AS num_members |
||
775 | FROM {db_prefix}members |
||
776 | WHERE id_group IN ({array_int:group_list}) |
||
777 | GROUP BY id_group', |
||
778 | array( |
||
779 | 'group_list' => $group_ids, |
||
780 | ) |
||
781 | ); |
||
782 | while ($row = $smcFunc['db_fetch_assoc']($query)) |
||
783 | $groups[$row['id_group']]['num_members'] += $row['num_members']; |
||
784 | $smcFunc['db_free_result']($query); |
||
785 | |||
786 | // Only do additional groups if we can moderate... |
||
787 | if ($context['can_moderate']) |
||
788 | { |
||
789 | $query = $smcFunc['db_query']('', ' |
||
790 | SELECT mg.id_group, COUNT(*) AS num_members |
||
791 | FROM {db_prefix}membergroups AS mg |
||
792 | INNER JOIN {db_prefix}members AS mem ON (mem.additional_groups != {string:blank_string} |
||
793 | AND mem.id_group != mg.id_group |
||
794 | AND FIND_IN_SET(mg.id_group, mem.additional_groups) != 0) |
||
795 | WHERE mg.id_group IN ({array_int:group_list}) |
||
796 | GROUP BY mg.id_group', |
||
797 | array( |
||
798 | 'group_list' => $group_ids, |
||
799 | 'blank_string' => '', |
||
800 | ) |
||
801 | ); |
||
802 | while ($row = $smcFunc['db_fetch_assoc']($query)) |
||
803 | $groups[$row['id_group']]['num_members'] += $row['num_members']; |
||
804 | $smcFunc['db_free_result']($query); |
||
805 | } |
||
806 | } |
||
807 | |||
808 | $query = $smcFunc['db_query']('', ' |
||
809 | SELECT mods.id_group, mods.id_member, mem.member_name, mem.real_name |
||
810 | FROM {db_prefix}group_moderators AS mods |
||
811 | INNER JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member) |
||
812 | WHERE mods.id_group IN ({array_int:group_list})', |
||
813 | array( |
||
814 | 'group_list' => $group_ids, |
||
815 | ) |
||
816 | ); |
||
817 | while ($row = $smcFunc['db_fetch_assoc']($query)) |
||
818 | $groups[$row['id_group']]['moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>'; |
||
819 | $smcFunc['db_free_result']($query); |
||
820 | } |
||
821 | |||
822 | // Apply manual sorting if the 'number of members' column is selected. |
||
823 | if (substr($sort, 0, 1) == '1' || strpos($sort, ', 1') !== false) |
||
824 | { |
||
825 | $sort_ascending = strpos($sort, 'DESC') === false; |
||
826 | |||
827 | foreach ($groups as $group) |
||
828 | $sort_array[] = $group['id_group'] != 3 ? (int) $group['num_members'] : -1; |
||
829 | |||
830 | array_multisort($sort_array, $sort_ascending ? SORT_ASC : SORT_DESC, SORT_REGULAR, $groups); |
||
831 | } |
||
832 | |||
833 | return $groups; |
||
834 | } |
||
835 | |||
836 | /** |
||
837 | * Retrieves a list of membergroups with the given permissions. |
||
838 | * |
||
839 | * @param array $group_permissions |
||
840 | * @param array $board_permissions |
||
841 | * @param int $profile_id |
||
842 | * |
||
843 | * @return array An array containing two arrays - 'allowed', which has which groups are allowed to do it and 'denied' which has the groups that are denied |
||
844 | */ |
||
845 | function getGroupsWithPermissions(array $group_permissions = array(), array $board_permissions = array(), $profile_id = 1) |
||
846 | { |
||
847 | global $smcFunc; |
||
848 | |||
849 | $member_groups = array(); |
||
850 | if (!empty($group_permissions)) |
||
851 | { |
||
852 | foreach ($group_permissions as $group_permission) |
||
853 | // Admins are allowed to do anything. |
||
854 | $member_groups[$group_permission] = array( |
||
855 | 'allowed' => array(1), |
||
856 | 'denied' => array(), |
||
857 | ); |
||
858 | |||
859 | $request = $smcFunc['db_query']('', ' |
||
860 | SELECT id_group, permission, add_deny |
||
861 | FROM {db_prefix}permissions |
||
862 | WHERE permission IN ({array_string:group_permissions})', |
||
863 | array( |
||
864 | 'group_permissions' => $group_permissions, |
||
865 | ) |
||
866 | ); |
||
867 | while (list ($id_group, $permission, $add_deny) = $smcFunc['db_fetch_row']($request)) |
||
868 | $member_groups[$permission][$add_deny === '1' ? 'allowed' : 'denied'][] = $id_group; |
||
869 | $smcFunc['db_free_result']($request); |
||
870 | } |
||
871 | |||
872 | if (!empty($board_permissions)) |
||
873 | { |
||
874 | foreach ($board_permissions as $board_permission) |
||
875 | $member_groups[$board_permission] = array( |
||
876 | 'allowed' => array(1), |
||
877 | 'denied' => array(), |
||
878 | ); |
||
879 | |||
880 | $request = $smcFunc['db_query']('', ' |
||
881 | SELECT id_group, permission, add_deny |
||
882 | FROM {db_prefix}board_permissions |
||
883 | WHERE permission IN ({array_string:board_permissions}) |
||
884 | AND id_profile = {int:profile_id}', |
||
885 | array( |
||
886 | 'profile_id' => $profile_id, |
||
887 | 'board_permissions' => $board_permissions, |
||
888 | ) |
||
889 | ); |
||
890 | while (list ($id_group, $permission, $add_deny) = $smcFunc['db_fetch_row']($request)) |
||
891 | $member_groups[$permission][$add_deny === '1' ? 'allowed' : 'denied'][] = $id_group; |
||
892 | $smcFunc['db_free_result']($request); |
||
893 | } |
||
894 | |||
895 | // Denied is never allowed. |
||
896 | foreach ($member_groups as $permission => $groups) |
||
897 | $member_groups[$permission]['allowed'] = array_diff($member_groups[$permission]['allowed'], $member_groups[$permission]['denied']); |
||
898 | |||
899 | return $member_groups; |
||
900 | } |
||
901 | |||
902 | ?> |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths