removeMembersFromGroups()   F
last analyzed

Complexity

Conditions 30
Paths 4788

Size

Total Lines 201
Code Lines 95

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 30
eloc 95
c 0
b 0
f 0
nop 4
dl 0
loc 201
rs 0
nc 4788

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
Bug introduced by
The type The was not found. Maybe you did not declare it correctly or list all dependencies?

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:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
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);
0 ignored issues
show
Bug introduced by
$sort_ascending ? SORT_ASC : SORT_DESC cannot be passed to array_multisort() as the parameter $rest expects a reference. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

830
		array_multisort($sort_array, /** @scrutinizer ignore-type */ $sort_ascending ? SORT_ASC : SORT_DESC, SORT_REGULAR, $groups);
Loading history...
Bug introduced by
SORT_REGULAR cannot be passed to array_multisort() as the parameter $rest expects a reference. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

830
		array_multisort($sort_array, $sort_ascending ? SORT_ASC : SORT_DESC, /** @scrutinizer ignore-type */ SORT_REGULAR, $groups);
Loading history...
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
?>