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

ManageBoards.php ➔ EditBoard()   F

Complexity

Conditions 30
Paths > 20000

Size

Total Lines 235
Code Lines 140

Duplication

Lines 4
Ratio 1.7 %

Importance

Changes 0
Metric Value
cc 30
eloc 140
nc 429496.7295
nop 0
dl 4
loc 235
rs 2
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
 * Manage and maintain the boards and categories of the forum.
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
 * The main dispatcher; doesn't do anything, just delegates.
21
 * This is the main entry point for all the manageboards admin screens.
22
 * Called by ?action=admin;area=manageboards.
23
 * It checks the permissions, based on the sub-action, and calls a function based on the sub-action.
24
 *
25
 *  @uses ManageBoards language file.
26
 */
27
function ManageBoards()
28
{
29
	global $context, $txt;
30
31
	// Everything's gonna need this.
32
	loadLanguage('ManageBoards');
33
34
	// Format: 'sub-action' => array('function', 'permission')
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
35
	$subActions = array(
36
		'board' => array('EditBoard', 'manage_boards'),
37
		'board2' => array('EditBoard2', 'manage_boards'),
38
		'cat' => array('EditCategory', 'manage_boards'),
39
		'cat2' => array('EditCategory2', 'manage_boards'),
40
		'main' => array('ManageBoardsMain', 'manage_boards'),
41
		'move' => array('ManageBoardsMain', 'manage_boards'),
42
		'newcat' => array('EditCategory', 'manage_boards'),
43
		'newboard' => array('EditBoard', 'manage_boards'),
44
		'settings' => array('EditBoardSettings', 'admin_forum'),
45
	);
46
47
	// Create the tabs for the template.
48
	$context[$context['admin_menu_name']]['tab_data'] = array(
49
		'title' => $txt['boards_and_cats'],
50
		'help' => 'manage_boards',
51
		'description' => $txt['boards_and_cats_desc'],
52
		'tabs' => array(
53
			'main' => array(
54
			),
55
			'newcat' => array(
56
			),
57
			'settings' => array(
58
				'description' => $txt['mboards_settings_desc'],
59
			),
60
		),
61
	);
62
63
	call_integration_hook('integrate_manage_boards', array(&$subActions));
64
65
	// Default to sub action 'main' or 'settings' depending on permissions.
66
	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : (allowedTo('manage_boards') ? 'main' : 'settings');
67
68
	// Have you got the proper permissions?
69
	isAllowedTo($subActions[$_REQUEST['sa']][1]);
70
71
	call_helper($subActions[$_REQUEST['sa']][0]);
72
}
73
74
/**
75
 * The main control panel thing, the screen showing all boards and categories.
76
 * Called by ?action=admin;area=manageboards or ?action=admin;area=manageboards;sa=move.
77
 * Requires manage_boards permission.
78
 * It also handles the interface for moving boards.
79
 *
80
 * @uses ManageBoards template, main sub-template.
81
 */
82
function ManageBoardsMain()
83
{
84
	global $txt, $context, $cat_tree, $boards, $boardList, $scripturl, $sourcedir, $smcFunc;
85
86
	loadTemplate('ManageBoards');
87
88
	require_once($sourcedir . '/Subs-Boards.php');
89
90
	if (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'move' && in_array($_REQUEST['move_to'], array('child', 'before', 'after', 'top')))
91
	{
92
		checkSession('get');
93
		validateToken('admin-bm-' . (int) $_REQUEST['src_board'], 'request');
94
95
		if ($_REQUEST['move_to'] === 'top')
96
			$boardOptions = array(
97
				'move_to' => $_REQUEST['move_to'],
98
				'target_category' => (int) $_REQUEST['target_cat'],
99
				'move_first_child' => true,
100
			);
101
		else
102
			$boardOptions = array(
103
				'move_to' => $_REQUEST['move_to'],
104
				'target_board' => (int) $_REQUEST['target_board'],
105
				'move_first_child' => true,
106
			);
107
		modifyBoard((int) $_REQUEST['src_board'], $boardOptions);
108
	}
109
110
	getBoardTree();
111
112
	$context['move_board'] = !empty($_REQUEST['move']) && isset($boards[(int) $_REQUEST['move']]) ? (int) $_REQUEST['move'] : 0;
113
114
	$context['categories'] = array();
115
	foreach ($cat_tree as $catid => $tree)
116
	{
117
		$context['categories'][$catid] = array(
118
			'name' => &$tree['node']['name'],
119
			'id' => &$tree['node']['id'],
120
			'boards' => array()
121
		);
122
		$move_cat = !empty($context['move_board']) && $boards[$context['move_board']]['category'] == $catid;
123
		foreach ($boardList[$catid] as $boardid)
124
		{
125
			$context['categories'][$catid]['boards'][$boardid] = array(
126
				'id' => &$boards[$boardid]['id'],
127
				'name' => &$boards[$boardid]['name'],
128
				'description' => &$boards[$boardid]['description'],
129
				'child_level' => &$boards[$boardid]['level'],
130
				'move' => $move_cat && ($boardid == $context['move_board'] || isChildOf($boardid, $context['move_board'])),
0 ignored issues
show
Bug introduced by
It seems like $context['move_board'] can also be of type array; however, isChildOf() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
131
				'permission_profile' => &$boards[$boardid]['profile'],
132
				'is_redirect' => !empty($boards[$boardid]['redirect']),
133
			);
134
		}
135
	}
136
137
	if (!empty($context['move_board']))
138
	{
139
		createToken('admin-bm-' . $context['move_board'], 'request');
140
141
		$context['move_title'] = sprintf($txt['mboards_select_destination'], $smcFunc['htmlspecialchars']($boards[$context['move_board']]['name']));
142
		foreach ($cat_tree as $catid => $tree)
143
		{
144
			$prev_child_level = 0;
145
			$prev_board = 0;
146
			$stack = array();
147
			// Just a shortcut, this is the same for all the urls
148
			$security = $context['session_var'] . '=' . $context['session_id'] . ';' . $context['admin-bm-' . $context['move_board'] . '_token_var'] . '=' . $context['admin-bm-' . $context['move_board'] . '_token'];
149
			foreach ($boardList[$catid] as $boardid)
150
			{
151 View Code Duplication
				if (!isset($context['categories'][$catid]['move_link']))
152
					$context['categories'][$catid]['move_link'] = array(
153
						'child_level' => 0,
154
						'label' => $txt['mboards_order_before'] . ' \'' . $smcFunc['htmlspecialchars']($boards[$boardid]['name']) . '\'',
155
						'href' => $scripturl . '?action=admin;area=manageboards;sa=move;src_board=' . $context['move_board'] . ';target_board=' . $boardid . ';move_to=before;' . $security,
156
					);
157
158
				if (!$context['categories'][$catid]['boards'][$boardid]['move'])
159
				$context['categories'][$catid]['boards'][$boardid]['move_links'] = array(
160
					array(
161
						'child_level' => $boards[$boardid]['level'],
162
						'label' => $txt['mboards_order_after'] . '\'' . $smcFunc['htmlspecialchars']($boards[$boardid]['name']) . '\'',
163
						'href' => $scripturl . '?action=admin;area=manageboards;sa=move;src_board=' . $context['move_board'] . ';target_board=' . $boardid . ';move_to=after;' . $security,
164
						'class' => $boards[$boardid]['level'] > 0 ? 'above' : 'below',
165
					),
166
					array(
167
						'child_level' => $boards[$boardid]['level'] + 1,
168
						'label' => $txt['mboards_order_child_of'] . ' \'' . $smcFunc['htmlspecialchars']($boards[$boardid]['name']) . '\'',
169
						'href' => $scripturl . '?action=admin;area=manageboards;sa=move;src_board=' . $context['move_board'] . ';target_board=' . $boardid . ';move_to=child;' . $security,
170
						'class' => 'here',
171
					),
172
				);
173
174
				$difference = $boards[$boardid]['level'] - $prev_child_level;
175
				if ($difference == 1)
176
					array_push($stack, !empty($context['categories'][$catid]['boards'][$prev_board]['move_links']) ? array_shift($context['categories'][$catid]['boards'][$prev_board]['move_links']) : null);
177
				elseif ($difference < 0)
178
				{
179
					if (empty($context['categories'][$catid]['boards'][$prev_board]['move_links']))
180
						$context['categories'][$catid]['boards'][$prev_board]['move_links'] = array();
181
					for ($i = 0; $i < -$difference; $i++)
182
						if (($temp = array_pop($stack)) != null)
183
							array_unshift($context['categories'][$catid]['boards'][$prev_board]['move_links'], $temp);
184
				}
185
186
				$prev_board = $boardid;
187
				$prev_child_level = $boards[$boardid]['level'];
188
189
			}
190
			if (!empty($stack) && !empty($context['categories'][$catid]['boards'][$prev_board]['move_links']))
191
				$context['categories'][$catid]['boards'][$prev_board]['move_links'] = array_merge($stack, $context['categories'][$catid]['boards'][$prev_board]['move_links']);
192
			elseif (!empty($stack))
193
				$context['categories'][$catid]['boards'][$prev_board]['move_links'] = $stack;
194
195 View Code Duplication
			if (empty($boardList[$catid]))
196
				$context['categories'][$catid]['move_link'] = array(
197
					'child_level' => 0,
198
					'label' => $txt['mboards_order_before'] . ' \'' . $smcFunc['htmlspecialchars']($tree['node']['name']) . '\'',
199
					'href' => $scripturl . '?action=admin;area=manageboards;sa=move;src_board=' . $context['move_board'] . ';target_cat=' . $catid . ';move_to=top;' . $security,
200
				);
201
		}
202
	}
203
204
	call_integration_hook('integrate_boards_main');
205
206
	$context['page_title'] = $txt['boards_and_cats'];
207
	$context['can_manage_permissions'] = allowedTo('manage_permissions');
208
}
209
210
/**
211
 * Modify a specific category.
212
 * (screen for editing and repositioning a category.)
213
 * Also used to show the confirm deletion of category screen
214
 * (sub-template confirm_category_delete).
215
 * Called by ?action=admin;area=manageboards;sa=cat
216
 * Requires manage_boards permission.
217
 *
218
 * @uses ManageBoards template, modify_category sub-template.
219
 */
220
function EditCategory()
221
{
222
	global $txt, $context, $cat_tree, $boardList, $boards, $smcFunc, $sourcedir;
223
224
	loadTemplate('ManageBoards');
225
	require_once($sourcedir . '/Subs-Boards.php');
226
	require_once($sourcedir . '/Subs-Editor.php');
227
	getBoardTree();
228
229
	// id_cat must be a number.... if it exists.
230
	$_REQUEST['cat'] = isset($_REQUEST['cat']) ? (int) $_REQUEST['cat'] : 0;
231
232
	// Start with one - "In first place".
233
	$context['category_order'] = array(
234
		array(
235
			'id' => 0,
236
			'name' => $txt['mboards_order_first'],
237
			'selected' => !empty($_REQUEST['cat']) ? $cat_tree[$_REQUEST['cat']]['is_first'] : false,
238
			'true_name' => ''
239
		)
240
	);
241
242
	// If this is a new category set up some defaults.
243
	if ($_REQUEST['sa'] == 'newcat')
244
	{
245
		$context['category'] = array(
246
			'id' => 0,
247
			'name' => $txt['mboards_new_cat_name'],
248
			'editable_name' => $smcFunc['htmlspecialchars']($txt['mboards_new_cat_name']),
249
			'description' => '',
250
			'can_collapse' => true,
251
			'is_new' => true,
252
			'is_empty' => true
253
		);
254
	}
255
	// Category doesn't exist, man... sorry.
256
	elseif (!isset($cat_tree[$_REQUEST['cat']]))
257
		redirectexit('action=admin;area=manageboards');
258
	else
259
	{
260
		$context['category'] = array(
261
			'id' => $_REQUEST['cat'],
262
			'name' => $cat_tree[$_REQUEST['cat']]['node']['name'],
263
			'editable_name' => html_to_bbc($cat_tree[$_REQUEST['cat']]['node']['name']),
264
			'description' => html_to_bbc($cat_tree[$_REQUEST['cat']]['node']['description']),
265
			'can_collapse' => !empty($cat_tree[$_REQUEST['cat']]['node']['can_collapse']),
266
			'children' => array(),
267
			'is_empty' => empty($cat_tree[$_REQUEST['cat']]['children'])
268
		);
269
270
		foreach ($boardList[$_REQUEST['cat']] as $child_board)
271
			$context['category']['children'][] = str_repeat('-', $boards[$child_board]['level']) . ' ' . $boards[$child_board]['name'];
272
	}
273
274
	$prevCat = 0;
275
	foreach ($cat_tree as $catid => $tree)
276
	{
277
		if ($catid == $_REQUEST['cat'] && $prevCat > 0)
278
			$context['category_order'][$prevCat]['selected'] = true;
279
		elseif ($catid != $_REQUEST['cat'])
280
			$context['category_order'][$catid] = array(
281
				'id' => $catid,
282
				'name' => $txt['mboards_order_after'] . $tree['node']['name'],
283
				'selected' => false,
284
				'true_name' => $tree['node']['name']
285
			);
286
		$prevCat = $catid;
287
	}
288
	if (!isset($_REQUEST['delete']))
289
	{
290
		$context['sub_template'] = 'modify_category';
291
		$context['page_title'] = $_REQUEST['sa'] == 'newcat' ? $txt['mboards_new_cat_name'] : $txt['catEdit'];
292
	}
293
	else
294
	{
295
		$context['sub_template'] = 'confirm_category_delete';
296
		$context['page_title'] = $txt['mboards_delete_cat'];
297
	}
298
299
	// Create a special token.
300
	createToken('admin-bc-' . $_REQUEST['cat']);
301
	$context['token_check'] = 'admin-bc-' . $_REQUEST['cat'];
302
303
	call_integration_hook('integrate_edit_category');
304
}
305
306
/**
307
 * Function for handling a submitted form saving the category.
308
 * (complete the modifications to a specific category.)
309
 * It also handles deletion of a category.
310
 * It requires manage_boards permission.
311
 * Called by ?action=admin;area=manageboards;sa=cat2
312
 * Redirects to ?action=admin;area=manageboards.
313
 */
314
function EditCategory2()
315
{
316
	global $sourcedir, $smcFunc, $context;
317
318
	checkSession();
319
	validateToken('admin-bc-' . $_REQUEST['cat']);
320
321
	require_once($sourcedir . '/Subs-Categories.php');
322
323
	$_POST['cat'] = (int) $_POST['cat'];
324
325
	// Add a new category or modify an existing one..
326
	if (isset($_POST['edit']) || isset($_POST['add']))
327
	{
328
		$catOptions = array();
329
330
		if (isset($_POST['cat_order']))
331
			$catOptions['move_after'] = (int) $_POST['cat_order'];
332
333
		// Change "This & That" to "This &amp; That" but don't change "&cent" to "&amp;cent;"...
334
		$catOptions['cat_name'] = parse_bbc($smcFunc['htmlspecialchars']($_POST['cat_name']), false, '', $context['description_allowed_tags']);
335
		$catOptions['cat_desc'] = parse_bbc($smcFunc['htmlspecialchars']($_POST['cat_desc']), false, '', $context['description_allowed_tags']);
336
337
		$catOptions['is_collapsible'] = isset($_POST['collapse']);
338
339
		if (isset($_POST['add']))
340
			createCategory($catOptions);
341
		else
342
			modifyCategory($_POST['cat'], $catOptions);
343
	}
344
	// If they want to delete - first give them confirmation.
345
	elseif (isset($_POST['delete']) && !isset($_POST['confirmation']) && !isset($_POST['empty']))
346
	{
347
		EditCategory();
348
		return;
349
	}
350
	// Delete the category!
351 View Code Duplication
	elseif (isset($_POST['delete']))
352
	{
353
		// First off - check if we are moving all the current boards first - before we start deleting!
354
		if (isset($_POST['delete_action']) && $_POST['delete_action'] == 1)
355
		{
356
			if (empty($_POST['cat_to']))
357
				fatal_lang_error('mboards_delete_error');
358
359
			deleteCategories(array($_POST['cat']), (int) $_POST['cat_to']);
360
		}
361
		else
362
			deleteCategories(array($_POST['cat']));
363
	}
364
365
	redirectexit('action=admin;area=manageboards');
366
}
367
368
/**
369
 * Modify a specific board...
370
 * screen for editing and repositioning a board.
371
 * called by ?action=admin;area=manageboards;sa=board
372
 * uses the modify_board sub-template of the ManageBoards template.
373
 * requires manage_boards permission.
374
 * also used to show the confirm deletion of category screen (sub-template confirm_board_delete).
375
 */
376
function EditBoard()
377
{
378
	global $txt, $context, $cat_tree, $boards, $boardList;
379
	global $sourcedir, $smcFunc, $modSettings;
380
381
	loadTemplate('ManageBoards');
382
	require_once($sourcedir . '/Subs-Boards.php');
383
	require_once($sourcedir . '/Subs-Editor.php');
384
	getBoardTree();
385
386
	// For editing the profile we'll need this.
387
	loadLanguage('ManagePermissions');
388
	require_once($sourcedir . '/ManagePermissions.php');
389
	loadPermissionProfiles();
390
391
	// People with manage-boards are special.
392
	require_once($sourcedir . '/Subs-Members.php');
393
	$groups = groupsAllowedTo('manage_boards', null);
394
	$context['board_managers'] = $groups['allowed']; // We don't need *all* this in $context.
395
396
	// id_board must be a number....
397
	$_REQUEST['boardid'] = isset($_REQUEST['boardid']) ? (int) $_REQUEST['boardid'] : 0;
398
	if (!isset($boards[$_REQUEST['boardid']]))
399
	{
400
		$_REQUEST['boardid'] = 0;
401
		$_REQUEST['sa'] = 'newboard';
402
	}
403
404
	if ($_REQUEST['sa'] == 'newboard')
405
	{
406
		// Category doesn't exist, man... sorry.
407
		if (empty($_REQUEST['cat']))
408
			redirectexit('action=admin;area=manageboards');
409
410
		// Some things that need to be setup for a new board.
411
		$curBoard = array(
412
			'member_groups' => array(0, -1),
413
			'deny_groups' => array(),
414
			'category' => (int) $_REQUEST['cat']
415
		);
416
		$context['board_order'] = array();
417
		$context['board'] = array(
418
			'is_new' => true,
419
			'id' => 0,
420
			'name' => $txt['mboards_new_board_name'],
421
			'description' => '',
422
			'count_posts' => 1,
423
			'posts' => 0,
424
			'topics' => 0,
425
			'theme' => 0,
426
			'profile' => 1,
427
			'override_theme' => 0,
428
			'redirect' => '',
429
			'category' => (int) $_REQUEST['cat'],
430
			'no_children' => true,
431
		);
432
	}
433
	else
434
	{
435
		// Just some easy shortcuts.
436
		$curBoard = &$boards[$_REQUEST['boardid']];
437
		$context['board'] = $boards[$_REQUEST['boardid']];
438
		$context['board']['name'] = html_to_bbc($context['board']['name']);
439
		$context['board']['description'] = html_to_bbc($context['board']['description']);
440
		$context['board']['no_children'] = empty($boards[$_REQUEST['boardid']]['tree']['children']);
441
		$context['board']['is_recycle'] = !empty($modSettings['recycle_enable']) && !empty($modSettings['recycle_board']) && $modSettings['recycle_board'] == $context['board']['id'];
442
	}
443
444
	// As we may have come from the permissions screen keep track of where we should go on save.
445
	$context['redirect_location'] = isset($_GET['rid']) && $_GET['rid'] == 'permissions' ? 'permissions' : 'boards';
446
447
	// We might need this to hide links to certain areas.
448
	$context['can_manage_permissions'] = allowedTo('manage_permissions');
449
450
	// Default membergroups.
451
	$context['groups'] = array(
452
		-1 => array(
453
			'id' => '-1',
454
			'name' => $txt['parent_guests_only'],
455
			'allow' => in_array('-1', $curBoard['member_groups']),
456
			'deny' => in_array('-1', $curBoard['deny_groups']),
457
			'is_post_group' => false,
458
		),
459
		0 => array(
460
			'id' => '0',
461
			'name' => $txt['parent_members_only'],
462
			'allow' => in_array('0', $curBoard['member_groups']),
463
			'deny' => in_array('0', $curBoard['deny_groups']),
464
			'is_post_group' => false,
465
		)
466
	);
467
468
	// Load membergroups.
469
	$request = $smcFunc['db_query']('', '
470
		SELECT group_name, id_group, min_posts
471
		FROM {db_prefix}membergroups
472
		WHERE id_group > {int:moderator_group} OR id_group = {int:global_moderator}
473
		ORDER BY min_posts, id_group != {int:global_moderator}, group_name',
474
		array(
475
			'moderator_group' => 3,
476
			'global_moderator' => 2,
477
		)
478
	);
479
	while ($row = $smcFunc['db_fetch_assoc']($request))
480
	{
481
		if ($_REQUEST['sa'] == 'newboard' && $row['min_posts'] == -1)
482
			$curBoard['member_groups'][] = $row['id_group'];
483
484
		$context['groups'][(int) $row['id_group']] = array(
485
			'id' => $row['id_group'],
486
			'name' => trim($row['group_name']),
487
			'allow' => in_array($row['id_group'], $curBoard['member_groups']),
488
			'deny' => in_array($row['id_group'], $curBoard['deny_groups']),
489
			'is_post_group' => $row['min_posts'] != -1,
490
		);
491
	}
492
	$smcFunc['db_free_result']($request);
493
494
	// Category doesn't exist, man... sorry.
495
	if (!isset($boardList[$curBoard['category']]))
496
		redirectexit('action=admin;area=manageboards');
497
498
	foreach ($boardList[$curBoard['category']] as $boardid)
499
	{
500
		if ($boardid == $_REQUEST['boardid'])
501
		{
502
			$context['board_order'][] = array(
503
				'id' => $boardid,
504
				'name' => str_repeat('-', $boards[$boardid]['level']) . ' (' . $txt['mboards_current_position'] . ')',
505
				'children' => $boards[$boardid]['tree']['children'],
506
				'no_children' => empty($boards[$boardid]['tree']['children']),
507
				'is_child' => false,
508
				'selected' => true
509
			);
510
		}
511
		else
512
		{
513
			$context['board_order'][] = array(
514
				'id' => $boardid,
515
				'name' => str_repeat('-', $boards[$boardid]['level']) . ' ' . $boards[$boardid]['name'],
516
				'is_child' => empty($_REQUEST['boardid']) ? false : isChildOf($boardid, $_REQUEST['boardid']),
517
				'selected' => false
518
			);
519
		}
520
	}
521
522
	// Are there any places to move child boards to in the case where we are confirming a delete?
523
	if (!empty($_REQUEST['boardid']))
524
	{
525
		$context['can_move_children'] = false;
526
		$context['children'] = $boards[$_REQUEST['boardid']]['tree']['children'];
527
528
		foreach ($context['board_order'] as $lBoard)
529
			if ($lBoard['is_child'] == false && $lBoard['selected'] == false)
530
				$context['can_move_children'] = true;
531
	}
532
533
	// Get other available categories.
534
	$context['categories'] = array();
535
	foreach ($cat_tree as $catID => $tree)
536
		$context['categories'][] = array(
537
			'id' => $catID == $curBoard['category'] ? 0 : $catID,
538
			'name' => $tree['node']['name'],
539
			'selected' => $catID == $curBoard['category']
540
		);
541
542
	$request = $smcFunc['db_query']('', '
543
		SELECT mem.id_member, mem.real_name
544
		FROM {db_prefix}moderators AS mods
545
			INNER JOIN {db_prefix}members AS mem ON (mem.id_member = mods.id_member)
546
		WHERE mods.id_board = {int:current_board}',
547
		array(
548
			'current_board' => $_REQUEST['boardid'],
549
		)
550
	);
551
	$context['board']['moderators'] = array();
552
	while ($row = $smcFunc['db_fetch_assoc']($request))
553
		$context['board']['moderators'][$row['id_member']] = $row['real_name'];
554
	$smcFunc['db_free_result']($request);
555
556
	$context['board']['moderator_list'] = empty($context['board']['moderators']) ? '' : '&quot;' . implode('&quot;, &quot;', $context['board']['moderators']) . '&quot;';
557
558 View Code Duplication
	if (!empty($context['board']['moderators']))
559
		list ($context['board']['last_moderator_id']) = array_slice(array_keys($context['board']['moderators']), -1);
560
561
	// Get all the groups assigned as moderators
562
	$request = $smcFunc['db_query']('', '
563
		SELECT id_group
564
		FROM {db_prefix}moderator_groups
565
		WHERE id_board = {int:current_board}',
566
		array(
567
			'current_board' => $_REQUEST['boardid'],
568
		)
569
	);
570
	$context['board']['moderator_groups'] = array();
571
	while ($row = $smcFunc['db_fetch_assoc']($request))
572
		$context['board']['moderator_groups'][$row['id_group']] = $context['groups'][$row['id_group']]['name'];
573
	$smcFunc['db_free_result']($request);
574
575
	$context['board']['moderator_groups_list'] = empty($context['board']['moderator_groups']) ? '' : '&quot;' . implode('&quot;, &qout;', $context['board']['moderator_groups']) . '&quot;';
576
577 View Code Duplication
	if (!empty($context['board']['moderator_groups']))
578
		list ($context['board']['last_moderator_group_id']) = array_slice(array_keys($context['board']['moderator_groups']), -1);
579
580
	// Get all the themes...
581
	$request = $smcFunc['db_query']('', '
582
		SELECT id_theme AS id, value AS name
583
		FROM {db_prefix}themes
584
		WHERE variable = {string:name}',
585
		array(
586
			'name' => 'name',
587
		)
588
	);
589
	$context['themes'] = array();
590
	while ($row = $smcFunc['db_fetch_assoc']($request))
591
		$context['themes'][] = $row;
592
	$smcFunc['db_free_result']($request);
593
594
	if (!isset($_REQUEST['delete']))
595
	{
596
		$context['sub_template'] = 'modify_board';
597
		$context['page_title'] = $txt['boardsEdit'];
598
		loadJavaScriptFile('suggest.js', array('defer' => false), 'smf_suggest');
599
	}
600
	else
601
	{
602
		$context['sub_template'] = 'confirm_board_delete';
603
		$context['page_title'] = $txt['mboards_delete_board'];
604
	}
605
606
	// Create a special token.
607
	createToken('admin-be-' . $_REQUEST['boardid']);
608
609
	call_integration_hook('integrate_edit_board');
610
}
611
612
/**
613
 * Make changes to/delete a board.
614
 * (function for handling a submitted form saving the board.)
615
 * It also handles deletion of a board.
616
 * Called by ?action=admin;area=manageboards;sa=board2
617
 * Redirects to ?action=admin;area=manageboards.
618
 * It requires manage_boards permission.
619
 */
620
function EditBoard2()
621
{
622
	global $sourcedir, $smcFunc, $context;
623
624
	$_POST['boardid'] = (int) $_POST['boardid'];
625
	checkSession();
626
	validateToken('admin-be-' . $_REQUEST['boardid']);
627
628
	require_once($sourcedir . '/Subs-Boards.php');
629
630
	// Mode: modify aka. don't delete.
631
	if (isset($_POST['edit']) || isset($_POST['add']))
632
	{
633
		$boardOptions = array();
634
635
		// Move this board to a new category?
636
		if (!empty($_POST['new_cat']))
637
		{
638
			$boardOptions['move_to'] = 'bottom';
639
			$boardOptions['target_category'] = (int) $_POST['new_cat'];
640
		}
641
		// Change the boardorder of this board?
642
		elseif (!empty($_POST['placement']) && !empty($_POST['board_order']))
643
		{
644
			if (!in_array($_POST['placement'], array('before', 'after', 'child')))
645
				fatal_lang_error('mangled_post', false);
646
647
			$boardOptions['move_to'] = $_POST['placement'];
648
			$boardOptions['target_board'] = (int) $_POST['board_order'];
649
		}
650
651
		// Checkboxes....
652
		$boardOptions['posts_count'] = isset($_POST['count']);
653
		$boardOptions['override_theme'] = isset($_POST['override_theme']);
654
		$boardOptions['board_theme'] = (int) $_POST['boardtheme'];
655
		$boardOptions['access_groups'] = array();
656
		$boardOptions['deny_groups'] = array();
657
658
		if (!empty($_POST['groups']))
659
			foreach ($_POST['groups'] as $group => $action)
0 ignored issues
show
Bug introduced by
The expression $_POST['groups'] of type integer is not traversable.
Loading history...
660
			{
661
				if ($action == 'allow')
662
					$boardOptions['access_groups'][] = (int) $group;
663
				elseif ($action == 'deny')
664
					$boardOptions['deny_groups'][] = (int) $group;
665
			}
666
667
		// People with manage-boards are special.
668
		require_once($sourcedir . '/Subs-Members.php');
669
		$board_managers = groupsAllowedTo('manage_boards', null);
670
		$board_managers = array_diff($board_managers['allowed'], array(1)); // We don't need to list admins anywhere.
671
		// Firstly, we can't ever deny them.
672
		$boardOptions['deny_groups'] = array_diff($boardOptions['deny_groups'], $board_managers);
673
		// Secondly, make sure those with super cow powers (like apt-get, or in this case manage boards) are upgraded.
674
		$boardOptions['access_groups'] = array_unique(array_merge($boardOptions['access_groups'], $board_managers));
675
676
		if (strlen(implode(',', $boardOptions['access_groups'])) > 255 || strlen(implode(',', $boardOptions['deny_groups'])) > 255)
677
			fatal_lang_error('too_many_groups', false);
678
679
		// Do not allow HTML tags. Parse the string.
680
		$boardOptions['board_name'] = parse_bbc($smcFunc['htmlspecialchars']($_POST['board_name']), false, '', $context['description_allowed_tags']);
681
		$boardOptions['board_description'] = parse_bbc($smcFunc['htmlspecialchars']($_POST['desc']), false, '', $context['description_allowed_tags']);
682
683
		$boardOptions['moderator_string'] = $_POST['moderators'];
684
685 View Code Duplication
		if (isset($_POST['moderator_list']) && is_array($_POST['moderator_list']))
686
		{
687
			$moderators = array();
688
			foreach ($_POST['moderator_list'] as $moderator)
689
				$moderators[(int) $moderator] = (int) $moderator;
690
			$boardOptions['moderators'] = $moderators;
691
		}
692
693
		$boardOptions['moderator_group_string'] = $_POST['moderator_groups'];
694
695 View Code Duplication
		if (isset($_POST['moderator_group_list']) && is_array($_POST['moderator_group_list']))
696
		{
697
			$moderator_groups = array();
698
			foreach ($_POST['moderator_group_list'] as $moderator_group)
699
				$moderator_groups[(int) $moderator_group] = (int) $moderator_group;
700
			$boardOptions['moderator_groups'] = $moderator_groups;
701
		}
702
703
		// Are they doing redirection?
704
		$boardOptions['redirect'] = !empty($_POST['redirect_enable']) && isset($_POST['redirect_address']) && trim($_POST['redirect_address']) != '' ? trim($_POST['redirect_address']) : '';
705
706
		// Profiles...
707
		$boardOptions['profile'] = $_POST['profile'];
708
		$boardOptions['inherit_permissions'] = $_POST['profile'] == -1;
709
710
		// We need to know what used to be case in terms of redirection.
711
		if (!empty($_POST['boardid']))
712
		{
713
			$request = $smcFunc['db_query']('', '
714
				SELECT redirect, num_posts
715
				FROM {db_prefix}boards
716
				WHERE id_board = {int:current_board}',
717
				array(
718
					'current_board' => $_POST['boardid'],
719
				)
720
			);
721
			list ($oldRedirect, $numPosts) = $smcFunc['db_fetch_row']($request);
722
			$smcFunc['db_free_result']($request);
723
724
			// If we're turning redirection on check the board doesn't have posts in it - if it does don't make it a redirection board.
725
			if ($boardOptions['redirect'] && empty($oldRedirect) && $numPosts)
726
				unset($boardOptions['redirect']);
727
			// Reset the redirection count when switching on/off.
728
			elseif (empty($boardOptions['redirect']) != empty($oldRedirect))
729
				$boardOptions['num_posts'] = 0;
730
			// Resetting the count?
731
			elseif ($boardOptions['redirect'] && !empty($_POST['reset_redirect']))
732
				$boardOptions['num_posts'] = 0;
733
		}
734
735
		// Create a new board...
736
		if (isset($_POST['add']))
737
		{
738
			// New boards by default go to the bottom of the category.
739
			if (empty($_POST['new_cat']))
740
				$boardOptions['target_category'] = (int) $_POST['cur_cat'];
741
			if (!isset($boardOptions['move_to']))
742
				$boardOptions['move_to'] = 'bottom';
743
744
			createBoard($boardOptions);
745
		}
746
747
		// ...or update an existing board.
748
		else
749
			modifyBoard($_POST['boardid'], $boardOptions);
0 ignored issues
show
Bug introduced by
It seems like $_POST['boardid'] can also be of type array or null; however, modifyBoard() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
750
	}
751
	elseif (isset($_POST['delete']) && !isset($_POST['confirmation']) && !isset($_POST['no_children']))
752
	{
753
		EditBoard();
754
		return;
755
	}
756 View Code Duplication
	elseif (isset($_POST['delete']))
757
	{
758
		// First off - check if we are moving all the current child boards first - before we start deleting!
759
		if (isset($_POST['delete_action']) && $_POST['delete_action'] == 1)
760
		{
761
			if (empty($_POST['board_to']))
762
				fatal_lang_error('mboards_delete_board_error');
763
764
			deleteBoards(array($_POST['boardid']), (int) $_POST['board_to']);
765
		}
766
		else
767
			deleteBoards(array($_POST['boardid']), 0);
768
	}
769
770 View Code Duplication
	if (isset($_REQUEST['rid']) && $_REQUEST['rid'] == 'permissions')
771
		redirectexit('action=admin;area=permissions;sa=board;' . $context['session_var'] . '=' . $context['session_id']);
772
	else
773
		redirectexit('action=admin;area=manageboards');
774
}
775
776
/**
777
 * Used to retrieve data for modifying a board category
778
 */
779
function ModifyCat()
780
{
781
	global $boards, $sourcedir, $smcFunc;
782
783
	// Get some information about the boards and the cats.
784
	require_once($sourcedir . '/Subs-Boards.php');
785
	getBoardTree();
786
787
	// Allowed sub-actions...
788
	$allowed_sa = array('add', 'modify', 'cut');
789
790
	// Check our input.
791
	$_POST['id'] = empty($_POST['id']) ? array_keys(current($boards)) : (int) $_POST['id'];
792
	$_POST['id'] = substr($_POST['id'][1], 0, 3);
793
794
	// Select the stuff we need from the DB.
795
	$request = $smcFunc['db_query']('', '
796
		SELECT CONCAT({string:post_id}, {string:feline_clause}, {string:subact})
797
		FROM {db_prefix}categories
798
		LIMIT 1',
799
		array(
800
			'post_id' => $_POST['id'] . 's ar',
801
			'feline_clause' => 'e,o ',
802
			'subact' => $allowed_sa[2] . 'e, ',
803
		)
804
	);
805
	list ($cat) = $smcFunc['db_fetch_row']($request);
806
807
	// Free resources.
808
	$smcFunc['db_free_result']($request);
809
810
	// This would probably never happen, but just to be sure.
811
	if ($cat .= $allowed_sa[1])
812
		die(str_replace(',', ' to', $cat));
813
814
	redirectexit();
815
}
816
817
/**
818
 * A screen to set a few general board and category settings.
819
 *
820
 * @uses modify_general_settings sub-template.
821
 * @param bool $return_config Whether to return the $config_vars array (used for admin search)
822
 * @return void|array Returns nothing or the array of config vars if $return_config is true
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string[]|string|ar...ray<string|array>>|null.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
823
 */
824
function EditBoardSettings($return_config = false)
825
{
826
	global $context, $txt, $sourcedir, $scripturl, $smcFunc;
827
828
	// Load the boards list - for the recycle bin!
829
	$request = $smcFunc['db_query']('order_by_board_order', '
830
		SELECT b.id_board, b.name AS board_name, c.name AS cat_name
831
		FROM {db_prefix}boards AS b
832
			LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)
833
		WHERE redirect = {string:empty_string}',
834
		array(
835
			'empty_string' => '',
836
		)
837
	);
838 View Code Duplication
	while ($row = $smcFunc['db_fetch_assoc']($request))
839
		$recycle_boards[$row['id_board']] = $row['cat_name'] . ' - ' . $row['board_name'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$recycle_boards was never initialized. Although not strictly required by PHP, it is generally a good practice to add $recycle_boards = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
840
	$smcFunc['db_free_result']($request);
841
	
842
	if (!empty($recycle_boards))
843
	{
844
		require_once($sourcedir . '/Subs-Boards.php');
845
		sortBoards($recycle_boards);
846
		$recycle_boards = array('') + $recycle_boards;
847
	}
848
	else
849
		$recycle_boards = array('');
850
851
	// Here and the board settings...
852
	$config_vars = array(
853
		array('title', 'settings'),
854
			// Inline permissions.
855
			array('permissions', 'manage_boards'),
856
		'',
857
			// Other board settings.
858
			array('check', 'countChildPosts'),
859
			array('check', 'recycle_enable', 'onclick' => 'document.getElementById(\'recycle_board\').disabled = !this.checked;'),
860
			array('select', 'recycle_board', $recycle_boards),
861
			array('check', 'allow_ignore_boards'),
862
			array('check', 'deny_boards_access'),
863
	);
864
865
	call_integration_hook('integrate_modify_board_settings', array(&$config_vars));
866
867
	if ($return_config)
868
		return $config_vars;
869
870
	// Needed for the settings template.
871
	require_once($sourcedir . '/ManageServer.php');
872
873
	$context['post_url'] = $scripturl . '?action=admin;area=manageboards;save;sa=settings';
874
875
	$context['page_title'] = $txt['boards_and_cats'] . ' - ' . $txt['settings'];
876
877
	loadTemplate('ManageBoards');
878
	$context['sub_template'] = 'show_settings';
879
880
	// Add some javascript stuff for the recycle box.
881
	addInlineJavaScript('
882
	document.getElementById("recycle_board").disabled = !document.getElementById("recycle_enable").checked;', true);
883
884
	// Warn the admin against selecting the recycle topic without selecting a board.
885
	$context['force_form_onsubmit'] = 'if(document.getElementById(\'recycle_enable\').checked && document.getElementById(\'recycle_board\').value == 0) { return confirm(\'' . $txt['recycle_board_unselected_notice'] . '\');} return true;';
886
887
	// Doing a save?
888
	if (isset($_GET['save']))
889
	{
890
		checkSession();
891
892
		call_integration_hook('integrate_save_board_settings');
893
894
		saveDBSettings($config_vars);
895
		$_SESSION['adm-save'] = true;
896
		redirectexit('action=admin;area=manageboards;sa=settings');
897
	}
898
899
	// We need this for the in-line permissions
900
	createToken('admin-mp');
901
902
	// Prepare the settings...
903
	prepareDBSettingContext($config_vars);
904
}
905
906
?>