Failed Conditions
Branch release-2.1 (4e22cf)
by Rick
06:39
created

Groups.php ➔ GroupRequests()   D

Complexity

Conditions 20
Paths 128

Size

Total Lines 235
Code Lines 135

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 20
eloc 135
nc 128
nop 0
dl 0
loc 235
rs 4.4507
c 0
b 0
f 0

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 currently just shows group info, and allows certain priviledged members to add/remove members.
5
 *
6
 * Simple Machines Forum (SMF)
7
 *
8
 * @package SMF
9
 * @author Simple Machines http://www.simplemachines.org
10
 * @copyright 2017 Simple Machines and individual contributors
11
 * @license http://www.simplemachines.org/about/smf/license.php BSD
12
 *
13
 * @version 2.1 Beta 4
14
 */
15
16
if (!defined('SMF'))
17
	die('No direct access...');
18
19
/**
20
 * Entry point function, permission checks, admin bars, etc.
21
 * It allows moderators and users to access the group showing functions.
22
 * It handles permission checks, and puts the moderation bar on as required.
23
 */
24
function Groups()
25
{
26
	global $context, $txt, $scripturl, $sourcedir, $user_info;
27
28
	// The sub-actions that we can do. Format "Function Name, Mod Bar Index if appropriate".
29
	$subActions = array(
30
		'index' => array('GroupList', 'view_groups'),
31
		'members' => array('MembergroupMembers', 'view_groups'),
32
		'requests' => array('GroupRequests', 'group_requests'),
33
	);
34
35
	// Default to sub action 'index'.
36
	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'index';
37
38
	// Get the template stuff up and running.
39
	loadLanguage('ManageMembers');
40
	loadLanguage('ModerationCenter');
41
	loadTemplate('ManageMembergroups');
42
43
	// If we can see the moderation center, and this has a mod bar entry, add the mod center bar.
44
	if (allowedTo('access_mod_center') || $user_info['mod_cache']['bq'] != '0=1' || $user_info['mod_cache']['gq'] != '0=1' || allowedTo('manage_membergroups'))
45
	{
46
		require_once($sourcedir . '/ModerationCenter.php');
47
		$_GET['area'] = $_REQUEST['sa'] == 'requests' ? 'groups' : 'viewgroups';
48
		ModerationMain(true);
49
	}
50
	// Otherwise add something to the link tree, for normal people.
51
	else
52
	{
53
		isAllowedTo('view_mlist');
54
55
		$context['linktree'][] = array(
56
			'url' => $scripturl . '?action=groups',
57
			'name' => $txt['groups'],
58
		);
59
	}
60
61
	// CRUD $subActions as needed.
62
	call_integration_hook('integrate_manage_groups', array(&$subActions));
63
64
	// Call the actual function.
65
	call_helper($subActions[$_REQUEST['sa']][0]);
66
}
67
68
/**
69
 * This very simply lists the groups, nothing snazy.
70
 */
71
function GroupList()
72
{
73
	global $txt, $context, $sourcedir, $scripturl;
74
75
	$context['page_title'] = $txt['viewing_groups'];
76
77
	// Making a list is not hard with this beauty.
78
	require_once($sourcedir . '/Subs-List.php');
79
80
	// Use the standard templates for showing this.
81
	$listOptions = array(
82
		'id' => 'group_lists',
83
		'title' => $context['page_title'],
84
		'base_href' => $scripturl . '?action=moderate;area=viewgroups;sa=view',
85
		'default_sort_col' => 'group',
86
		'get_items' => array(
87
			'file' => $sourcedir . '/Subs-Membergroups.php',
88
			'function' => 'list_getMembergroups',
89
			'params' => array(
90
				'regular',
91
			),
92
		),
93
		'columns' => array(
94
			'group' => array(
95
				'header' => array(
96
					'value' => $txt['name'],
97
				),
98
				'data' => array(
99
					'function' => function($rowData) use ($scripturl)
100
					{
101
						// Since the moderator group has no explicit members, no link is needed.
102
						if ($rowData['id_group'] == 3)
103
							$group_name = $rowData['group_name'];
104
						else
105
						{
106
							$color_style = empty($rowData['online_color']) ? '' : sprintf(' style="color: %1$s;"', $rowData['online_color']);
107
108 View Code Duplication
							if (allowedTo('manage_membergroups'))
109
							{
110
								$group_name = sprintf('<a href="%1$s?action=admin;area=membergroups;sa=members;group=%2$d"%3$s>%4$s</a>', $scripturl, $rowData['id_group'], $color_style, $rowData['group_name']);
111
							}
112
							else
113
							{
114
								$group_name = sprintf('<a href="%1$s?action=groups;sa=members;group=%2$d"%3$s>%4$s</a>', $scripturl, $rowData['id_group'], $color_style, $rowData['group_name']);
115
							}
116
						}
117
118
						// Add a help option for moderator and administrator.
119 View Code Duplication
						if ($rowData['id_group'] == 1)
120
							$group_name .= sprintf(' (<a href="%1$s?action=helpadmin;help=membergroup_administrator" onclick="return reqOverlayDiv(this.href);">?</a>)', $scripturl);
121
						elseif ($rowData['id_group'] == 3)
122
							$group_name .= sprintf(' (<a href="%1$s?action=helpadmin;help=membergroup_moderator" onclick="return reqOverlayDiv(this.href);">?</a>)', $scripturl);
123
124
						return $group_name;
125
					},
126
				),
127
				'sort' => array(
128
					'default' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, mg.group_name',
129
					'reverse' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, mg.group_name DESC',
130
				),
131
			),
132
			'icons' => array(
133
				'header' => array(
134
					'value' => $txt['membergroups_icons'],
135
				),
136
				'data' => array(
137
					'db' => 'icons',
138
				),
139
				'sort' => array(
140
					'default' => 'mg.icons',
141
					'reverse' => 'mg.icons DESC',
142
				)
143
			),
144
			'moderators' => array(
145
				'header' => array(
146
					'value' => $txt['moderators'],
147
				),
148
				'data' => array(
149
					'function' => function($group) use ($txt)
150
					{
151
						return empty($group['moderators']) ? '<em>' . $txt['membergroups_new_copy_none'] . '</em>' : implode(', ', $group['moderators']);
152
					},
153
				),
154
			),
155
			'members' => array(
156
				'header' => array(
157
					'value' => $txt['membergroups_members_top'],
158
				),
159
				'data' => array(
160 View Code Duplication
					'function' => function($rowData) use ($txt)
161
					{
162
						// No explicit members for the moderator group.
163
						return $rowData['id_group'] == 3 ? $txt['membergroups_guests_na'] : comma_format($rowData['num_members']);
164
					},
165
					'class' => 'centercol',
166
				),
167
				'sort' => array(
168
					'default' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, 1',
169
					'reverse' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, 1 DESC',
170
				),
171
			),
172
		),
173
	);
174
175
	// Create the request list.
176
	createList($listOptions);
177
178
	$context['sub_template'] = 'show_list';
179
	$context['default_list'] = 'group_lists';
180
}
181
182
/**
183
 * Display members of a group, and allow adding of members to a group. Silly function name though ;)
184
 * It can be called from ManageMembergroups if it needs templating within the admin environment.
185
 * It shows a list of members that are part of a given membergroup.
186
 * It is called by ?action=moderate;area=viewgroups;sa=members;group=x
187
 * It requires the manage_membergroups permission.
188
 * It allows to add and remove members from the selected membergroup.
189
 * It allows sorting on several columns.
190
 * It redirects to itself.
191
 * @uses ManageMembergroups template, group_members sub template.
192
 * @todo: use createList
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
193
 */
194
function MembergroupMembers()
195
{
196
	global $txt, $scripturl, $context, $modSettings, $sourcedir, $user_info, $settings, $smcFunc;
197
198
	$_REQUEST['group'] = isset($_REQUEST['group']) ? (int) $_REQUEST['group'] : 0;
199
200
	// No browsing of guests, membergroup 0 or moderators.
201
	if (in_array($_REQUEST['group'], array(-1, 0, 3)))
202
		fatal_lang_error('membergroup_does_not_exist', false);
203
204
	// Load up the group details.
205
	$request = $smcFunc['db_query']('', '
206
		SELECT id_group AS id, group_name AS name, CASE WHEN min_posts = {int:min_posts} THEN 1 ELSE 0 END AS assignable, hidden, online_color,
207
			icons, description, CASE WHEN min_posts != {int:min_posts} THEN 1 ELSE 0 END AS is_post_group, group_type
208
		FROM {db_prefix}membergroups
209
		WHERE id_group = {int:id_group}
210
		LIMIT 1',
211
		array(
212
			'min_posts' => -1,
213
			'id_group' => $_REQUEST['group'],
214
		)
215
	);
216
	// Doesn't exist?
217
	if ($smcFunc['db_num_rows']($request) == 0)
218
		fatal_lang_error('membergroup_does_not_exist', false);
219
	$context['group'] = $smcFunc['db_fetch_assoc']($request);
220
	$smcFunc['db_free_result']($request);
221
222
	// Fix the membergroup icons.
223
	$context['group']['icons'] = explode('#', $context['group']['icons']);
224
	$context['group']['icons'] = !empty($context['group']['icons'][0]) && !empty($context['group']['icons'][1]) ? str_repeat('<img src="' . $settings['images_url'] . '/membericons/' . $context['group']['icons'][1] . '" alt="*">', $context['group']['icons'][0]) : '';
225
	$context['group']['can_moderate'] = allowedTo('manage_membergroups') && (allowedTo('admin_forum') || $context['group']['group_type'] != 1);
226
227
	$context['linktree'][] = array(
228
		'url' => $scripturl . '?action=groups;sa=members;group=' . $context['group']['id'],
229
		'name' => $context['group']['name'],
230
	);
231
	$context['can_send_email'] = allowedTo('moderate_forum');
232
233
	// Load all the group moderators, for fun.
234
	$request = $smcFunc['db_query']('', '
235
		SELECT mem.id_member, mem.real_name
236
		FROM {db_prefix}group_moderators AS mods
237
			INNER JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member)
238
		WHERE mods.id_group = {int:id_group}',
239
		array(
240
			'id_group' => $_REQUEST['group'],
241
		)
242
	);
243
	$context['group']['moderators'] = array();
244
	while ($row = $smcFunc['db_fetch_assoc']($request))
245
	{
246
		$context['group']['moderators'][] = array(
247
			'id' => $row['id_member'],
248
			'name' => $row['real_name']
249
		);
250
251
		if ($user_info['id'] == $row['id_member'] && $context['group']['group_type'] != 1)
252
			$context['group']['can_moderate'] = true;
253
	}
254
	$smcFunc['db_free_result']($request);
255
256
	// If this group is hidden then it can only "exists" if the user can moderate it!
257
	if ($context['group']['hidden'] && !$context['group']['can_moderate'])
258
		fatal_lang_error('membergroup_does_not_exist', false);
259
260
	// You can only assign membership if you are the moderator and/or can manage groups!
261
	if (!$context['group']['can_moderate'])
262
		$context['group']['assignable'] = 0;
263
	// Non-admins cannot assign admins.
264
	elseif ($context['group']['id'] == 1 && !allowedTo('admin_forum'))
265
		$context['group']['assignable'] = 0;
266
267
	// Removing member from group?
268
	if (isset($_POST['remove']) && !empty($_REQUEST['rem']) && is_array($_REQUEST['rem']) && $context['group']['assignable'])
269
	{
270
		checkSession();
271
		validateToken('mod-mgm');
272
273
		// Make sure we're dealing with integers only.
274
		foreach ($_REQUEST['rem'] as $key => $group)
275
			$_REQUEST['rem'][$key] = (int) $group;
276
277
		require_once($sourcedir . '/Subs-Membergroups.php');
278
		removeMembersFromGroups($_REQUEST['rem'], $_REQUEST['group'], true);
279
	}
280
	// Must be adding new members to the group...
281
	elseif (isset($_REQUEST['add']) && (!empty($_REQUEST['toAdd']) || !empty($_REQUEST['member_add'])) && $context['group']['assignable'])
282
	{
283
		checkSession();
284
		validateToken('mod-mgm');
285
286
		$member_query = array();
287
		$member_parameters = array();
288
289
		// Get all the members to be added... taking into account names can be quoted ;)
290
		$_REQUEST['toAdd'] = strtr($smcFunc['htmlspecialchars']($_REQUEST['toAdd'], ENT_QUOTES), array('&quot;' => '"'));
291
		preg_match_all('~"([^"]+)"~', $_REQUEST['toAdd'], $matches);
292
		$member_names = array_unique(array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $_REQUEST['toAdd']))));
293
294
		foreach ($member_names as $index => $member_name)
295
		{
296
			$member_names[$index] = trim($smcFunc['strtolower']($member_names[$index]));
297
298
			if (strlen($member_names[$index]) == 0)
299
				unset($member_names[$index]);
300
		}
301
302
		// Any passed by ID?
303
		$member_ids = array();
304
		if (!empty($_REQUEST['member_add']))
305
			foreach ($_REQUEST['member_add'] as $id)
0 ignored issues
show
Bug introduced by
The expression $_REQUEST['member_add'] of type integer|array|string is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
306
				if ($id > 0)
307
					$member_ids[] = (int) $id;
308
309
		// Construct the query pelements.
310
		if (!empty($member_ids))
311
		{
312
			$member_query[] = 'id_member IN ({array_int:member_ids})';
313
			$member_parameters['member_ids'] = $member_ids;
314
		}
315
		if (!empty($member_names))
316
		{
317
			$member_query[] = 'LOWER(member_name) IN ({array_string:member_names})';
318
			$member_query[] = 'LOWER(real_name) IN ({array_string:member_names})';
319
			$member_parameters['member_names'] = $member_names;
320
		}
321
322
		$members = array();
323
		if (!empty($member_query))
324
		{
325
			$request = $smcFunc['db_query']('', '
326
				SELECT id_member
327
				FROM {db_prefix}members
328
				WHERE (' . implode(' OR ', $member_query) . ')
329
					AND id_group != {int:id_group}
330
					AND FIND_IN_SET({int:id_group}, additional_groups) = 0',
331
				array_merge($member_parameters, array(
332
					'id_group' => $_REQUEST['group'],
333
				))
334
			);
335
			while ($row = $smcFunc['db_fetch_assoc']($request))
336
				$members[] = $row['id_member'];
337
			$smcFunc['db_free_result']($request);
338
		}
339
340
		// @todo Add $_POST['additional'] to templates!
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
341
342
		// Do the updates...
343
		if (!empty($members))
344
		{
345
			require_once($sourcedir . '/Subs-Membergroups.php');
346
			addMembersToGroup($members, $_REQUEST['group'], isset($_POST['additional']) || $context['group']['hidden'] ? 'only_additional' : 'auto', true);
347
		}
348
	}
349
350
	// Sort out the sorting!
351
	$sort_methods = array(
352
		'name' => 'real_name',
353
		'email' => 'email_address',
354
		'active' => 'last_login',
355
		'registered' => 'date_registered',
356
		'posts' => 'posts',
357
	);
358
359
	// They didn't pick one, default to by name..
360
	if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']]))
361
	{
362
		$context['sort_by'] = 'name';
363
		$querySort = 'real_name';
364
	}
365
	// Otherwise default to ascending.
366
	else
367
	{
368
		$context['sort_by'] = $_REQUEST['sort'];
369
		$querySort = $sort_methods[$_REQUEST['sort']];
370
	}
371
372
	$context['sort_direction'] = isset($_REQUEST['desc']) ? 'down' : 'up';
373
374
	// The where on the query is interesting. Non-moderators should only see people who are in this group as primary.
375
	if ($context['group']['can_moderate'])
376
		$where = $context['group']['is_post_group'] ? 'id_post_group = {int:group}' : 'id_group = {int:group} OR FIND_IN_SET({int:group}, additional_groups) != 0';
377
	else
378
		$where = $context['group']['is_post_group'] ? 'id_post_group = {int:group}' : 'id_group = {int:group}';
379
380
	// Count members of the group.
381
	$request = $smcFunc['db_query']('', '
382
		SELECT COUNT(*)
383
		FROM {db_prefix}members
384
		WHERE ' . $where,
385
		array(
386
			'group' => $_REQUEST['group'],
387
		)
388
	);
389
	list ($context['total_members']) = $smcFunc['db_fetch_row']($request);
390
	$smcFunc['db_free_result']($request);
391
	$context['total_members'] = comma_format($context['total_members']);
392
393
	// Create the page index.
394
	$context['page_index'] = constructPageIndex($scripturl . '?action=' . ($context['group']['can_moderate'] ? 'moderate;area=viewgroups' : 'groups') . ';sa=members;group=' . $_REQUEST['group'] . ';sort=' . $context['sort_by'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $context['total_members'], $modSettings['defaultMaxMembers']);
395
	$context['start'] = $_REQUEST['start'];
396
	$context['can_moderate_forum'] = allowedTo('moderate_forum');
397
398
	// Load up all members of this group.
399
	$request = $smcFunc['db_query']('', '
400
		SELECT id_member, member_name, real_name, email_address, member_ip, date_registered, last_login,
401
			posts, is_activated, real_name
402
		FROM {db_prefix}members
403
		WHERE ' . $where . '
404
		ORDER BY ' . $querySort . ' ' . ($context['sort_direction'] == 'down' ? 'DESC' : 'ASC') . '
405
		LIMIT {int:start}, {int:max}',
406
		array(
407
			'group' => $_REQUEST['group'],
408
			'start' => $context['start'],
409
			'max' => $modSettings['defaultMaxMembers'],
410
		)
411
	);
412
	$context['members'] = array();
413
	while ($row = $smcFunc['db_fetch_assoc']($request))
414
	{
415
		$row['member_ip'] = inet_dtop($row['member_ip']);
416
		$last_online = empty($row['last_login']) ? $txt['never'] : timeformat($row['last_login']);
417
418
		// Italicize the online note if they aren't activated.
419
		if ($row['is_activated'] % 10 != 1)
420
			$last_online = '<em title="' . $txt['not_activated'] . '">' . $last_online . '</em>';
421
422
		$context['members'][] = array(
423
			'id' => $row['id_member'],
424
			'name' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>',
425
			'email' => $row['email_address'],
426
			'ip' => '<a href="' . $scripturl . '?action=trackip;searchip=' . $row['member_ip'] . '">' . $row['member_ip'] . '</a>',
427
			'registered' => timeformat($row['date_registered']),
428
			'last_online' => $last_online,
429
			'posts' => comma_format($row['posts']),
430
			'is_activated' => $row['is_activated'] % 10 == 1,
431
		);
432
	}
433
	$smcFunc['db_free_result']($request);
434
435
	// Select the template.
436
	$context['sub_template'] = 'group_members';
437
	$context['page_title'] = $txt['membergroups_members_title'] . ': ' . $context['group']['name'];
438
	createToken('mod-mgm');
439
440
	if ($context['group']['assignable'])
441
		loadJavaScriptFile('suggest.js', array('defer' => false), 'smf_suggest');
442
}
443
444
/**
445
 * Show and manage all group requests.
446
 */
447
function GroupRequests()
448
{
449
	global $txt, $context, $scripturl, $user_info, $sourcedir, $smcFunc, $modSettings;
450
451
	// Set up the template stuff...
452
	$context['page_title'] = $txt['mc_group_requests'];
453
	$context['sub_template'] = 'show_list';
454
455
	// Verify we can be here.
456
	if ($user_info['mod_cache']['gq'] == '0=1')
457
		isAllowedTo('manage_membergroups');
458
459
	// Normally, we act normally...
460
	$where = ($user_info['mod_cache']['gq'] == '1=1' || $user_info['mod_cache']['gq'] == '0=1' ? $user_info['mod_cache']['gq'] : 'lgr.' . $user_info['mod_cache']['gq']);
461
462
	if (isset($_GET['closed']))
463
		$where .= ' AND lgr.status != {int:status_open}';
464
	else
465
		$where .= ' AND lgr.status = {int:status_open}';
466
467
	$where_parameters = array(
468
		'status_open' => 0,
469
	);
470
471
	// We've submitted?
472
	if (isset($_POST[$context['session_var']]) && !empty($_POST['groupr']) && !empty($_POST['req_action']))
473
	{
474
		checkSession();
475
		validateToken('mod-gr');
476
477
		// Clean the values.
478
		foreach ($_POST['groupr'] as $k => $request)
479
			$_POST['groupr'][$k] = (int) $request;
480
481
		$log_changes = array();
482
483
		// If we are giving a reason (And why shouldn't we?), then we don't actually do much.
484
		if ($_POST['req_action'] == 'reason')
485
		{
486
			// Different sub template...
487
			$context['sub_template'] = 'group_request_reason';
488
			// And a limitation. We don't care that the page number bit makes no sense, as we don't need it!
489
			$where .= ' AND lgr.id_request IN ({array_int:request_ids})';
490
			$where_parameters['request_ids'] = $_POST['groupr'];
491
492
			$context['group_requests'] = list_getGroupRequests(0, $modSettings['defaultMaxListItems'], 'lgr.id_request', $where, $where_parameters);
0 ignored issues
show
Documentation introduced by
$where_parameters is of type array<string,?,{"request_ids":"?"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
493
494
			// Need to make another token for this.
495
			createToken('mod-gr');
496
497
			// Let obExit etc sort things out.
498
			obExit();
499
		}
500
		// Otherwise we do something!
501
		else
502
		{
503
			$request = $smcFunc['db_query']('', '
504
				SELECT lgr.id_request
505
				FROM {db_prefix}log_group_requests AS lgr
506
				WHERE ' . $where . '
507
					AND lgr.id_request IN ({array_int:request_list})',
508
				array(
509
					'request_list' => $_POST['groupr'],
510
					'status_open' => 0,
511
				)
512
			);
513
			$request_list = array();
514
			while ($row = $smcFunc['db_fetch_assoc']($request))
515
			{
516
				if (!isset($log_changes[$row['id_request']]))
517
					$log_changes[$row['id_request']] = array(
518
						'id_request' => $row['id_request'],
519
						'status' => $_POST['req_action'] == 'approve' ? 1 : 2, // 1 = approved, 2 = rejected
520
						'id_member_acted' => $user_info['id'],
521
						'member_name_acted' => $user_info['name'],
522
						'time_acted' => time(),
523
						'act_reason' => $_POST['req_action'] != 'approve' && !empty($_POST['groupreason']) && !empty($_POST['groupreason'][$row['id_request']]) ? $smcFunc['htmlspecialchars']($_POST['groupreason'][$row['id_request']], ENT_QUOTES) : '',
524
					);
525
				$request_list[] = $row['id_request'];
526
			}
527
			$smcFunc['db_free_result']($request);
528
529
			// Add a background task to handle notifying people of this request
530
			$data = $smcFunc['json_encode'](array('member_id' => $user_info['id'], 'member_ip' => $user_info['ip'], 'request_list' => $request_list, 'status' => $_POST['req_action'], 'reason' => isset($_POST['groupreason']) ? $_POST['groupreason'] : '', 'time' => time()));
531
			$smcFunc['db_insert']('insert', '{db_prefix}background_tasks',
532
				array('task_file' => 'string-255', 'task_class' => 'string-255', 'task_data' => 'string', 'claimed_time' => 'int'),
533
				array('$sourcedir/tasks/GroupAct-Notify.php', 'GroupAct_Notify_Background', $data, 0), array()
534
			);
535
536
			// Some changes to log?
537
			if (!empty($log_changes))
538
			{
539
				foreach ($log_changes as $id_request => $details)
540
				{
541
					$smcFunc['db_query']('', '
542
						UPDATE {db_prefix}log_group_requests
543
						SET status = {int:status},
544
							id_member_acted = {int:id_member_acted},
545
							member_name_acted = {string:member_name_acted},
546
							time_acted = {int:time_acted},
547
							act_reason = {string:act_reason}
548
						WHERE id_request = {int:id_request}',
549
						$details
550
					);
551
				}
552
			}
553
		}
554
	}
555
556
	// We're going to want this for making our list.
557
	require_once($sourcedir . '/Subs-List.php');
558
559
	// This is all the information required for a group listing.
560
	$listOptions = array(
561
		'id' => 'group_request_list',
562
		'width' => '100%',
563
		'items_per_page' => $modSettings['defaultMaxListItems'],
564
		'no_items_label' => $txt['mc_groupr_none_found'],
565
		'base_href' => $scripturl . '?action=groups;sa=requests',
566
		'default_sort_col' => 'member',
567
		'get_items' => array(
568
			'function' => 'list_getGroupRequests',
569
			'params' => array(
570
				$where,
571
				$where_parameters,
572
			),
573
		),
574
		'get_count' => array(
575
			'function' => 'list_getGroupRequestCount',
576
			'params' => array(
577
				$where,
578
				$where_parameters,
579
			),
580
		),
581
		'columns' => array(
582
			'member' => array(
583
				'header' => array(
584
					'value' => $txt['mc_groupr_member'],
585
				),
586
				'data' => array(
587
					'db' => 'member_link',
588
				),
589
				'sort' => array(
590
					'default' => 'mem.member_name',
591
					'reverse' => 'mem.member_name DESC',
592
				),
593
			),
594
			'group' => array(
595
				'header' => array(
596
					'value' => $txt['mc_groupr_group'],
597
				),
598
				'data' => array(
599
					'db' => 'group_link',
600
				),
601
				'sort' => array(
602
					'default' => 'mg.group_name',
603
					'reverse' => 'mg.group_name DESC',
604
				),
605
			),
606
			'reason' => array(
607
				'header' => array(
608
					'value' => $txt['mc_groupr_reason'],
609
				),
610
				'data' => array(
611
					'db' => 'reason',
612
				),
613
			),
614
			'date' => array(
615
				'header' => array(
616
					'value' => $txt['date'],
617
					'style' => 'width: 18%; white-space:nowrap;',
618
				),
619
				'data' => array(
620
					'db' => 'time_submitted',
621
				),
622
			),
623
			'action' => array(
624
				'header' => array(
625
					'value' => '<input type="checkbox" class="input_check" onclick="invertAll(this, this.form);">',
626
					'style' => 'width: 4%;',
627
					'class' => 'centercol',
628
				),
629
				'data' => array(
630
					'sprintf' => array(
631
						'format' => '<input type="checkbox" name="groupr[]" value="%1$d" class="input_check">',
632
						'params' => array(
633
							'id' => false,
634
						),
635
					),
636
					'class' => 'centercol',
637
				),
638
			),
639
		),
640
		'form' => array(
641
			'href' => $scripturl . '?action=groups;sa=requests',
642
			'include_sort' => true,
643
			'include_start' => true,
644
			'hidden_fields' => array(
645
				$context['session_var'] => $context['session_id'],
646
			),
647
			'token' => 'mod-gr',
648
		),
649
		'additional_rows' => array(
650
			array(
651
				'position' => 'bottom_of_list',
652
				'value' => '
653
					<select name="req_action" onchange="if (this.value != 0 &amp;&amp; (this.value == \'reason\' || confirm(\'' . $txt['mc_groupr_warning'] . '\'))) this.form.submit();">
654
						<option value="0">' . $txt['with_selected'] . ':</option>
655
						<option value="0" disabled>---------------------</option>
656
						<option value="approve">' . $txt['mc_groupr_approve'] . '</option>
657
						<option value="reject">' . $txt['mc_groupr_reject'] . '</option>
658
						<option value="reason">' . $txt['mc_groupr_reject_w_reason'] . '</option>
659
					</select>
660
					<input type="submit" name="go" value="' . $txt['go'] . '" onclick="var sel = document.getElementById(\'req_action\'); if (sel.value != 0 &amp;&amp; sel.value != \'reason\' &amp;&amp; !confirm(\'' . $txt['mc_groupr_warning'] . '\')) return false;" class="button_submit">',
661
				'class' => 'floatright',
662
			),
663
		),
664
	);
665
666
	if (isset($_GET['closed']))
667
	{
668
		// Closed requests don't require interaction.
669
		unset($listOptions['columns']['action'], $listOptions['form'], $listOptions['additional_rows'][0]);
670
		$listOptions['base_href'] .= 'closed';
671
	}
672
673
	// Create the request list.
674
	createToken('mod-gr');
675
	createList($listOptions);
676
677
	$context['default_list'] = 'group_request_list';
678
	$context[$context['moderation_menu_name']]['tab_data'] = array(
679
		'title' => $txt['mc_group_requests'],
680
	);
681
}
682
683
/**
684
 * Callback function for createList().
685
 *
686
 * @param string $where The WHERE clause for the query
687
 * @param array $where_parameters The parameters for the WHERE clause
688
 * @return int The number of group requests
689
 */
690 View Code Duplication
function list_getGroupRequestCount($where, $where_parameters)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
691
{
692
	global $smcFunc;
693
694
	$request = $smcFunc['db_query']('', '
695
		SELECT COUNT(*)
696
		FROM {db_prefix}log_group_requests AS lgr
697
		WHERE ' . $where,
698
		array_merge($where_parameters, array(
699
		))
700
	);
701
	list ($totalRequests) = $smcFunc['db_fetch_row']($request);
702
	$smcFunc['db_free_result']($request);
703
704
	return $totalRequests;
705
}
706
707
/**
708
 * Callback function for createList()
709
 *
710
 * @param int $start The result to start with
711
 * @param int $items_per_page The number of items per page
712
 * @param string $sort An SQL sort expression (column/direction)
713
 * @param string $where Data for the WHERE clause
714
 * @param string $where_parameters Parameter values to be inserted into the WHERE clause
715
 * @return array An array of group requests
716
 * Each group request has:
717
 * 		'id'
718
 * 		'member_link'
719
 * 		'group_link'
720
 * 		'reason'
721
 * 		'time_submitted'
722
 */
723
function list_getGroupRequests($start, $items_per_page, $sort, $where, $where_parameters)
724
{
725
	global $smcFunc, $scripturl, $txt;
726
727
	$request = $smcFunc['db_query']('', '
728
		SELECT
729
			lgr.id_request, lgr.id_member, lgr.id_group, lgr.time_applied, lgr.reason,
730
			lgr.status, lgr.id_member_acted, lgr.member_name_acted, lgr.time_acted, lgr.act_reason,
731
			mem.member_name, mg.group_name, mg.online_color, mem.real_name
732
		FROM {db_prefix}log_group_requests AS lgr
733
			INNER JOIN {db_prefix}members AS mem ON (mem.id_member = lgr.id_member)
734
			INNER JOIN {db_prefix}membergroups AS mg ON (mg.id_group = lgr.id_group)
735
		WHERE ' . $where . '
736
		ORDER BY {raw:sort}
737
		LIMIT {int:start}, {int:max}',
738
		array_merge($where_parameters, array(
739
			'sort' => $sort,
740
			'start' => $start,
741
			'max' => $items_per_page,
742
		))
743
	);
744
	$group_requests = array();
745
	while ($row = $smcFunc['db_fetch_assoc']($request))
746
	{
747
		if (empty($row['reason']))
748
			$reason = '<em>(' . $txt['mc_groupr_no_reason'] . ')</em>';
749
		else
750
			$reason = censorText($row['reason']);
751
752
		if (isset($_GET['closed']))
753
		{
754
			if ($row['status'] == 1)
755
				$reason .= '<br><br><strong>' . $txt['mc_groupr_approved'] . '</strong>';
756
			elseif ($row['status'] == 2)
757
				$reason .= '<br><br><strong>' . $txt['mc_groupr_rejected'] . '</strong>';
758
759
				$reason .= ' (' . timeformat($row['time_acted']) . ')';
760
			if (!empty($row['act_reason']))
761
				$reason .= '<br><br>' . censorText($row['act_reason']);
762
		}
763
764
		$group_requests[] = array(
765
			'id' => $row['id_request'],
766
			'member_link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>',
767
			'group_link' => '<span style="color: ' . $row['online_color'] . '">' . $row['group_name'] . '</span>',
768
			'reason' => $reason,
769
			'time_submitted' => timeformat($row['time_applied']),
770
		);
771
	}
772
	$smcFunc['db_free_result']($request);
773
774
	return $group_requests;
775
}
776
777
?>