ManageMembergroups::action_edit()   F
last analyzed

Complexity

Conditions 66

Size

Total Lines 304
Code Lines 151

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 4422

Importance

Changes 0
Metric Value
cc 66
eloc 151
nop 0
dl 0
loc 304
ccs 0
cts 134
cp 0
crap 4422
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
 * Handles the administration page for membergroups.
5
 *
6
 * @package   ElkArte Forum
7
 * @copyright ElkArte Forum contributors
8
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
9
 *
10
 * This file contains code covered by:
11
 * copyright: 2011 Simple Machines (http://www.simplemachines.org)
12
 *
13
 * @version 2.0 Beta 1
14
 *
15
 */
16
17
namespace ElkArte\AdminController;
18
19
use ElkArte\AbstractController;
20
use ElkArte\Action;
21
use ElkArte\Controller\Groups;
22
use ElkArte\Exceptions\Exception;
23
use ElkArte\Helper\DataValidator;
24
use ElkArte\Languages\Txt;
25
use ElkArte\Permissions;
26
use ElkArte\SettingsForm\SettingsForm;
27
28
/**
29
 * ManageMembergroups controller, administration page for membergroups.
30
 *
31
 * @package Membergroups
32
 */
33
class ManageMembergroups extends AbstractController
34
{
35
	/**
36
	 * Main dispatcher, the en\trance point for all 'Manage Membergroup' actions.
37
	 *
38
	 * What it does:
39
	 *
40
	 * - It forwards to a function based on the given subaction, default being subaction 'index', or, without manage_membergroup
41
	 * permissions, then 'settings'.
42
	 * - Called by ?action=admin;area=membergroups.
43
	 * - Requires the manage_membergroups or the admin_forum permission.
44
	 *
45
	 * @event integrate_sa_manage_membergroups Used to add more sub actions
46
	 * @uses ManageMembergroups template.
47
	 * @uses ManageMembers language file.
48
	 * @see AbstractController::action_index()
49
	 */
50
	public function action_index()
51
	{
52
		global $context, $txt;
53
54
		// Language and template stuff, the usual.
55
		Txt::load('ManageMembers');
56
		theme()->getTemplates()->load('ManageMembergroups');
57
58
		$subActions = [
59
			'add' => [$this, 'action_add', 'permission' => 'manage_membergroups'],
60
			'delete' => [$this, 'action_delete', 'permission' => 'manage_membergroups'],
61
			'edit' => [$this, 'action_edit', 'permission' => 'manage_membergroups'],
62
			'index' => [$this, 'action_list', 'permission' => 'manage_membergroups'],
63
			'members' => [Groups::class, 'action_index', 'permission' => 'manage_membergroups'],
64
			'settings' => [$this, 'action_groupSettings_display', 'permission' => 'admin_forum'],
65
		];
66
67
		$action = new Action('manage_membergroups');
68
69
		// Set up the admin tabs.
70
		$context[$context['admin_menu_name']]['object']->prepareTabData([
71
			'title' => 'membergroups_title',
72
			'description' => 'membergroups_description',
73
			'help' => 'membergroups']
74
		);
75
76
		// Set that subaction, call integrate_sa_manage_membergroups
77
		$subAction = $action->initialize($subActions, allowedTo('manage_membergroups') ? 'index' : 'settings');
78
79
		// Final items for the template
80
		$context['page_title'] = $txt['membergroups_title'];
81
		$context['sub_action'] = $subAction;
82
83
		// Call the right function.
84
		$action->dispatch($subAction);
85
	}
86
87
	/**
88
	 * Shows an overview of the current membergroups.
89
	 *
90
	 * What it does:
91
	 *
92
	 * - Called by ?action=admin;area=membergroups.
93
	 * - Requires the manage_membergroups permission.
94
	 * - Splits the membergroups in regular ones and post-count-based groups.
95
	 * - It also counts the number of members part of each membergroup.
96
	 *
97
	 * @event integrate_list_regular_membergroups_list
98
	 * @event integrate_list_post_count_membergroups_list
99
	 * @uses ManageMembergroups template, main.
100
	 */
101
	public function action_list(): void
102
	{
103
		global $txt, $context;
104
105
		$context['page_title'] = $txt['membergroups_title'];
106
107
		// The first list shows the regular membergroups.
108
		$listOptions = [
109
			'id' => 'regular_membergroups_list',
110
			'title' => $txt['membergroups_regular'],
111
			'base_href' => getUrl('admin', ['action' => 'admin', 'area' => 'membergroups'] + ($this->_req->hasQuery('sort2') ? ['sort2' => urlencode($this->_req->getQuery('sort2', 'trim'))] : [])),
112
			'default_sort_col' => 'name',
113
			'get_items' => [
114
				'file' => SUBSDIR . '/Membergroups.subs.php',
115
				'function' => 'list_getMembergroups',
116
				'params' => [
117
					'regular',
118
					$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...
119
					allowedTo('manage_membergroups'),
120
					allowedTo('admin_forum'),
121
				],
122
			],
123
			'columns' => [
124
				'name' => [
125
					'header' => [
126
						'value' => $txt['membergroups_name'],
127
					],
128
					'data' => [
129
						'function' => static function ($rowData) {
130
							// Since the moderator group has no explicit members, no link is needed.
131
							if ($rowData['id_group'] === 3)
132
							{
133
								$group_name = $rowData['group_name'];
134
							}
135
							else
136
							{
137
								$group_name = sprintf('<a href="' . getUrl('admin', ['action' => 'admin', 'area' => 'membergroups', 'sa' => 'members', 'group' => $rowData['id_group']]) . '">%1$s</a>', $rowData['group_name_color']);
138
							}
139
140
							// Add a help option for moderator and administrator.
141
							if ($rowData['id_group'] === 1)
142
							{
143
								$group_name .= ' <a href="' . getUrl('action', ['action' => 'quickhelp', 'help' => 'membergroup_administrator']) . '" onclick="return reqOverlayDiv(this.href);" class="helpicon i-help"></a>';
144
							}
145
							elseif ($rowData['id_group'] === 3)
146
							{
147
								$group_name .= ' <a href="' . getUrl('action', ['action' => 'quickhelp', 'help' => 'membergroup_moderator']) . '" onclick="return reqOverlayDiv(this.href);" class="helpicon i-help"></a>';
148
							}
149
							return $group_name;
150
						},
151
					],
152
					'sort' => [
153
						'default' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, mg.group_name',
154
						'reverse' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, mg.group_name DESC',
155
					],
156
				],
157
				'icons' => [
158
					'header' => [
159
						'value' => $txt['membergroups_icons'],
160
					],
161
					'data' => [
162
						'function' => static function ($rowData) {
163
							global $settings;
164
165
							if (empty($rowData['icons'][0]))
166
							{
167
								return '';
168
							}
169
170
							if (empty($rowData['icons'][1]))
171
							{
172
								return '';
173
							}
174
175
							return str_repeat('<img src="' . $settings['images_url'] . '/group_icons/' . $rowData['icons'][1] . '" alt="*" />', $rowData['icons'][0]);
176
						},
177
					],
178
					'sort' => [
179
						'default' => 'mg.icons',
180
						'reverse' => 'mg.icons DESC',
181
					]
182
				],
183
				'members' => [
184
					'header' => [
185
						'value' => $txt['membergroups_members_top'],
186
					],
187
					'data' => [
188
						'function' => static function ($rowData) {
189
							global $txt;
190
							// No explicit members for the moderator group.
191
							return $rowData['id_group'] === 3 ? $txt['membergroups_guests_na'] : comma_format($rowData['num_members']);
192
						},
193
					],
194
					'sort' => [
195
						'default' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, 1',
196
						'reverse' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, 1 DESC',
197
					],
198
				],
199
				'modify' => [
200
					'header' => [
201
						'value' => $txt['modify'],
202
					],
203
					'data' => [
204
						'sprintf' => [
205
							'format' => '<a href="' . getUrl('admin', ['action' => 'admin', 'area' => 'membergroups', 'sa' => 'edit', 'group' => '']) . '%1$d">' . $txt['membergroups_modify'] . '</a>',
206
							'params' => [
207
								'id_group' => false,
208
							],
209
						],
210
					],
211
				],
212
			],
213
			'additional_rows' => [
214
				[
215
					'position' => 'below_table_data',
216
					'class' => 'submitbutton',
217
					'value' => '<a class="linkbutton" href="' . getUrl('admin', ['action' => 'admin', 'area' => 'membergroups', 'sa' => 'add', 'generalgroup']) . '">' . $txt['membergroups_add_group'] . '</a>',
218
				],
219
			],
220
		];
221
222
		createList($listOptions);
223
224
		// The second list shows the post-count-based groups.
225
		$listOptions = [
226
			'id' => 'post_count_membergroups_list',
227
			'title' => $txt['membergroups_post'],
228
			'base_href' => getUrl('admin', ['action' => 'admin', 'area' => 'membergroups'] + ($this->_req->hasQuery('sort') ? ['sort' => urlencode($this->_req->getQuery('sort', 'trim'))] : [])),
229
			'default_sort_col' => 'required_posts',
230
			'request_vars' => [
231
				'sort' => 'sort2',
232
				'desc' => 'desc2',
233
			],
234
			'get_items' => [
235
				'file' => SUBSDIR . '/Membergroups.subs.php',
236
				'function' => 'list_getMembergroups',
237
				'params' => [
238
					'post_count',
239
					$this->user->id,
240
					allowedTo('manage_membergroups'),
241
					allowedTo('admin_forum'),
242
				],
243
			],
244
			'columns' => [
245
				'name' => [
246
					'header' => [
247
						'value' => $txt['membergroups_name'],
248
					],
249
					'data' => [
250
						'function' => static fn($rowData) => sprintf('<a href="' . getUrl('admin', ['action' => 'admin', 'area' => 'membergroups', 'sa' => 'members', 'group' => $rowData['id_group']]) . '">%1$s</a>', $rowData['group_name_color']),
251
					],
252
					'sort' => [
253
						'default' => 'mg.group_name',
254
						'reverse' => 'mg.group_name DESC',
255
					],
256
				],
257
				'icons' => [
258
					'header' => [
259
						'value' => $txt['membergroups_icons'],
260
					],
261
					'data' => [
262
						'function' => static function ($rowData) {
263
							global $settings;
264
265
							if (empty($rowData['icons'][0]))
266
							{
267
								return '';
268
							}
269
270
							if (empty($rowData['icons'][1]))
271
							{
272
								return '';
273
							}
274
275
							return str_repeat('<img src="' . $settings['images_url'] . '/group_icons/' . $rowData['icons'][1] . '" alt="*" />', $rowData['icons'][0]);
276
						},
277
					],
278
					'sort' => [
279
						'default' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, icons',
280
						'reverse' => 'CASE WHEN mg.id_group < 4 THEN mg.id_group ELSE 4 END, icons DESC',
281
					]
282
				],
283
				'members' => [
284
					'header' => [
285
						'value' => $txt['membergroups_members_top'],
286
					],
287
					'data' => [
288
						'db' => 'num_members',
289
					],
290
					'sort' => [
291
						'default' => '1 DESC',
292
						'reverse' => '1',
293
					],
294
				],
295
				'required_posts' => [
296
					'header' => [
297
						'value' => $txt['membergroups_min_posts'],
298
					],
299
					'data' => [
300
						'db' => 'min_posts',
301
					],
302
					'sort' => [
303
						'default' => 'mg.min_posts',
304
						'reverse' => 'mg.min_posts DESC',
305
					],
306
				],
307
				'modify' => [
308
					'header' => [
309
						'value' => $txt['modify'],
310
					],
311
					'data' => [
312
						'sprintf' => [
313
							'format' => '<a href="' . getUrl('admin', ['action' => 'admin', 'area' => 'membergroups', 'sa' => 'edit', 'group' => '']) . '%1$d">' . $txt['membergroups_modify'] . '</a>',
314
							'params' => [
315
								'id_group' => false,
316
							],
317
						],
318
					],
319
				],
320
			],
321
			'additional_rows' => [
322
				[
323
					'position' => 'below_table_data',
324
					'class' => 'submitbutton',
325
					'value' => '<a class="linkbutton" href="' . getUrl('admin', ['action' => 'admin', 'area' => 'membergroups', 'sa' => 'add', 'postgroup']) . '">' . $txt['membergroups_add_group'] . '</a>',
326
				],
327
			],
328
		];
329
330
		createList($listOptions);
331
	}
332
333
	/**
334
	 * This function handles adding a membergroup and setting some initial properties.
335
	 *
336
	 * What it does:
337
	 *
338
	 * - Called by ?action=admin;area=membergroups;sa=add.
339
	 * - It requires the manage_membergroups permission.
340
	 * - Allows using a predefined permission profile or copying one from another group.
341
	 * - Redirects to action=admin;area=membergroups;sa=edit;group=x.
342
	 *
343
	 * @event integrate_add_membergroup passed $id_group and $postCountBasedGroup
344
	 * @uses the new_group sub template of ManageMembergroups.
345
	 */
346
	public function action_add(): void
347
	{
348
		global $context, $txt, $modSettings;
349
350
		require_once(SUBSDIR . '/Membergroups.subs.php');
351
352
		// A form was submitted, we can start adding.
353
		if (!$this->_req->comparePost('group_name', '', 'trim', ''))
354
		{
355
			checkSession();
356
			validateToken('admin-mmg');
357
358
			$postCountBasedGroup = isset($this->_req->post->min_posts) && (!isset($this->_req->post->postgroup_based) || !empty($this->_req->post->postgroup_based));
359
			$group_type = !isset($this->_req->post->group_type) || $this->_req->post->group_type < 0 || $this->_req->post->group_type > 3 || ($this->_req->post->group_type == 1 && !allowedTo('admin_forum')) ? 0 : (int) $this->_req->post->group_type;
360
361
			// @todo Check for members with same name too?
362
363
			// Don't allow copying of a real privileged person!
364
			$permissionsObject = new Permissions();
365
			$illegal_permissions = $permissionsObject->getIllegalPermissions();
366
			$minposts = empty($this->_req->post->min_posts) ? '-1' : (int) $this->_req->post->min_posts;
367
368
			$id_group = createMembergroup($this->_req->post->group_name, $minposts, $group_type);
369
370
			call_integration_hook('integrate_add_membergroup', [$id_group, $postCountBasedGroup]);
371
372
			// Update the post-groups now if this is a post group!
373
			if (isset($this->_req->post->min_posts))
374
			{
375
				require_once(SUBSDIR . '/Membergroups.subs.php');
376
				updatePostGroupStats();
377
			}
378
379
			// You cannot set permissions for post-groups if they are disabled.
380
			if ($postCountBasedGroup && empty($modSettings['permission_enable_postgroups']))
381
			{
382
				$this->_req->post->perm_type = '';
383
			}
384
385
			if ($this->_req->post->perm_type === 'predefined')
386
			{
387
				// Set the default permission level.
388
				require_once(SUBSDIR . '/ManagePermissions.subs.php');
389
				setPermissionLevel($this->_req->post->level, $id_group);
390
			}
391
			// Copy or inherit the permissions!
392
			elseif ($this->_req->post->perm_type === 'copy' || $this->_req->post->perm_type === 'inherit')
393
			{
394
				$copy_id = $this->_req->post->perm_type === 'copy' ? (int) $this->_req->post->copyperm : (int) $this->_req->post->inheritperm;
395
396
				// Are you a powerful admin?
397
				if (!allowedTo('admin_forum'))
398
				{
399
					$copy_type = membergroupById($copy_id);
400
401
					// Keep protected groups ... well, protected!
402
					if ($copy_type['group_type'] === 1)
403
					{
404
						throw new Exception('membergroup_does_not_exist');
405
					}
406
				}
407
408
				// Don't allow copying of a real privileged person!
409
				copyPermissions($id_group, $copy_id, $illegal_permissions);
410
				copyBoardPermissions($id_group, $copy_id);
411
412
				// Also get some membergroup information if we're copying and not copying from guests...
413
				if ($copy_id > 0 && $this->_req->post->perm_type === 'copy')
414
				{
415
					updateCopiedGroup($id_group, $copy_id);
416
				}
417
				// If inheriting say so...
418
				elseif ($this->_req->post->perm_type === 'inherit')
419
				{
420
					updateInheritedGroup($id_group, $copy_id);
421
				}
422
			}
423
424
			// Make sure all boards selected are stored in a proper array.
425
			$changed_boards = [];
426
			$accesses = empty($this->_req->post->boardaccess) || !is_array($this->_req->post->boardaccess) ? [] : $this->_req->post->boardaccess;
427
			$changed_boards['allow'] = [];
428
			$changed_boards['deny'] = [];
429
			$changed_boards['ignore'] = [];
430
			foreach ($accesses as $group_id => $action)
431
			{
432
				$changed_boards[$action][] = (int) $group_id;
433
			}
434
435
			foreach (['allow', 'deny'] as $board_action)
436
			{
437
				// Only do this if they have special access requirements.
438
				if (!isset($changed_boards[$board_action]))
439
				{
440
					continue;
441
				}
442
443
				if ($changed_boards[$board_action] === [])
444
				{
445
					continue;
446
				}
447
448
				assignGroupToBoards($id_group, $changed_boards, $board_action);
449
			}
450
451
			// If this is joinable, then set it to show group membership in people's profiles.
452
			if (empty($modSettings['show_group_membership']) && $group_type > 1)
453
			{
454
				updateSettings(['show_group_membership' => 1]);
455
			}
456
457
			// Rebuild the group cache.
458
			updateSettings([
459
				'settings_updated' => time(),
460
			]);
461
462
			// We did it.
463
			logAction('add_group', ['group' => $this->_req->post->group_name], 'admin');
464
465
			// Go change some more settings.
466
			redirectexit('action=admin;area=membergroups;sa=edit;group=' . $id_group);
467
		}
468
469
		// Just show the 'add membergroup' screen.
470
		$context['page_title'] = $txt['membergroups_new_group'];
471
		$context['sub_template'] = 'new_group';
472
		$context['post_group'] = $this->_req->hasQuery('postgroup');
473
		$context['undefined_group'] = !$this->_req->hasQuery('postgroup') && !$this->_req->hasQuery('generalgroup');
474
		$context['allow_protected'] = allowedTo('admin_forum');
475
476
		if (!empty($modSettings['deny_boards_access']))
477
		{
478
			Txt::load('ManagePermissions');
479
		}
480
481
		$context['groups'] = getBasicMembergroupData(['globalmod'], [], 'min_posts, id_group != {int:global_mod_group}, group_name');
482
483
		require_once(SUBSDIR . '/Boards.subs.php');
484
		$context += getBoardList();
485
486
		// Include a list of boards per category for easy toggling.
487
		foreach ($context['categories'] as $category)
488
		{
489
			$context['categories'][$category['id']]['child_ids'] = array_keys($category['boards']);
490
		}
491
492
		createToken('admin-mmg');
493
	}
494
495
	/**
496
	 * Deleting a membergroup by URL (not implemented).
497
	 *
498
	 * What it does:
499
	 *
500
	 * - Called by ?action=admin;area=membergroups;sa=delete;group=x;session_var=y.
501
	 * - Requires the manage_membergroups permission.
502
	 * - Redirects to ?action=admin;area=membergroups.
503
	 *
504
	 * @todo look at this
505
	 */
506
	public function action_delete(): void
507
	{
508
		checkSession('get');
509
510
		require_once(SUBSDIR . '/Membergroups.subs.php');
511
		deleteMembergroups((int) $this->_req->query->group);
512
513
		// Go back to the membergroup index.
514
		redirectexit('action=admin;area=membergroups;');
515
	}
516
517
	/**
518
	 * Editing a membergroup.
519
	 *
520
	 * What it does:
521
	 *
522
	 * - Screen to edit a specific membergroup.
523
	 * - Called by ?action=admin;area=membergroups;sa=edit;group=x.
524
	 * - It requires the manage_membergroups permission.
525
	 * - Also handles the delete button of the edit form.
526
	 * - Redirects to ?action=admin;area=membergroups.
527
	 *
528
	 * @event integrate_save_membergroup, passed $current_group['id_group']
529
	 * @event integrate_view_membergroup
530
	 * @uses the edit_group sub template of ManageMembergroups.
531
	 */
532
	public function action_edit(): void
533
	{
534
		global $context, $txt, $modSettings;
535
536
		$current_group_id = $this->_req->getQuery('group', 'intval', 0);
537
		$current_group = [];
538
539
		if (!empty($modSettings['deny_boards_access']))
540
		{
541
			Txt::load('ManagePermissions');
542
		}
543
544
		require_once(SUBSDIR . '/Membergroups.subs.php');
545
546
		// Make sure this group is editable.
547
		if (!empty($current_group_id))
548
		{
549
			$current_group = membergroupById($current_group_id);
550
		}
551
552
		// Now, do we have a valid id?
553
		if (!allowedTo('admin_forum') && !empty($current_group_id) && $current_group['group_type'] == 1)
554
		{
555
			throw new Exception('membergroup_does_not_exist', false);
556
		}
557
558
		// Delete this membergroup button was pressed.
559
		if (isset($this->_req->post->delete))
560
		{
561
			checkSession();
562
			validateToken('admin-mmg');
563
564
			if (empty($current_group_id))
565
			{
566
				throw new Exception('membergroup_does_not_exist', false);
567
			}
568
569
			// Let's delete the group
570
			deleteMembergroups($current_group['id_group']);
571
572
			redirectexit('action=admin;area=membergroups;');
573
		}
574
		// A form was submitted with the new membergroup settings.
575
		elseif ($this->_req->hasPost('save'))
576
		{
577
			// Validate the session.
578
			checkSession();
579
			validateToken('admin-mmg');
580
581
			if (empty($current_group_id))
582
			{
583
				throw new Exception('membergroup_does_not_exist', false);
584
			}
585
586
			// Empty values will be replaced by validator values where they exist
587
			$empty_post = ['max_messages' => null, 'min_posts' => null, 'group_type' => null, 'group_desc' => '',
588
				'group_name' => '', 'group_hidden' => null, 'group_inherit' => null, 'icon_count' => null,
589
				'icon_image' => '', 'online_color' => '', 'boardaccess' => null];
590
591
			$validator = new DataValidator();
592
593
			// Clean up the inputs! :D
594
			$validator->sanitation_rules([
595
				'max_messages' => 'intval',
596
				'min_posts' => 'intval|abs',
597
				'group_type' => 'intval',
598
				'group_desc' => 'trim|Util::htmlspecialchars',
599
				'group_name' => 'trim|Util::htmlspecialchars',
600
				'group_hidden' => 'intval',
601
				'group_inherit' => 'intval',
602
				'icon_count' => 'intval',
603
				'icon_image' => 'trim|Util::htmlspecialchars',
604
				'online_color' => 'trim|valid_color',
605
			]);
606
			$validator->input_processing([
607
				'boardaccess' => 'array',
608
			]);
609
			$validator->validation_rules([
610
				'boardaccess' => 'contains[allow,ignore,deny]',
611
			]);
612
			$validator->validate($this->_req->post);
613
614
			// Insert the clean data
615
			$our_post = array_replace((array) $this->_req->post, $empty_post, $validator->validation_data());
616
617
			// Can they really inherit from this group?
618
			$inherit_type = [];
619
			if ($our_post['group_inherit'] != -2 && !allowedTo('admin_forum'))
620
			{
621
				$inherit_type = membergroupById($our_post['group_inherit']);
622
			}
623
624
			$min_posts = $our_post['group_type'] == -1 && $our_post['min_posts'] >= 0 && $current_group['id_group'] > 3 ? $our_post['min_posts'] : ($current_group['id_group'] == 4 ? 0 : -1);
625
			$group_inherit = $current_group['id_group'] > 1 && $current_group['id_group'] != 3 && (empty($inherit_type['group_type']) || $inherit_type['group_type'] != 1) ? $our_post['group_inherit'] : -2;
626
627
			//@todo Don't set online_color for the Moderators group?
628
629
			// Do the update of the membergroup settings.
630
			$properties = [
631
				'max_messages' => $our_post['max_messages'],
632
				'min_posts' => $min_posts,
633
				'group_type' => $our_post['group_type'] < 0 || $our_post['group_type'] > 3 || ($our_post['group_type'] == 1 && !allowedTo('admin_forum')) ? 0 : $our_post['group_type'],
634
				'hidden' => !$our_post['group_hidden'] || $min_posts != -1 || $current_group['id_group'] == 3 ? 0 : $our_post['group_hidden'],
635
				'id_parent' => $group_inherit,
636
				'current_group' => $current_group['id_group'],
637
				'group_name' => $our_post['group_name'],
638
				'online_color' => $our_post['online_color'],
639
				'icons' => $our_post['icon_count'] <= 0 ? '' : min($our_post['icon_count'], 10) . '#' . $our_post['icon_image'],
640
				// /me wonders why admin is *so* special
641
				'description' => $current_group['id_group'] == 1 || $our_post['group_type'] != -1 ? $our_post['group_desc'] : '',
642
			];
643
			updateMembergroupProperties($properties);
644
645
			call_integration_hook('integrate_save_membergroup', [$current_group['id_group']]);
646
647
			// Time to update the boards this membergroup has access to.
648
			if ($current_group['id_group'] == 2 || $current_group['id_group'] > 3)
649
			{
650
				$changed_boards = [];
651
				$changed_boards['allow'] = [];
652
				$changed_boards['deny'] = [];
653
				$changed_boards['ignore'] = [];
654
655
				if ($our_post['boardaccess'])
656
				{
657
					foreach ($our_post['boardaccess'] as $group_id => $action)
658
					{
659
						$changed_boards[$action][] = (int) $group_id;
660
					}
661
				}
662
663
				foreach (['allow', 'deny'] as $board_action)
664
				{
665
					// Find all board this group is in, but shouldn't be in.
666
					detachGroupFromBoards($current_group['id_group'], $changed_boards, $board_action);
667
668
					// Add the membergroup to all boards that hadn't been set yet.
669
					if (!isset($changed_boards[$board_action]))
670
					{
671
						continue;
672
					}
673
674
					if (empty($changed_boards[$board_action]))
675
					{
676
						continue;
677
					}
678
679
					assignGroupToBoards($current_group['id_group'], $changed_boards, $board_action);
680
				}
681
			}
682
683
			// Remove everyone from this group!
684
			if ($min_posts != -1)
685
			{
686
				detachDeletedGroupFromMembers($current_group['id_group']);
687
			}
688
			elseif ($current_group['id_group'] != 3)
689
			{
690
				// Making it a hidden group? If so, remove everyone with it as a primary group (Actually, just make them additional).
691
				if ($our_post['group_hidden'] == 2)
692
				{
693
					setGroupToHidden($current_group['id_group']);
694
				}
695
696
				// Either way, let's check our "show group membership" setting is correct.
697
				validateShowGroupMembership();
698
			}
699
700
			// Do we need to set inherited permissions?
701
			if ($group_inherit !== -2 && $group_inherit !== $this->_req->post->old_inherit)
702
			{
703
				$permissionsObject = new Permissions();
704
				$permissionsObject->updateChild($group_inherit);
705
			}
706
707
			// Lastly, moderators!
708
			$moderator_string = $this->_req->getPost('group_moderators', 'trim', '');
709
			detachGroupModerators($current_group['id_group']);
710
711
			if ((!empty($moderator_string) || !empty($this->_req->post->moderator_list)) && $min_posts == -1 && $current_group['id_group'] != 3)
712
			{
713
				// Get all the usernames from the string
714
				if (!empty($moderator_string))
715
				{
716
					$moderator_string = strtr(preg_replace('~&amp;#(\d{4,5}|[2-9]\d{2,4}|1[2-9]\d);~', '&#$1;', htmlspecialchars($moderator_string, ENT_QUOTES, 'UTF-8')), ['&quot;' => '"']);
717
					preg_match_all('~"([^"]+)"~', $moderator_string, $matches);
718
					$moderators = array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $moderator_string)));
719
					$moderators = array_filter(array_map('trim', $moderators));
720
721
					// Find all the id_member's for the member_name's in the list.
722
					if (!empty($moderators))
723
					{
724
						$group_moderators = getIDMemberFromGroupModerators($moderators);
725
					}
726
				}
727
				else
728
				{
729
					$moderators = [];
730
					foreach ($this->_req->post->moderator_list as $moderator)
731
					{
732
						$moderators[] = (int) $moderator;
733
					}
734
735
					$group_moderators = [];
736
					if (!empty($moderators))
737
					{
738
						require_once(SUBSDIR . '/Members.subs.php');
739
						$members = getBasicMemberData($moderators);
740
						foreach ($members as $member)
741
						{
742
							$group_moderators[] = $member['id_member'];
743
						}
744
					}
745
				}
746
747
				// Found some?
748
				if (!empty($group_moderators))
749
				{
750
					assignGroupModerators($current_group['id_group'], $group_moderators);
751
				}
752
			}
753
754
			// There might have been some post-group changes.
755
			require_once(SUBSDIR . '/Membergroups.subs.php');
756
			updatePostGroupStats();
757
758
			// We've definitely changed some group stuff.
759
			updateSettings([
760
				'settings_updated' => time(),
761
			]);
762
763
			// Log the edit.
764
			logAction('edited_group', ['group' => $our_post['group_name']], 'admin');
765
766
			redirectexit('action=admin;area=membergroups');
767
		}
768
769
		// Fetch the current group information.
770
		$row = membergroupById($current_group['id_group'], true);
771
772
		if (empty($row) || (!allowedTo('admin_forum') && $row['group_type'] === 1))
773
		{
774
			throw new Exception('membergroup_does_not_exist', false);
775
		}
776
777
		$row['icons'] = explode('#', $row['icons']);
778
779
		$context['group'] = [
780
			'id' => $row['id_group'],
781
			'name' => $row['group_name'],
782
			'description' => htmlspecialchars($row['description'], ENT_COMPAT, 'UTF-8'),
783
			'editable_name' => $row['group_name'],
784
			'color' => $row['online_color'],
785
			'min_posts' => $row['min_posts'],
786
			'max_messages' => $row['max_messages'],
787
			'icon_count' => (int) $row['icons'][0],
788
			'icon_image' => $row['icons'][1] ?? '',
789
			'is_post_group' => $row['min_posts'] !== -1,
790
			'type' => $row['min_posts'] !== -1 ? 0 : $row['group_type'],
791
			'hidden' => $row['min_posts'] === -1 ? $row['hidden'] : 0,
792
			'inherited_from' => $row['id_parent'],
793
			'allow_post_group' => $row['id_group'] === 2 || $row['id_group'] > 4,
794
			'allow_delete' => $row['id_group'] === 2 || $row['id_group'] > 4,
795
			'allow_protected' => allowedTo('admin_forum'),
796
		];
797
798
		// Get any moderators for this group
799
		$context['group']['moderators'] = getGroupModerators($row['id_group']);
800
		$context['group']['moderator_list'] = empty($context['group']['moderators']) ? '' : '&quot;' . implode('&quot;, &quot;', $context['group']['moderators']) . '&quot;';
801
802
		if (!empty($context['group']['moderators']))
803
		{
804
			[$context['group']['last_moderator_id']] = array_slice(array_keys($context['group']['moderators']), -1);
805
		}
806
807
		// Get a list of boards this membergroup is allowed to see.
808
		$context['boards'] = [];
809
		if ($row['id_group'] === 2 || $row['id_group'] > 3)
810
		{
811
			require_once(SUBSDIR . '/Boards.subs.php');
812
			$context += getBoardList(['override_permissions' => true, 'access' => $row['id_group'], 'not_redirection' => true]);
813
814
			// Include a list of boards per category for easy toggling.
815
			foreach ($context['categories'] as $category)
816
			{
817
				$context['categories'][$category['id']]['child_ids'] = array_keys($category['boards']);
818
			}
819
		}
820
821
		// Finally, get all the groups that could be inherited off.
822
		$context['inheritable_groups'] = getInheritableGroups($row['id_group']);
823
824
		call_integration_hook('integrate_view_membergroup');
825
826
		$context['sub_template'] = 'edit_group';
827
		$context['page_title'] = $txt['membergroups_edit_group'];
828
829
		// Use the autosuggest script when needed
830
		if ($context['group']['id'] != 3 && $context['group']['id'] != 4)
831
		{
832
			loadJavascriptFile('suggest.js', ['defer' => true]);
833
		}
834
835
		createToken('admin-mmg');
836
	}
837
838
	/**
839
	 * Set some general membergroup settings and permissions.
840
	 *
841
	 * What it does:
842
	 *
843
	 * - Called by ?action=admin;area=membergroups;sa=settings
844
	 * - Requires the admin_forum permission (and manage_permissions for changing permissions)
845
	 * - Redirects to itself.
846
	 *
847
	 * @event integrate_save_membergroup_settings
848
	 * @uses membergroup_settings sub template of ManageMembergroups.
849
	 */
850
	public function action_groupSettings_display(): void
851
	{
852
		global $context, $txt;
853
854
		$context['sub_template'] = 'show_settings';
855
		$context['page_title'] = $txt['membergroups_settings'];
856
857
		// Instantiate the form
858
		$settingsForm = new SettingsForm(SettingsForm::DB_ADAPTER);
859
		$settingsForm->setConfigVars($this->_settings());
860
861
		if ($this->_req->hasQuery('save'))
862
		{
863
			checkSession();
864
			call_integration_hook('integrate_save_membergroup_settings');
865
866
			// Yeppers, saving this...
867
			$settingsForm->setConfigValues((array) $this->_req->post);
868
			$settingsForm->save();
869
			redirectexit('action=admin;area=membergroups;sa=settings');
870
		}
871
872
		// Some simple context.
873
		$context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'membergroups', 'sa' => 'settings']);
874
		$context['settings_title'] = $txt['membergroups_settings'];
875
876
		$settingsForm->prepare();
877
	}
878
879
	/**
880
	 * Return the configuration settings for membergroups management.
881
	 *
882
	 * @event integrate_modify_membergroup_settings
883
	 */
884
	private function _settings()
885
	{
886
		// Only one thing here!
887
		$config_vars = [
888 2
			['permissions', 'manage_membergroups'],
889
		];
890
891
		// Add new settings with a nice hook, makes them available for admin settings search as well
892 2
		call_integration_hook('integrate_modify_membergroup_settings', [&$config_vars]);
893
894
		return $config_vars;
895
	}
896 2
897
	/**
898 2
	 * Return the form settings for use in admin search
899
	 */
900
	public function settings_search()
901
	{
902
		return $this->_settings();
903
	}
904
}
905