Groups::action_requests()   F
last analyzed

Complexity

Conditions 20
Paths 40

Size

Total Lines 241
Code Lines 131

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 420

Importance

Changes 0
Metric Value
cc 20
eloc 131
nc 40
nop 0
dl 0
loc 241
ccs 0
cts 81
cp 0
crap 420
rs 3.3333
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 privileged
5
 * members to add/remove members.
6
 *
7
 * @package   ElkArte Forum
8
 * @copyright ElkArte Forum contributors
9
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
10
 *
11
 * This file contains code covered by:
12
 * copyright: 2011 Simple Machines (http://www.simplemachines.org)
13
 *
14
 * @version 2.0 dev
15
 *
16
 */
17
18
namespace ElkArte\Controller;
19
20
use ElkArte\AbstractController;
21
use ElkArte\Action;
22
use ElkArte\EventManager;
23
use ElkArte\Exceptions\Exception;
24
use ElkArte\Helper\Util;
25
use ElkArte\Languages\Txt;
26
use ElkArte\User;
27
28
/**
29
 * Shows group access and allows for add/remove group members
30
 */
31
class Groups extends AbstractController
32
{
33
	/**
34
	 * Set up templates and pre-requisites for any request processed by this class.
35
	 *
36
	 * - Called automagically before any action_() call.
37
	 * - It handles permission checks, and puts the moderation bar on as required.
38 2
	 */
39
	public function pre_dispatch()
40 2
	{
41
		global $context, $txt;
42
43 2
		// Get the template stuff up and running.
44 2
		Txt::load('ManageMembers');
45 2
		Txt::load('ModerationCenter');
46
		theme()->getTemplates()->load('ManageMembergroups');
47
48 2
		// If we can see the moderation center, and this has a mod bar entry, add the mod center bar.
49
		if (User::$info->canMod(true) || allowedTo('manage_membergroups'))
0 ignored issues
show
Bug introduced by
The method canMod() does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

49
		if (User::$info->/** @scrutinizer ignore-call */ canMod(true) || allowedTo('manage_membergroups'))
Loading history...
50 2
		{
51 2
			$this->_req->query->area = $this->_req->getQuery('sa') === 'requests' ? 'groups' : 'viewgroups';
52 2
			$controller = new ModerationCenter(new EventManager());
53 2
			$controller->setUser(User::$info);
54 2
			$controller->pre_dispatch();
55
			$controller->prepareModcenter();
56
		}
57
		// Otherwise add something to the link tree, for normal people.
58
		else
59
		{
60
			isAllowedTo('view_mlist');
61
62
			$context['breadcrumbs'][] = [
63
				'url' => getUrl('group', ['action' => 'groups']),
64
				'name' => $txt['groups'],
65
			];
66 2
		}
67
	}
68
69
	/**
70
	 * Entry point to groups.
71
	 * It allows moderators and users to access the group showing functions.
72
	 *
73
	 * @see AbstractController::action_index
74 2
	 */
75
	public function action_index()
76 2
	{
77
		global $context;
78
79
		// Little short on the list here
80 2
		$subActions = array(
81 2
			'list' => array($this, 'action_list', 'permission' => 'view_mlist'),
82 2
			'members' => array($this, 'action_members', 'permission' => 'view_mlist'),
83
			'requests' => array($this, 'action_requests'),
84
		);
85
86 2
		// I don't think we know what to do... throw dies?
87 2
		$action = new Action('groups');
88 2
		$subAction = $action->initialize($subActions, 'list');
89 2
		$context['sub_action'] = $subAction;
90 2
		$action->dispatch($subAction);
91
	}
92
93
	/**
94
	 * This very simply lists the groups, nothing snazzy.
95 2
	 */
96
	public function action_list()
97 2
	{
98
		global $txt, $context;
99 2
100 2
		$context['page_title'] = $txt['viewing_groups'];
101 2
		$current_area = $context['admin_menu_name'] ?? ($context['moderation_menu_name'] ?? '');
102
		if (!empty($current_area))
103 2
		{
104 2
			$context[$current_area]['tab_data'] = array(
105
				'title' => $txt['mc_group_requests'],
106
			);
107
		}
108 2
109
		if (isset($context['admin_menu_name']))
110 2
		{
111 2
			$base_type = 'admin';
112
			$base_params = ['action' => 'admin', 'area' => 'membergroups', 'sa' => 'members'];
113
		}
114
		elseif (isset($context['moderation_menu_name']))
115
		{
116
			$base_type = 'moderate';
117
			$base_params = ['action' => 'moderate', 'area' => 'viewgroups', 'sa' => 'members'];
118
		}
119
		else
120
		{
121
			$base_type = 'group';
122
			$base_params = ['action' => 'groups', 'sa' => 'members'];
123
		}
124
125
		// Use the standard templates for showing this.
126 2
		$listOptions = array(
127 2
			'id' => 'group_lists',
128 2
			'base_href' => getUrl($base_type, $base_params),
129
			'default_sort_col' => 'group',
130 2
			'get_items' => array(
131 2
				'file' => SUBSDIR . '/Membergroups.subs.php',
132
				'function' => 'list_getMembergroups',
133 2
				'params' => array(
134 2
					'regular',
135 2
					$this->user->id,
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
136 2
					allowedTo('manage_membergroups'),
137
					allowedTo('admin_forum'),
138
				),
139
			),
140
			'columns' => array(
141
				'group' => array(
142 2
					'header' => array(
143
						'value' => $txt['name'],
144
					),
145
					'data' => array(
146
						'function' => static function ($rowData) use ($base_type, $base_params) {
147 2
          // Since the moderator group has no explicit members, no link is needed.
148
          if ($rowData['id_group'] == 3)
149 2
   							{
150
   								$group_name = $rowData['group_name'];
151
   							}
152
   							else
153 2
   							{
154 2
   								$url = getUrl($base_type, array_merge($base_params, ['group' => $rowData['id_group']]));
155
   								$group_name = sprintf('<a href="%1$s">%2$s</a>', $url, $rowData['group_name_color']);
156
   							}
157
          // Add a help option for moderator and administrator.
158 2
          if ($rowData['id_group'] == 1)
159
   							{
160 2
   								$group_name .= ' (<a href="' . getUrl('action', ['action' => 'quickhelp', 'help' => 'membergroup_administrator']) . '" onclick="return reqOverlayDiv(this.href);" class="helpicon i-help"></a>)';
161
   							}
162 2
   							elseif ($rowData['id_group'] == 3)
163
   							{
164 2
   								$group_name .= ' (<a href="' . getUrl('action', ['action' => 'quickhelp', 'help' => 'membergroup_moderator']) . '" onclick="return reqOverlayDiv(this.href);" class="helpicon i-help"></a>)';
165
   							}
166
          return $group_name;
167 2
      },
168 2
					),
169
					'sort' => array(
170
						'default' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, mg.group_name',
171
						'reverse' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, mg.group_name DESC',
172
					),
173
				),
174
				'icons' => array(
175
					'header' => array(
176
						'value' => $txt['membergroups_icons'],
177 2
					),
178
					'data' => array(
179
						'function' => static function ($rowData) {
180
          global $settings;
181 2
          if (empty($rowData['icons'][0])) {
182
              return '';
183 2
          }
184
          if (empty($rowData['icons'][1])) {
185 2
              return '';
186
          }
187
          return str_repeat('<img src="' . $settings['images_url'] . '/group_icons/' . $rowData['icons'][1] . '" alt="*" />', $rowData['icons'][0]);
188
      },
189
					),
190
					'sort' => array(
191 2
						'default' => 'mg.icons',
192
						'reverse' => 'mg.icons DESC',
193
					)
194
				),
195
				'moderators' => array(
196
					'header' => array(
197
						'value' => $txt['moderators'],
198
					),
199
					'data' => array(
200 2
						'function' => static function ($group) {
201
          global $txt;
202
          return empty($group['moderators']) ? '<em>' . $txt['membergroups_new_copy_none'] . '</em>' : implode(', ', $group['moderators']);
203
      },
204 2
					),
205
				),
206 2
				'members' => array(
207 2
					'header' => array(
208
						'value' => $txt['membergroups_members_top'],
209
					),
210
					'data' => array(
211
						'function' => static function ($rowData) {
212 2
          global $txt;
213
          // No explicit members for the moderator group.
214
          return $rowData['id_group'] == 3 ? $txt['membergroups_guests_na'] : comma_format($rowData['num_members']);
215
      },
216 2
						'class' => 'centertext',
217
					),
218
					'sort' => array(
219 2
						'default' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, 1',
220 2
						'reverse' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, 1 DESC',
221 2
					),
222
				),
223
			),
224
		);
225
226
		// Create the request list.
227
		createList($listOptions);
228
229
		$context['sub_template'] = 'show_list';
230
		$context['default_list'] = 'group_lists';
231
	}
232 2
233
	/**
234 2
	 * Display members of a group, and allow adding of members to a group.
235 2
	 *
236 2
	 * What it does:
237
	 *
238
	 * - It can be called from ManageMembergroups if it needs templating within the admin environment.
239
	 * - It shows a list of members that are part of a given membergroup.
240
	 * - It is called by ?action=moderate;area=viewgroups;sa=members;group=x
241
	 * - It requires the manage_membergroups permission.
242
	 * - It allows to add and remove members from the selected membergroup.
243
	 * - It allows sorting on several columns.
244
	 * - It redirects to itself.
245
	 *
246
	 * @uses ManageMembergroups template, group_members sub template.
247
	 */
248
	public function action_members()
249
	{
250
		global $txt, $context, $modSettings, $settings;
251
252
		$current_group = $this->_req->getQuery('group', 'intval', 0);
253
254
		// These will be needed
255
		require_once(SUBSDIR . '/Membergroups.subs.php');
256
		require_once(SUBSDIR . '/Members.subs.php');
257
258
		// Load up the group details.
259
		$context['group'] = membergroupById($current_group, true, true);
260
261
		// No browsing of guests, membergroup 0 or moderators or non-existing groups.
262
		if ($context['group'] === false || in_array($current_group, array(-1, 0, 3)))
263
		{
264
			throw new Exception('membergroup_does_not_exist', false);
265
		}
266
267
		$context['group']['id'] = $context['group']['id_group'];
268
		$context['group']['name'] = $context['group']['group_name'];
269
270
		// Fix the membergroup icons.
271
		$context['group']['icons'] = explode('#', $context['group']['icons']);
272
		$context['group']['icons'] = !empty($context['group']['icons'][0]) && !empty($context['group']['icons'][1]) ? str_repeat('<img src="' . $settings['images_url'] . '/group_icons/' . $context['group']['icons'][1] . '" alt="*" />', $context['group']['icons'][0]) : '';
273
		$context['group']['can_moderate'] = allowedTo('manage_membergroups') && (allowedTo('admin_forum') || $context['group']['group_type'] != 1);
274
275
		// The template is very needy
276
		$context['breadcrumbs'][] = [
277
			'url' => getUrl('group', ['action' => 'groups', 'sa' => 'members', 'group' => $context['group']['id'], 'name' => $context['group']['name']]),
278
			'name' => $context['group']['name'],
279
		];
280
		$context['can_send_email'] = allowedTo('send_email_to_members');
281
		$context['sort_direction'] = isset($this->_req->query->desc) ? 'down' : 'up';
282
		$context['start'] = $this->_req->query->start;
283
		$context['can_moderate_forum'] = allowedTo('moderate_forum');
284
285
		// @todo: use createList
286
287
		// Load all the group moderators, for fun.
288
		$context['group']['moderators'] = array();
289
		$moderators = getGroupModerators($current_group);
290
		foreach ($moderators as $id_member => $name)
291
		{
292
			$context['group']['moderators'][] = array(
293
				'id' => $id_member,
294
				'name' => $name
295
			);
296
   if ($this->user->id != $id_member) {
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
297
       continue;
298
   }
299
   if ($context['group']['group_type'] == 1) {
300
       continue;
301
   }
302
   $context['group']['can_moderate'] = true;
303
		}
304
305
		// If this group is hidden then it can only "exist" if the user can moderate it!
306
		if ($context['group']['hidden'] && !$context['group']['can_moderate'])
307
		{
308
			throw new Exception('membergroup_does_not_exist', false);
309
		}
310
311
		// You can only assign membership if you are the moderator and/or can manage groups!
312
		if (!$context['group']['can_moderate'])
313
		{
314
			$context['group']['assignable'] = 0;
315
		}
316
		// Non-admins cannot assign admins.
317
		elseif ($context['group']['id'] == 1 && !allowedTo('admin_forum'))
318
		{
319
			$context['group']['assignable'] = 0;
320
		}
321
322
		// Removing member from group?
323
		if (isset($this->_req->post->remove)
324
			&& !empty($this->_req->post->rem)
325
			&& is_array($this->_req->post->rem)
326
			&& $context['group']['assignable'])
327
		{
328
			// Security first
329
			checkSession();
330
			validateToken('mod-mgm');
331
332
			// Make sure we're dealing with integers only.
333
			$to_remove = array_map('intval', $this->_req->post->rem);
334
			removeMembersFromGroups($to_remove, $current_group, true);
335
		}
336
		// Must be adding new members to the group...
337
		elseif (isset($this->_req->post->add)
338
			&& (!empty($this->_req->post->toAdd) || !empty($this->_req->post->member_add)) && $context['group']['assignable'])
339
		{
340
			// Make sure you can do this
341
			checkSession();
342
			validateToken('mod-mgm');
343
344
			$member_query = array(array('and' => 'not_in_group'));
345
			$member_parameters = array('not_in_group' => $current_group);
346
347
			// Get all the members to be added... taking into account names can be quoted ;)
348
			$toAdd = strtr(Util::htmlspecialchars($this->_req->post->toAdd, ENT_QUOTES), array('&quot;' => '"'));
349
			preg_match_all('~"([^"]+)"~', $toAdd, $matches);
350
			$member_names = array_unique(array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $toAdd))));
351
352
			foreach (array_keys($member_names) as $index)
353
			{
354
				$member_names[$index] = trim(Util::strtolower($member_names[$index]));
355
				if ($member_names[$index] === '')
356
				{
357
					unset($member_names[$index]);
358
				}
359
			}
360
361
			// Any members passed by ID?
362
			$member_ids = array();
363
			if (!empty($this->_req->post->member_add))
364
			{
365
				foreach ($this->_req->post->member_add as $id)
366
				{
367
					if ($id > 0)
368
					{
369
						$member_ids[] = (int) $id;
370
					}
371
				}
372
			}
373
374
			// Construct the query elements, first for adds by name
375
			if (!empty($member_ids))
376
			{
377
				$member_query[] = array('or' => 'member_ids');
378
				$member_parameters['member_ids'] = $member_ids;
379
			}
380
381
			// And then adds by ID
382
			if (!empty($member_names))
383
			{
384
				$member_query[] = array('or' => 'member_names');
385
				$member_parameters['member_names'] = $member_names;
386
			}
387
388
			// Get back the ones that were not already in the group
389
			$members = membersBy($member_query, $member_parameters);
390
391
			// Do the updates...
392
			if (!empty($members))
393
			{
394
				addMembersToGroup($members, $current_group, $context['group']['hidden'] ? 'only_additional' : 'auto', true);
395
			}
396
		}
397
398
		// Sort out the sorting!
399
		$sort_methods = array(
400
			'name' => 'real_name',
401
			'email' => allowedTo('moderate_forum') ? 'email_address' : ' ' . (isset($this->_req->query->desc) ? 'DESC' : 'ASC') . ', email_address',
402
			'active' => 'last_login',
403
			'registered' => 'date_registered',
404
			'posts' => 'posts',
405
		);
406
407
		// They didn't pick one, or tried a wrong one, so default to by name..
408
		if (!isset($this->_req->query->sort, $sort_methods[$this->_req->query->sort]))
409
		{
410
			$context['sort_by'] = 'name';
411
			$querySort = 'real_name' . (isset($this->_req->query->desc) ? ' DESC' : ' ASC');
412
		}
413
		// Otherwise sort by what they asked
414
		else
415
		{
416
			$context['sort_by'] = $this->_req->query->sort;
417
			$querySort = $sort_methods[$this->_req->query->sort] . (isset($this->_req->query->desc) ? ' DESC' : ' ASC');
418
		}
419
420
		// The where on the query is interesting. Non-moderators should only see people who are in this group as primary.
421
		if ($context['group']['can_moderate'])
422
		{
423
			$where = $context['group']['is_post_group'] ? 'in_post_group' : 'in_group';
424
		}
425
		else
426
		{
427
			$where = $context['group']['is_post_group'] ? 'in_post_group' : 'in_group_no_add';
428
		}
429
430
		// Count members of the group.
431
		$context['total_members'] = countMembersBy($where, array($where => $current_group));
432
		$context['total_members'] = comma_format($context['total_members']);
433
434
		// Create the page index.
435
		$context['page_index'] = constructPageIndex('{scripturl}?action=' . ($context['group']['can_moderate'] ? 'moderate;area=viewgroups' : 'groups') . ';sa=members;group=' . $current_group . ';sort=' . $context['sort_by'] . (isset($this->_req->query->desc) ? ';desc' : ''), $this->_req->query->start, $context['total_members'], $modSettings['defaultMaxMembers']);
436
437
		// Fetch the members that meet the where criteria
438
		$query_params = [$where => $current_group, 'order' => $querySort, 'start' => $this->_req->query->start, 'limit' => $modSettings['defaultMaxMembers']];
439
		$context['members'] = membersBy($where, $query_params, true);
440
		foreach ($context['members'] as $id => $row)
441
		{
442
			$last_online = empty($row['last_login']) ? $txt['never'] : standardTime($row['last_login']);
443
444
			// Italicize the online note if they aren't activated.
445
			if ($row['is_activated'] % 10 !== 1)
446
			{
447
				$last_online = '<em title="' . $txt['not_activated'] . '">' . $last_online . '</em>';
448
			}
449
450
			$context['members'][$id] = array(
451
				'id' => $row['id_member'],
452
				'name' => '<a href="' . getUrl('profile', ['action' => 'profile', 'u' => $row['id_member'], 'name' => $row['real_name']]) . '">' . $row['real_name'] . '</a>',
453
				'email' => $row['email_address'],
454
				'show_email' => showEmailAddress($row['id_member']),
455
				'ip' => '<a href="' . getUrl('action', ['action' => 'trackip', 'searchip' => $row['member_ip']]) . '">' . $row['member_ip'] . '</a>',
456
				'registered' => standardTime($row['date_registered']),
457
				'last_online' => $last_online,
458
				'posts' => comma_format($row['posts']),
459
				'is_activated' => $row['is_activated'] % 10 === 1,
460
			);
461
		}
462
463
		if (!empty($context['group']['assignable']))
464
		{
465
			loadJavascriptFile('suggest.js', ['defer' => true]);
466
		}
467
468
		// Select the template.
469
		$context['sub_template'] = 'group_members';
470
		$context['page_title'] = $txt['membergroups_members_title'] . ': ' . $context['group']['name'];
471
		createToken('mod-mgm');
472
	}
473
474
	/**
475
	 * Show and manage all group requests.
476
	 */
477
	public function action_requests()
478
	{
479
		global $txt, $context, $modSettings;
480
481
		// Set up the template stuff...
482
		$context['page_title'] = $txt['mc_group_requests'];
483
		$context['sub_template'] = 'show_list';
484
		$context[$context['moderation_menu_name']]['object']->prepareTabData([
485
			'title' => $txt['mc_group_requests'],
486
		]);
487
488
		// Verify we can be here.
489
		if ($this->user->mod_cache['gq'] == '0=1')
0 ignored issues
show
Bug Best Practice introduced by
The property mod_cache does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
490
		{
491
			isAllowedTo('manage_membergroups');
492
		}
493
494
		// Normally, we act normally...
495
		$where = $this->user->mod_cache['gq'] == '1=1' || $this->user->mod_cache['gq'] == '0=1' ? $this->user->mod_cache['gq'] : 'lgr.' . $this->user->mod_cache['gq'];
496
		$where_parameters = array();
497
498
		// We've submitted?
499
		if (isset($this->_req->post->{$context['session_var']})
500
			&& !empty($this->_req->post->groupr)
501
			&& !empty($this->_req->post->req_action))
502
		{
503
			checkSession('post');
504
			validateToken('mod-gr');
505
506
			require_once(SUBSDIR . '/Membergroups.subs.php');
507
508
			// Clean the values.
509
			$this->_req->post->groupr = array_map('intval', $this->_req->post->groupr);
510
511
			// If we are giving a reason (And why shouldn't we?), then we don't actually do much.
512
			if ($this->_req->post->req_action === 'reason')
513
			{
514
				// Different sub template...
515
				$context['sub_template'] = 'group_request_reason';
516
517
				// And a limitation. We don't care that the page number bit makes no sense, as we don't need it!
518
				$where .= ' AND lgr.id_request IN ({array_int:request_ids})';
519
				$where_parameters['request_ids'] = $this->_req->post->groupr;
520
521
				$context['group_requests'] = list_getGroupRequests(0, $modSettings['defaultMaxMessages'], 'lgr.id_request', $where, $where_parameters);
522
				createToken('mod-gr');
523
524
				// Let obExit etc sort things out.
525
				obExit();
526
			}
527
			// Otherwise we do something!
528
			else
529
			{
530
				// Get the details of all the members concerned...
531
				require_once(SUBSDIR . '/Members.subs.php');
532
				$concerned = getConcernedMembers($this->_req->post->groupr, $where, $this->_req->post->req_action === 'approve');
533
534
				// Cleanup old group requests..
535
				deleteGroupRequests($this->_req->post->groupr);
536
537
				// Ensure everyone who is online gets their changes right away.
538
				updateSettings(array('settings_updated' => time()));
539
540
				if (!empty($concerned['email_details']))
541
				{
542
					require_once(SUBSDIR . '/Mail.subs.php');
543
544
					// They are being approved?
545
					if ($this->_req->post->req_action === 'approve')
546
					{
547
						// Make the group changes.
548
						foreach ($concerned['group_changes'] as $id => $groups)
549
						{
550
							// Sanity check!
551
							foreach ($groups['add'] as $key => $value)
552
							{
553
								if ($value == 0 || trim($value) === '')
554
								{
555
									unset($groups['add'][$key]);
556
								}
557
							}
558
559
							assignGroupsToMember($id, $groups['primary'], $groups['add']);
560
						}
561
562
						foreach ($concerned['email_details'] as $email)
563
						{
564
							$replacements = array(
565
								'USERNAME' => $email['member_name'],
566
								'GROUPNAME' => $email['group_name'],
567
							);
568
569
							$emaildata = loadEmailTemplate('mc_group_approve', $replacements, $email['language']);
570
571
							sendmail($email['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 2);
572
						}
573
					}
574
					// Otherwise, they are getting rejected (With or without a reason).
575
					else
576
					{
577
						// Same as for approving, kind of.
578
						foreach ($concerned['email_details'] as $email)
579
						{
580
							$custom_reason = isset($this->_req->post->groupreason) && isset($this->_req->post->groupreason[$email['rid']]) ? $this->_req->post->groupreason[$email['rid']] : '';
581
582
							$replacements = array(
583
								'USERNAME' => $email['member_name'],
584
								'GROUPNAME' => $email['group_name'],
585
							);
586
587
							if (!empty($custom_reason))
588
							{
589
								$replacements['REASON'] = $custom_reason;
590
							}
591
592
							$emaildata = loadEmailTemplate(empty($custom_reason) ? 'mc_group_reject' : 'mc_group_reject_reason', $replacements, $email['language']);
593
594
							sendmail($email['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 2);
595
						}
596
					}
597
				}
598
599
				// Restore the current language.
600
				Txt::load('ModerationCenter');
601
			}
602
		}
603
604
		// We're going to want this for making our list.
605
		require_once(SUBSDIR . '/Membergroups.subs.php');
606
607
		// This is all the information required for a group listing.
608
		$listOptions = array(
609
			'id' => 'group_request_list',
610
			'width' => '100%',
611
			'items_per_page' => $modSettings['defaultMaxMessages'],
612
			'no_items_label' => $txt['mc_groupr_none_found'],
613
			'base_href' => getUrl('group', ['action' => 'groups', 'sa' => 'requests']),
614
			'default_sort_col' => 'member',
615
			'get_items' => array(
616
				'function' => 'list_getGroupRequests',
617
				'params' => array(
618
					$where,
619
					$where_parameters,
620
				),
621
			),
622
			'get_count' => array(
623
				'function' => 'list_getGroupRequestCount',
624
				'params' => array(
625
					$where,
626
					$where_parameters,
627
				),
628
			),
629
			'columns' => array(
630
				'member' => array(
631
					'header' => array(
632
						'value' => $txt['mc_groupr_member'],
633
					),
634
					'data' => array(
635
						'db' => 'member_link',
636
					),
637
					'sort' => array(
638
						'default' => 'mem.member_name',
639
						'reverse' => 'mem.member_name DESC',
640
					),
641
				),
642
				'group' => array(
643
					'header' => array(
644
						'value' => $txt['mc_groupr_group'],
645
					),
646
					'data' => array(
647
						'db' => 'group_link',
648
					),
649
					'sort' => array(
650
						'default' => 'mg.group_name',
651
						'reverse' => 'mg.group_name DESC',
652
					),
653
				),
654
				'reason' => array(
655
					'header' => array(
656
						'value' => $txt['mc_groupr_reason'],
657
					),
658
					'data' => array(
659
						'db' => 'reason',
660
					),
661
				),
662
				'date' => array(
663
					'header' => array(
664
						'value' => $txt['date'],
665
						'style' => 'width: 18%; white-space:nowrap;',
666
					),
667
					'data' => array(
668
						'db' => 'time_submitted',
669
					),
670
				),
671
				'action' => array(
672
					'header' => array(
673
						'value' => '<input type="checkbox" class="input_check" onclick="invertAll(this, this.form);" />',
674
						'style' => 'width: 4%;text-align: center;',
675
					),
676
					'data' => array(
677
						'sprintf' => array(
678
							'format' => '<input type="checkbox" name="groupr[]" value="%1$d" class="input_check" />',
679
							'params' => array(
680
								'id' => false,
681
							),
682
						),
683
						'class' => 'centertext',
684
					),
685
				),
686
			),
687
			'form' => array(
688
				'href' => getUrl('group', ['action' => 'groups', 'sa' => 'requests']),
689
				'include_sort' => true,
690
				'include_start' => true,
691
				'hidden_fields' => array(
692
					$context['session_var'] => $context['session_id'],
693
				),
694
				'token' => 'mod-gr',
695
			),
696
			'additional_rows' => array(
697
				array(
698
					'position' => 'bottom_of_list',
699
					'value' => '
700
						<select name="req_action" onchange="if (this.value != 0 &amp;&amp; (this.value === \'reason\' || confirm(\'' . $txt['mc_groupr_warning'] . '\'))) this.form.submit();">
701
							<option value="0">' . $txt['with_selected'] . ':</option>
702
							<option value="0" disabled="disabled">' . str_repeat('&#8212;', strlen($txt['mc_groupr_approve'])) . '</option>
703
							<option value="approve">&#10148;&nbsp;' . $txt['mc_groupr_approve'] . '</option>
704
							<option value="reject">&#10148;&nbsp;' . $txt['mc_groupr_reject'] . '</option>
705
							<option value="reason">&#10148;&nbsp;' . $txt['mc_groupr_reject_w_reason'] . '</option>
706
						</select>
707
						<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;" />',
708
					'class' => 'floatright',
709
				),
710
			),
711
		);
712
713
		// Create the request list.
714
		createToken('mod-gr');
715
		createList($listOptions);
716
717
		$context['default_list'] = 'group_request_list';
718
	}
719
}
720