ManageBoards::action_main()   D
last analyzed

Complexity

Conditions 25
Paths 108

Size

Total Lines 163
Code Lines 91

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 650

Importance

Changes 0
Metric Value
cc 25
eloc 91
c 0
b 0
f 0
nc 108
nop 0
dl 0
loc 163
ccs 0
cts 78
cp 0
crap 650
rs 4.1

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
 * @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 dev
14
 *
15
 */
16
17
namespace ElkArte\AdminController;
18
19
use BBC\ParserWrapper;
20
use ElkArte\AbstractController;
21
use ElkArte\Action;
22
use ElkArte\BoardsTree;
23
use ElkArte\Converters\Html2BBC;
24
use ElkArte\Exceptions\Exception;
25
use ElkArte\Helper\Util;
26
use ElkArte\Languages\Txt;
27
use ElkArte\SettingsForm\SettingsForm;
28
29
/**
30
 * This class controls execution for actions in the manage boards area
31
 * of the admin panel.
32
 *
33
 * @package Boards
34
 */
35
class ManageBoards extends AbstractController
36
{
37
	/** @var int Category being worked on */
38
	public $cat;
39
40
	/** @var int Current board id being modified */
41
	public $boardid;
42
43
	/**
44
	 * The main dispatcher; delegates.
45
	 *
46
	 * What it does:
47
	 *
48
	 * - This is the main entry point for all the manageboards admin screens.
49
	 * - Called by ?action=admin;area=manageboards.
50
	 * - It checks the permissions, based on the sub-action, and calls a function based on the sub-action.
51
	 *
52
	 * @uses ManageBoards language file.
53
	 */
54
	public function action_index()
55
	{
56
		global $context;
57
58
		// Everything's gonna need this.
59
		Txt::load('ManageBoards');
60
61
		// Format: 'sub-action' => array('controller', 'function', 'permission'=>'need')
62
		$subActions = array(
63
			'board' => array(
64
				'controller' => $this,
65
				'function' => 'action_board',
66
				'permission' => 'manage_boards'),
67
			'board2' => array(
68
				'controller' => $this,
69
				'function' => 'action_board2',
70
				'permission' => 'manage_boards'),
71
			'cat' => array(
72
				'controller' => $this,
73
				'function' => 'action_cat',
74
				'permission' => 'manage_boards'),
75
			'cat2' => array(
76
				'controller' => $this,
77
				'function' => 'action_cat2',
78
				'permission' => 'manage_boards'),
79
			'main' => array(
80
				'controller' => $this,
81
				'function' => 'action_main',
82
				'permission' => 'manage_boards'),
83
			'move' => array(
84
				'controller' => $this,
85
				'function' => 'action_main',
86
				'permission' => 'manage_boards'),
87
			'newcat' => array(
88
				'controller' => $this,
89
				'function' => 'action_cat',
90
				'permission' => 'manage_boards'),
91
			'newboard' => array(
92
				'controller' => $this,
93
				'function' => 'action_board',
94
				'permission' => 'manage_boards'),
95
			'settings' => array(
96
				'controller' => $this,
97
				'function' => 'action_boardSettings_display',
98
				'permission' => 'admin_forum'),
99
		);
100
101
		// You way will end here if you don't have permission.
102
		$action = new Action('manage_boards');
103
104
		// Default to sub-action 'main' or 'settings' depending on permissions.
105
		$subAction = $action->initialize($subActions, allowedTo('manage_boards') ? 'main' : 'settings');
106
		$context['sub_action'] = $subAction;
107
108
		// Create the tabs for the template.
109
		$context[$context['admin_menu_name']]['object']->prepareTabData([
110
			'title' => 'boards_and_cats',
111
			'help' => 'manage_boards',
112
			'description' => 'boards_and_cats_desc',
113
			'prefix' => 'mboards',
114
		]);
115
116
		$action->dispatch($subAction);
117
	}
118
119
	/**
120
	 * The main control panel thing, the screen showing all boards and categories.
121
	 *
122
	 * What it does:
123
	 *
124
	 * - Called by ?action=admin;area=manageboards or ?action=admin;area=manageboards;sa=move.
125
	 * - Requires manage_boards permission.
126
	 * - It also handles the interface for moving boards.
127
	 *
128
	 * @event integrate_boards_main Used to access global board arrays before the template
129
	 * @uses ManageBoards template, main sub-template.
130
	 */
131
	public function action_main()
132
	{
133
		global $txt, $context;
134
135
		theme()->getTemplates()->load('ManageBoards');
136
137
		require_once(SUBSDIR . '/Boards.subs.php');
138
139
		// Moving a board, child of, before, after, top
140
		if ($this->_req->compareQuery('sa', 'move', 'trim|strval')
141
			&& in_array($this->_req->query->move_to, array('child', 'before', 'after', 'top')))
142
		{
143
			checkSession('get');
144
			validateToken('admin-bm-' . (int) $this->_req->query->src_board, 'request');
145
146
			// Top is special, its the top!
147
			if ($this->_req->query->move_to === 'top')
148
			{
149
				$boardOptions = array(
150
					'move_to' => $this->_req->query->move_to,
151
					'target_category' => $this->_req->getQuery('target_cat', 'intval', 0),
152
					'move_first_child' => true,
153
				);
154
			}
155
			// Moving it after another board
156
			else
157
			{
158
				$boardOptions = array(
159
					'move_to' => $this->_req->query->move_to,
160
					'target_board' => $this->_req->getQuery('target_board', 'intval', 0),
161
					'move_first_child' => true,
162
				);
163
			}
164
165
			// Use modifyBoard to perform the action
166
			modifyBoard((int) $this->_req->query->src_board, $boardOptions);
167
			redirectexit('action=admin;area=manageboards');
168
		}
169
170
		$boardTree = new BoardsTree(database());
171
		$boards = $boardTree->getBoards();
172
		$boardList = $boardTree->getBoardList();
173
174
		createToken('admin-sort');
175
		$move_board = $this->_req->getQuery('move', 'intval', 0);
176
		$context['move_board'] = isset($boards[$move_board]) ? $move_board : 0;
177
178
		$bbc_parser = ParserWrapper::instance();
179
		$cat_tree = $boardTree->getCategories();
180
181
		$context['categories'] = array();
182
		foreach ($cat_tree as $catid => $tree)
183
		{
184
			$context['categories'][$catid] = array(
185
				'name' => $tree['node']['name'],
186
				'id' => $tree['node']['id'],
187
				'boards' => array()
188
			);
189
			$move_cat = !empty($context['move_board']) && $boards[$context['move_board']]['category'] === $catid;
190
			foreach ($boardList[$catid] as $boardid)
191
			{
192
				$boards[$boardid]['description'] = $bbc_parser->parseBoard($boards[$boardid]['description']);
193
				$context['categories'][$catid]['boards'][$boardid] = array(
194
					'id' => $boards[$boardid]['id'],
195
					'name' => $boards[$boardid]['name'],
196
					'description' => $boards[$boardid]['description'],
197
					'child_level' => $boards[$boardid]['level'],
198
					'move' => $move_cat && ($boardid === $context['move_board'] || $boardTree->isChildOf($boardid, (int) $context['move_board'])),
199
					'permission_profile' => $boards[$boardid]['profile'],
200
				);
201
			}
202
		}
203
204
		if (!empty($context['move_board']))
205
		{
206
			createToken('admin-bm-' . $context['move_board'], 'request');
207
208
			$context['move_title'] = sprintf($txt['mboards_select_destination'], htmlspecialchars($boards[$context['move_board']]['name'], ENT_COMPAT, 'UTF-8'));
209
			foreach ($cat_tree as $catid => $tree)
210
			{
211
				$prev_child_level = 0;
212
				$prev_board = 0;
213
				$stack = array();
214
215
				// Just a shortcut, this is the same for all the urls
216
				$security_token = $context['admin-bm-' . $context['move_board'] . '_token_var'] . '=' . $context['admin-bm-' . $context['move_board'] . '_token'];
217
				foreach ($boardList[$catid] as $boardid)
218
				{
219
					if (!isset($context['categories'][$catid]['move_link']))
220
					{
221
						$context['categories'][$catid]['move_link'] = array(
222
							'child_level' => 0,
223
							'label' => $txt['mboards_order_before'] . " '" . htmlspecialchars($boards[$boardid]['name'], ENT_COMPAT, 'UTF-8') . "'",
224
							'href' => getUrl('admin', ['action' => 'admin', 'area' => 'manageboards', 'sa' => 'move', 'src_board' => $context['move_board'], 'target_board' => $boardid, 'move_to' => 'before', '{session_data}', $security_token]),
225
						);
226
					}
227
228
					if (!$context['categories'][$catid]['boards'][$boardid]['move'])
229
					{
230
						$context['categories'][$catid]['boards'][$boardid]['move_links'] = array(
231
							array(
232
								'child_level' => $boards[$boardid]['level'],
233
								'label' => $txt['mboards_order_after'] . "'" . htmlspecialchars($boards[$boardid]['name'], ENT_COMPAT, 'UTF-8') . "'",
234
								'href' => getUrl('admin', ['action' => 'admin', 'area' => 'manageboards', 'sa' => 'move', 'src_board' => $context['move_board'], 'target_board' => $boardid, 'move_to' => 'after', '{session_data}', $security_token]),
235
							),
236
							array(
237
								'child_level' => $boards[$boardid]['level'] + 1,
238
								'label' => $txt['mboards_order_child_of'] . " '" . htmlspecialchars($boards[$boardid]['name'], ENT_COMPAT, 'UTF-8') . "'",
239
								'href' => getUrl('admin', ['action' => 'admin', 'area' => 'manageboards', 'sa' => 'move', 'src_board' => $context['move_board'], 'target_board' => $boardid, 'move_to' => 'child', '{session_data}', $security_token]),
240
							),
241
						);
242
					}
243
244
					$difference = $boards[$boardid]['level'] - $prev_child_level;
245
					if ($difference === 1)
246
					{
247
						$stack[] = empty($context['categories'][$catid]['boards'][$prev_board]['move_links']) ? null : array_shift($context['categories'][$catid]['boards'][$prev_board]['move_links']);
248
					}
249
					elseif ($difference < 0)
250
					{
251
						if (empty($context['categories'][$catid]['boards'][$prev_board]['move_links']))
252
						{
253
							$context['categories'][$catid]['boards'][$prev_board]['move_links'] = array();
254
						}
255
256
						for ($i = 0; $i < -$difference; $i++)
257
						{
258
							if (($temp = array_pop($stack)) !== null)
259
							{
260
								array_unshift($context['categories'][$catid]['boards'][$prev_board]['move_links'], $temp);
261
							}
262
						}
263
					}
264
265
					$prev_board = $boardid;
266
					$prev_child_level = $boards[$boardid]['level'];
267
				}
268
269
				if (!empty($stack) && !empty($context['categories'][$catid]['boards'][$prev_board]['move_links']))
270
				{
271
					$context['categories'][$catid]['boards'][$prev_board]['move_links'] = array_merge($stack, $context['categories'][$catid]['boards'][$prev_board]['move_links']);
272
				}
273
				elseif (!empty($stack))
274
				{
275
					$context['categories'][$catid]['boards'][$prev_board]['move_links'] = $stack;
276
				}
277
278
				if (empty($boardList[$catid]))
279
				{
280
					$context['categories'][$catid]['move_link'] = array(
281
						'child_level' => 0,
282
						'label' => $txt['mboards_order_before'] . " '" . htmlspecialchars($tree['node']['name'], ENT_COMPAT, 'UTF-8') . "'",
283
						'href' => getUrl('admin', ['action' => 'admin', 'area' => 'manageboards', 'sa' => 'move', 'src_board' => $context['move_board'], 'target_cat' => $catid, 'move_to' => 'top', '{session_data}', $security_token]),
284
					);
285
				}
286
			}
287
		}
288
289
		call_integration_hook('integrate_boards_main');
290
291
		$context['page_title'] = $txt['boards_and_cats'];
292
		$context['sub_template'] = 'manage_boards';
293
		$context['can_manage_permissions'] = allowedTo('manage_permissions');
294
	}
295
296
	/**
297
	 * Function for handling a submitted form saving the category.
298
	 *
299
	 * What it does:
300
	 *
301
	 * - complete the modifications to a specific category.
302
	 * - It also handles deletion of a category.
303
	 * - It requires manage_boards permission.
304
	 * - Called by ?action=admin;area=manageboards;sa=cat2
305
	 * - Redirects to ?action=admin;area=manageboards.
306
	 */
307
	public function action_cat2()
308
	{
309
		checkSession();
310
		validateToken('admin-bc-' . $this->_req->post->cat);
311
312
		require_once(SUBSDIR . '/Categories.subs.php');
313
314
		$this->cat = $this->_req->getPost('cat', 'intval');
315
316
		// Add a new category or modify an existing one..
317
		if (isset($this->_req->post->edit) || isset($this->_req->post->add))
318
		{
319
			$catOptions = array();
320
321
			if (isset($this->_req->post->cat_order))
322
			{
323
				$catOptions['move_after'] = (int) $this->_req->post->cat_order;
324
			}
325
326
			// Change "This & That" to "This &amp; That" but don't change "&cent" to "&amp;cent;"...
327
			$catOptions['cat_name'] = preg_replace('~[&]([^;]{8}|[^;]{0,8}$)~', '&amp;$1', $this->_req->post->cat_name);
328
			$catOptions['is_collapsible'] = isset($this->_req->post->collapse);
329
330
			if (isset($this->_req->post->add))
331
			{
332
				createCategory($catOptions);
333
			}
334
			else
335
			{
336
				modifyCategory($this->cat, $catOptions);
337
			}
338
		}
339
		// If they want to delete - first give them confirmation.
340
		elseif (isset($this->_req->post->delete) && !isset($this->_req->post->confirmation) && !isset($this->_req->post->empty))
341
		{
342
			$this->action_cat();
343
344
			return;
345
		}
346
		// Delete the category!
347
		elseif (isset($this->_req->post->delete))
348
		{
349
			// First off - check if we are moving all the current boards first - before we start deleting!
350
			if ($this->_req->comparePost('delete_action', 1, 'intval'))
351
			{
352
				if (empty($this->_req->post->cat_to))
353
				{
354
					throw new Exception('mboards_delete_error');
355
				}
356
357
				deleteCategories(array($this->cat), $this->_req->getPost('cat_to', 'intval'));
358
			}
359
			else
360
			{
361
				deleteCategories(array($this->cat));
362
			}
363
		}
364
365
		redirectexit('action=admin;area=manageboards');
366
	}
367
368
	/**
369
	 * Modify a specific category.
370
	 *
371
	 * What it does:
372
	 *
373
	 * - screen for editing and repositioning a category.
374
	 * - Also used to show the confirm deletion of category screen
375
	 * - Called by ?action=admin;area=manageboards;sa=cat
376
	 * - Requires manage_boards permission.
377
	 *
378
	 * @event integrate_edit_category access category globals before the template
379
	 * @uses ManageBoards template, modify_category sub-template.
380
	 */
381
	public function action_cat()
382
	{
383
		global $txt, $context;
384
385
		theme()->getTemplates()->load('ManageBoards');
386
		require_once(SUBSDIR . '/Boards.subs.php');
387
		$boardTree = new BoardsTree(database());
388
		$cat_tree = $boardTree->getCategories();
389
390
		// id_cat must be a number.... if it exists.
391
		$this->cat = $this->_req->getQuery('cat', 'intval', 0);
392
393
		// Start with one - "In first place".
394
		$context['category_order'] = array(
395
			array(
396
				'id' => 0,
397
				'name' => $txt['mboards_order_first'],
398
				'selected' => !empty($this->cat) && !empty($cat_tree[$this->cat]['is_first']),
399
				'true_name' => ''
400
			)
401
		);
402
403
		// If this is a new category set up some defaults.
404
		if ($this->_req->compareQuery('sa', 'newcat', 'trim'))
405
		{
406
			$context['category'] = array(
407
				'id' => 0,
408
				'name' => $txt['mboards_new_cat_name'],
409
				'editable_name' => htmlspecialchars($txt['mboards_new_cat_name'], ENT_COMPAT, 'UTF-8'),
410
				'can_collapse' => true,
411
				'is_new' => true,
412
				'is_empty' => true
413
			);
414
		}
415
		// Category doesn't exist, man... sorry.
416
		elseif ($boardTree->categoryExists($this->cat) === false)
417
		{
418
			redirectexit('action=admin;area=manageboards');
419
		}
420
		else
421
		{
422
			$context['category'] = array(
423
				'id' => $this->cat,
424
				'name' => $cat_tree[$this->cat]['node']['name'],
425
				'editable_name' => htmlspecialchars($cat_tree[$this->cat]['node']['name'], ENT_COMPAT, 'UTF-8'),
426
				'can_collapse' => !empty($cat_tree[$this->cat]['node']['can_collapse']),
427
				'children' => array(),
428
				'is_empty' => empty($cat_tree[$this->cat]['children'])
429
			);
430
431
			$boardCat = $boardTree->getBoardsInCat($this->cat);
432
			$boards = $boardTree->getBoards();
433
			foreach ($boardCat as $child_board)
434
			{
435
				$context['category']['children'][] = str_repeat('-', $boards[$child_board]['level']) . ' ' . $boards[$child_board]['name'];
436
			}
437
		}
438
439
		$prevCat = 0;
440
		foreach ($cat_tree as $catid => $tree)
441
		{
442
			if ($catid === $this->cat && $prevCat > 0)
443
			{
444
				$context['category_order'][$prevCat]['selected'] = true;
445
			}
446
			elseif ($catid !== $this->cat)
447
			{
448
				$context['category_order'][$catid] = array(
449
					'id' => $catid,
450
					'name' => $txt['mboards_order_after'] . $tree['node']['name'],
451
					'selected' => false,
452
					'true_name' => $tree['node']['name']
453
				);
454
			}
455
456
			$prevCat = $catid;
457
		}
458
459
		if (!isset($this->_req->query->delete))
460
		{
461
			$context['sub_template'] = 'modify_category';
462
			$context['page_title'] = $this->_req->compareQuery('sa', 'newcat') ? $txt['mboards_new_cat_name'] : $txt['catEdit'];
463
		}
464
		else
465
		{
466
			$context['sub_template'] = 'confirm_category_delete';
467
			$context['page_title'] = $txt['mboards_delete_cat'];
468
		}
469
470
		// Create a special token.
471
		$context['token_check'] = 'admin-bc-' . $this->cat;
472
		createToken($context['token_check']);
473
474
		call_integration_hook('integrate_edit_category');
475
	}
476
477
	/**
478
	 * Make changes to/delete a board.
479
	 *
480
	 * What it does:
481
	 *
482
	 * - function for handling a submitted form saving the board.
483
	 * - It also handles deletion of a board.
484
	 * - Called by ?action=admin;area=manageboards;sa=board2
485
	 * - Redirects to ?action=admin;area=manageboards.
486
	 * - It requires manage_boards permission.
487
	 *
488
	 * @event integrate_save_board
489
	 */
490
	public function action_board2()
491
	{
492
		global $context;
493
494
		$board_id = $this->_req->getPost('boardid', 'intval', 0);
495
		checkSession();
496
		validateToken('admin-be-' . $this->_req->post->boardid);
497
498
		require_once(SUBSDIR . '/Boards.subs.php');
499
		require_once(SUBSDIR . '/Post.subs.php');
500
501
		$posts = getBoardProperties($this->_req->post->boardid)['numPosts'];
502
503
		// Mode: modify aka. don't delete.
504
		if (isset($this->_req->post->edit) || isset($this->_req->post->add))
505
		{
506
			$boardOptions = array();
507
508
			// Move this board to a new category?
509
			if (!empty($this->_req->post->new_cat))
510
			{
511
				$boardOptions['move_to'] = 'bottom';
512
				$boardOptions['target_category'] = (int) $this->_req->post->new_cat;
513
			}
514
			// Change the boardorder of this board?
515
			elseif (!empty($this->_req->post->placement) && !empty($this->_req->post->board_order))
516
			{
517
				if (!in_array($this->_req->post->placement, array('before', 'after', 'child')))
518
				{
519
					throw new Exception('mangled_post', false);
520
				}
521
522
				$boardOptions['move_to'] = $this->_req->post->placement;
523
				$boardOptions['target_board'] = (int) $this->_req->post->board_order;
524
			}
525
526
			// Checkboxes....
527
			$boardOptions['posts_count'] = isset($this->_req->post->count);
528
			$boardOptions['old_posts'] = isset($this->_req->post->old_posts);
529
			$boardOptions['override_theme'] = isset($this->_req->post->override_theme);
530
			$boardOptions['board_theme'] = (int) $this->_req->post->boardtheme;
531
			$boardOptions['access_groups'] = array();
532
			$boardOptions['deny_groups'] = array();
533
534
			if (!empty($this->_req->post->groups))
535
			{
536
				foreach ($this->_req->post->groups as $group => $action)
537
				{
538
					if ($action === 'allow')
539
					{
540
						$boardOptions['access_groups'][] = (int) $group;
541
					}
542
					elseif ($action === 'deny')
543
					{
544
						$boardOptions['deny_groups'][] = (int) $group;
545
					}
546
				}
547
			}
548
549
			if (strlen(implode(',', $boardOptions['access_groups'])) > 255 || strlen(implode(',', $boardOptions['deny_groups'])) > 255)
550
			{
551
				throw new Exception('too_many_groups', false);
552
			}
553
554
			// Change '1 & 2' to '1 &amp; 2', but not '&amp;' to '&amp;amp;'...
555
			$boardOptions['board_name'] = preg_replace('~[&]([^;]{8}|[^;]{0,8}$)~', '&amp;$1', $this->_req->post->board_name);
556
557
			// Convert any html to bbc
558
			$parser = new Html2BBC($this->_req->post->desc);
559
			$boardOptions['board_description'] = Util::htmlspecialchars($parser->get_bbc());
560
			preparsecode($boardOptions['board_description']);
561
562
			$boardOptions['moderator_string'] = $this->_req->post->moderators;
563
564
			if (isset($this->_req->post->moderator_list) && is_array($this->_req->post->moderator_list))
565
			{
566
				$moderators = array();
567
				foreach ($this->_req->post->moderator_list as $moderator)
568
				{
569
					$moderators[(int) $moderator] = (int) $moderator;
570
				}
571
572
				$boardOptions['moderators'] = $moderators;
573
			}
574
575
			// Are they doing redirection?
576
			$boardOptions['redirect'] = $this->_req->comparePost('redirect_address', '', 'trim') ? '' : $this->_req->get('redirect_address');
577
578
			// Profiles...
579
			$boardOptions['profile'] = $this->_req->post->profile;
580
			$boardOptions['inherit_permissions'] = (int) $this->_req->post->profile === -1;
581
582
			// We need to know what used to be case in terms of redirection.
583
			if (!empty($board_id))
584
			{
585
				$properties = getBoardProperties($board_id);
586
587
				// 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.
588
				if ($boardOptions['redirect'] && empty($properties['oldRedirect']) && $properties['numPosts'])
589
				{
590
					unset($boardOptions['redirect']);
591
				}
592
				// Reset the redirection count when switching on/off.
593
				elseif (empty($boardOptions['redirect']) !== empty($properties['oldRedirect']))
594
				{
595
					$boardOptions['num_posts'] = 0;
596
				}
597
				// Resetting the count?
598
				elseif ($boardOptions['redirect'] && !empty($this->_req->post->reset_redirect))
599
				{
600
					$boardOptions['num_posts'] = 0;
601
				}
602
			}
603
604
			call_integration_hook('integrate_save_board', array($board_id, &$boardOptions));
605
606
			// Create a new board...
607
			if (isset($this->_req->post->add))
608
			{
609
				// New boards by default go to the bottom of the category.
610
				if (empty($this->_req->post->new_cat))
611
				{
612
					$boardOptions['target_category'] = $this->_req->getPost('cur_cat', 'intval', 0);
613
				}
614
615
				if (!isset($boardOptions['move_to']))
616
				{
617
					$boardOptions['move_to'] = 'bottom';
618
				}
619
620
				createBoard($boardOptions);
621
			}
622
			// ...or update an existing board.
623
			else
624
			{
625
				modifyBoard($board_id, $boardOptions);
626
			}
627
		}
628
		elseif (isset($this->_req->post->delete) && !isset($this->_req->post->confirmation) && !isset($this->_req->post->no_children))
629
		{
630
			if ($posts)
631
			{
632
				throw new Exception('mboards_delete_board_has_posts');
633
			}
634
			$this->action_board();
635
636
			return;
637
		}
638
		elseif (isset($this->_req->post->delete))
639
		{
640
			$boardTree = new BoardsTree(database());
641
			// First, check if our board still has posts or topics.
642
			if ($posts)
643
			{
644
				throw new Exception('mboards_delete_board_has_posts');
645
			}
646
647
			if ($this->_req->comparePost('delete_action', 1, 'intval'))
648
			{
649
				// Check if we are moving all the current sub-boards first - before we start deleting!
650
				if (empty($this->_req->post->board_to))
651
				{
652
					throw new Exception('mboards_delete_board_error');
653
				}
654
				$boardTree->deleteBoards(array($board_id), $this->_req->getPost('board_to', 'intval'));
655
			}
656
			else
657
			{
658
				$boardTree->deleteBoards(array($board_id), 0);
659
			}
660
		}
661
662
		if ($this->_req->compareQuery('rid', 'permissions', 'trim'))
663
		{
664
			redirectexit('action=admin;area=permissions;sa=board;' . $context['session_var'] . '=' . $context['session_id']);
665
		}
666
		else
667
		{
668
			redirectexit('action=admin;area=manageboards');
669
		}
670
	}
671
672
	/**
673
	 * Modify a specific board...
674
	 *
675
	 * What it does
676
	 * - screen for editing and repositioning a board.
677
	 * - called by ?action=admin;area=manageboards;sa=board
678
	 * - also used to show the confirm deletion of category screen (sub-template confirm_board_delete).
679
	 * - requires manage_boards permission.
680
	 *
681
	 * @event integrate_edit_board
682
	 * @uses the modify_board sub-template of the ManageBoards template.
683
	 * @uses ManagePermissions language
684
	 */
685
	public function action_board()
686
	{
687
		global $txt, $context, $modSettings;
688
689
		theme()->getTemplates()->load('ManageBoards');
690
		require_once(SUBSDIR . '/Boards.subs.php');
691
		require_once(SUBSDIR . '/Post.subs.php');
692
		$boardTree = new BoardsTree(database());
693
694
		// For editing the profile we'll need this.
695
		Txt::load('ManagePermissions');
696
		require_once(SUBSDIR . '/ManagePermissions.subs.php');
697
		loadPermissionProfiles();
698
699
		// id_board must be a number....
700
		$this->boardid = $this->_req->getQuery('boardid', 'intval', 0);
701
		if ($boardTree->boardExists($this->boardid) === false)
702
		{
703
			$this->boardid = 0;
704
			$this->_req->query->sa = 'newboard';
705
		}
706
707
		if ($this->_req->compareQuery('sa', 'newboard', 'trim'))
708
		{
709
			$this->cat = $this->_req->getQuery('cat', 'intval', 0);
710
711
			// Category doesn't exist, man... sorry.
712
			if (empty($this->cat))
713
			{
714
				redirectexit('action=admin;area=manageboards');
715
			}
716
717
			// Some things that need to be setup for a new board.
718
			$curBoard = array(
719
				'member_groups' => array(0, -1),
720
				'deny_groups' => array(),
721
				'category' => $this->cat
722
			);
723
			$context['board_order'] = array();
724
			$context['board'] = array(
725
				'is_new' => true,
726
				'id' => 0,
727
				'name' => $txt['mboards_new_board_name'],
728
				'description' => '',
729
				'count_posts' => 1,
730
				'old_posts' => 1,
731
				'posts' => 0,
732
				'topics' => 0,
733
				'theme' => 0,
734
				'profile' => 1,
735
				'override_theme' => 0,
736
				'redirect' => '',
737
				'category' => $this->cat,
738
				'no_children' => true,
739
			);
740
		}
741
		else
742
		{
743
			// Just some easy shortcuts.
744
			$curBoard = $boardTree->getBoardById($this->boardid);
745
			$context['board'] = $curBoard;
746
			$context['board']['name'] = htmlspecialchars(strtr($context['board']['name'], array('&amp;' => '&')), ENT_COMPAT, 'UTF-8');
747
			$context['board']['description'] = un_preparsecode($context['board']['description']);
748
			$context['board']['no_children'] = empty($curBoard['tree']['children']);
749
			$context['board']['is_recycle'] = !empty($modSettings['recycle_enable']) && !empty($modSettings['recycle_board']) && $modSettings['recycle_board'] == $context['board']['id'];
750
		}
751
752
		// As we may have come from the permissions screen keep track of where we should go on save.
753
		$context['redirect_location'] = $this->_req->compareQuery('rid', 'permissions', 'trim') ? 'permissions' : 'boards';
754
755
		// We might need this to hide links to certain areas.
756
		$context['can_manage_permissions'] = allowedTo('manage_permissions');
757
758
		// Default membergroups.
759
		$context['groups'] = array(
760
			-1 => array(
761
				'id' => '-1',
762
				'name' => $txt['parent_guests_only'],
763
				'allow' => in_array('-1', $curBoard['member_groups']),
764
				'deny' => in_array('-1', $curBoard['deny_groups']),
765
				'is_post_group' => false,
766
			),
767
			0 => array(
768
				'id' => '0',
769
				'name' => $txt['parent_members_only'],
770
				'allow' => in_array('0', $curBoard['member_groups']),
771
				'deny' => in_array('0', $curBoard['deny_groups']),
772
				'is_post_group' => false,
773
			)
774
		);
775
776
		$context['groups'] += getOtherGroups($curBoard, $this->_req->compareQuery('sa', 'newboard'));
777
778
		// Category doesn't exist, man... sorry.
779
		if ($boardTree->categoryExists($curBoard['category']) === false)
780
		{
781
			redirectexit('action=admin;area=manageboards');
782
		}
783
784
		$catBoards = $boardTree->getBoardsInCat($curBoard['category']);
785
		foreach ($catBoards as $boardid)
786
		{
787
			$thisBoard = $boardTree->getBoardById($boardid);
788
			if ($boardid === $this->boardid)
789
			{
790
				$context['board_order'][] = array(
791
					'id' => $boardid,
792
					'name' => str_repeat('-', $thisBoard['level']) . ' (' . $txt['mboards_current_position'] . ')',
793
					'children' => $thisBoard['tree']['children'],
794
					'no_children' => empty($thisBoard['tree']['children']),
795
					'is_child' => false,
796
					'selected' => true
797
				);
798
			}
799
			else
800
			{
801
				$context['board_order'][] = array(
802
					'id' => $boardid,
803
					'name' => str_repeat('-', $thisBoard['level']) . ' ' . $thisBoard['name'],
804
					'is_child' => !empty($this->boardid) && $boardTree->isChildOf($boardid, $this->boardid),
805
					'selected' => false
806
				);
807
			}
808
		}
809
810
		// Are there any places to move sub-boards to in the case where we are confirming a delete?
811
		if (!empty($this->boardid))
812
		{
813
			$context['can_move_children'] = false;
814
			$context['children'] = $curBoard['tree']['children'];
815
			foreach ($context['board_order'] as $board)
816
			{
817
				if ($board['is_child'] !== false)
818
				{
819
					continue;
820
				}
821
822
				if ($board['selected'] !== false)
823
				{
824
					continue;
825
				}
826
827
				$context['can_move_children'] = true;
828
			}
829
		}
830
831
		// Get other available categories.
832
		$context['categories'] = array();
833
		$cat_tree = $boardTree->getCategories();
834
		foreach ($cat_tree as $catID => $tree)
835
		{
836
			$context['categories'][] = array(
837
				'id' => $catID === $curBoard['category'] ? 0 : $catID,
838
				'name' => $tree['node']['name'],
839
				'selected' => $catID === $curBoard['category']
840
			);
841
		}
842
843
		$context['board']['moderators'] = getBoardModerators($this->boardid);
844
		$context['board']['moderator_list'] = empty($context['board']['moderators']) ? '' : '&quot;' . implode('&quot;, &quot;', $context['board']['moderators']) . '&quot;';
845
846
		if (!empty($context['board']['moderators']))
847
		{
848
			[$context['board']['last_moderator_id']] = array_slice(array_keys($context['board']['moderators']), -1);
849
		}
850
851
		$context['themes'] = getAllThemes();
852
853
		if (!isset($this->_req->query->delete))
854
		{
855
			$context['sub_template'] = 'modify_board';
856
			$context['page_title'] = $txt['boardsEdit'];
857
			loadJavascriptFile('suggest.js', array('defer' => true));
858
		}
859
		else
860
		{
861
			$context['sub_template'] = 'confirm_board_delete';
862
			$context['page_title'] = $txt['mboards_delete_board'];
863
		}
864
865
		// Create a special token.
866
		createToken('admin-be-' . $this->boardid);
867
868
		call_integration_hook('integrate_edit_board');
869
	}
870
871
	/**
872
	 * A screen to display and allow to set a few general board and category settings.
873
	 *
874
	 * @event integrate_save_board_settings called during manage board settings
875
	 * @uses modify_general_settings sub-template.
876
	 */
877
	public function action_boardSettings_display()
878
	{
879
		global $context, $txt;
880
881
		// Initialize the form
882
		$settingsForm = new SettingsForm(SettingsForm::DB_ADAPTER);
883
884
		// Initialize it with our settings
885
		$settingsForm->setConfigVars($this->_settings());
886
887
		// Add some javascript stuff for the recycle box.
888
		theme()->addInlineJavascript('
889
				document.getElementById("recycle_board").disabled = !document.getElementById("recycle_enable").checked;', true);
890
891
		// Get the needed template bits
892
		theme()->getTemplates()->load('ManageBoards');
893
		$context['page_title'] = $txt['boards_and_cats'] . ' - ' . $txt['settings'];
894
		$context['sub_template'] = 'show_settings';
895
		$context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'manageboards', 'sa' => 'settings', 'save']);
896
897
		// Warn the admin against selecting the recycle topic without selecting a board.
898
		$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;";
899
900
		// Doing a save?
901
		if (isset($this->_req->query->save))
902
		{
903
			checkSession();
904
905
			call_integration_hook('integrate_save_board_settings');
906
907
			$settingsForm->setConfigValues((array) $this->_req->post);
908
			$settingsForm->save();
909
			redirectexit('action=admin;area=manageboards;sa=settings');
910
		}
911
912
		// Prepare the settings...
913
		$settingsForm->prepare();
914
	}
915
916
	/**
917
	 * Retrieve and return all admin settings for boards management.
918
	 *
919
	 * @event integrate_modify_board_settings add config settings to boards management
920
	 */
921
	private function _settings()
922
	{
923
		global $txt;
924
925 4
		// We need to borrow a string from here
926
		Txt::load('ManagePermissions');
927 4
928
		// Load the boards list - for the recycle bin!
929
		require_once(SUBSDIR . '/Boards.subs.php');
930 4
		$boards = getBoardList(array('override_permissions' => true, 'not_redirection' => true), true);
931
		$recycle_boards = array('');
932
		foreach ($boards as $board)
933 4
		{
934 4
			$recycle_boards[$board['id_board']] = $board['cat_name'] . ' - ' . $board['board_name'];
935 4
		}
936 4
937
		// Here and the board settings...
938 4
		$config_vars = array(
939
			array('title', 'settings'),
940
			// Inline permissions.
941
			array('permissions', 'manage_boards', 'helptext' => $txt['permissionhelp_manage_boards'], 'collapsed' => true),
942
			'',
943 4
			// Other board settings.
944
			array('check', 'countChildPosts'),
945 4
			array('check', 'recycle_enable', 'onclick' => "document.getElementById('recycle_board').disabled = !this.checked;"),
946 4
			array('select', 'recycle_board', $recycle_boards),
947
			array('check', 'allow_ignore_boards'),
948
			array('check', 'deny_boards_access'),
949
		);
950 4
951
		// Add new settings with a nice hook, makes them available for admin settings search as well
952
		call_integration_hook('integrate_modify_board_settings', array(&$config_vars));
953
954
		return $config_vars;
955
	}
956 4
957
	/**
958 4
	 * Return the form settings for use in admin search
959
	 */
960
	public function settings_search()
961
	{
962
		return $this->_settings();
963
	}
964
}
965