Admin::pre_dispatch()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 14
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file, unpredictable as this might be, handles basic administration.
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\AdminSettingsSearch;
22
use ElkArte\EventManager;
23
use ElkArte\Exceptions\Exception;
24
use ElkArte\Hooks;
25
use ElkArte\Languages\Txt;
26
use ElkArte\Menu\Menu;
27
use ElkArte\Packages\Packages;
28
use ElkArte\Packages\PackageServers;
29
use ElkArte\User;
30
use ElkArte\XmlArray;
31
32
/**
33
 * Admin controller class.
34
 *
35
 * What it does:
36
 *
37
 * - This class handles the first general admin screens: home,
38
 * - Handles admin area search actions and end admin session.
39
 *
40
 * @package Admin
41
 */
42
class Admin extends AbstractController
43
{
44
	/** @var string[] areas to find current installed status and installed version */
45
	private array $_checkFor = ['gd', 'imagick', 'db_server', 'php', 'server',
46
		'zend', 'apc', 'memcache', 'memcached', 'opcache'];
47
48
	/**
49
	 * Pre-dispatch, called before other methods.
50
	 *
51
	 * - Loads integration hooks
52
	 */
53
	public function pre_dispatch()
54
	{
55
		global $context, $modSettings;
56
57
		Hooks::instance()->loadIntegrationsSettings();
58
59
		// The Admin functions require Jquery UI ....
60
		$modSettings['jquery_include_ui'] = true;
61
62
		// No indexing evil stuff.
63
		$context['robot_no_index'] = true;
64
65
		// Need this to do much
66
		require_once(SUBSDIR . '/Admin.subs.php');
67
	}
68
69
	/**
70
	 * The main admin handling function.
71
	 *
72
	 * What it does:
73
	 *
74
	 * - It initializes all the basic context required for the admin center.
75
	 * - It passes execution onto the relevant admin section.
76
	 * - If the passed section is not found, it shows the admin home page.
77
	 * - Accessed by ?action=admin.
78
	 */
79
	public function action_index()
80
	{
81
		// Make sure the administrator has a valid session...
82
		validateSession();
83
84
		// Load the language and templates....
85
		Txt::load('Admin+Help+ManageSettings');
86
		theme()->getTemplates()->load('Admin');
87
		loadCSSFile('admin.css');
88
		loadJavascriptFile('admin.js', [], 'admin_script');
89
90
		// Actually create the menu!
91
		$admin_include_data = $this->loadMenu();
92
		$this->buildBreadCrumbs($admin_include_data);
93
94
		// And off we go, only one action, the chosen menu area
95
		$action = new Action();
96
		$action->initialize(['action' => $admin_include_data]);
97
		$action->dispatch('action');
98
	}
99
100
	/**
101
	 * Load the admin_areas array
102
	 *
103
	 * What it does:
104
	 *
105
	 * - Creates the admin menu
106
	 * - Allows integrations to add/edit menu with addMenu event and integrate_admin_include
107
	 *
108
	 * @event integrate_admin_include used add files to include for administration
109
	 * @event addMenu passed admin area, allows active modules registered to this event to add items to the admin menu,
110
	 * @event integrate_admin_areas passed admin area, used to add items to the admin menu
111 2
	 *
112
	 * @return array
113 2
	 * @throws Exception no_access
114
	 */
115
	private function loadMenu(): array
116 2
	{
117
		global $txt, $context, $modSettings, $settings;
118
119
		// Need these to do much
120 1
		require_once(SUBSDIR . '/Menu.subs.php');
121 2
122
		// Define the menu structure - see subs/Menu.subs.php for details!
123
		$admin_areas = [
124
			'admin_tools' => [
125 2
				'title' => $txt['admin_main'],
126 2
				'permission' => ['admin_forum', 'manage_permissions', 'moderate_forum', 'manage_membergroups', 'manage_bans', 'send_mail', 'edit_news', 'manage_boards', 'manage_smileys', 'manage_attachments'],
127 2
				'areas' => [
128 2
					'index' => [
129 2
						'label' => $txt['admin_center'],
130
						'controller' => __CLASS__,
131
						'function' => 'action_home',
132 2
						'class' => 'i-home i-admin',
133 2
					],
134 2
					'credits' => [
135 2
						'label' => $txt['support_credits_title'],
136 2
						'controller' => __CLASS__,
137
						'function' => 'action_credits',
138
						'class' => 'i-support i-admin',
139 2
					],
140 2
					'adminlogoff' => [
141 2
						'label' => $txt['admin_logoff'],
142 2
						'controller' => __CLASS__,
143 2
						'function' => 'action_endsession',
144
						'enabled' => empty($modSettings['securityDisable']),
145 2
						'class' => 'i-sign-out i-admin',
146
					],
147 2
					'search' => [
148 2
						'controller' => __CLASS__,
149 2
						'function' => 'action_search',
150 2
						'permission' => ['admin_forum'],
151 2
						'class' => 'i-search i-admin',
152
						'select' => 'index',
153
						'hidden' => true,
154
					],
155 2
				],
156 2
			],
157 2
			'communication' => [
158 2
				'title' => $txt['communication_title'],
159 2
				'permission' => ['approve_emails', 'send_mail', 'edit_news', 'admin_forum'],
160
				'areas' => [
161
					'maillist' => [
162 2
						'label' => $txt['mail_center'],
163 2
						'controller' => ManageMaillist::class,
164 2
						'function' => 'action_index',
165
						'class' => 'i-envelope-blank i-admin',
166
						'permission' => ['approve_emails', 'admin_forum'],
167
						'enabled' => featureEnabled('pe'),
168 2
						'subsections' => [
169 2
							'emaillist' => [$txt['mm_emailerror'], 'approve_emails'],
170 2
							'emailfilters' => [$txt['mm_emailfilters'], 'admin_forum'],
171
							'emailparser' => [$txt['mm_emailparsers'], 'admin_forum'],
172 2
							'emailtemplates' => [$txt['mm_emailtemplates'], 'approve_emails'],
173 2
							'emailsettings' => [$txt['mm_emailsettings'], 'admin_forum'],
174
						],
175 2
					],
176 2
					'news' => [
177 2
						'label' => $txt['news_title'],
178 2
						'controller' => ManageNews::class,
179 2
						'function' => 'action_index',
180 2
						'class' => 'i-post-text i-admin',
181
						'permission' => ['edit_news', 'send_mail', 'admin_forum'],
182
						'subsections' => [
183
							'editnews' => [$txt['admin_edit_news'], 'edit_news'],
184 2
							'mailingmembers' => [$txt['admin_newsletters'], 'send_mail'],
185 2
							'settings' => [$txt['settings'], 'admin_forum'],
186 2
						],
187
					],
188 2
					'mailqueue' => [
189 2
						'label' => $txt['mailqueue_title'],
190
						'controller' => ManageMail::class,
191
						'function' => 'action_index',
192
						'class' => 'i-envelope-blank i-admin',
193
						'subsections' => [
194
							'browse' => [$txt['mailqueue_browse'], 'admin_forum'],
195
							'test' => [$txt['mailqueue_test'], 'admin_forum'],
196
							'settings' => [$txt['mailqueue_settings'], 'admin_forum'],
197
						],
198
					],
199 2
				],
200 2
			],
201 2
			'forum' => [
202 2
				'title' => $txt['layout_controls'],
203 2
				'permission' => ['manage_boards', 'admin_forum', 'manage_smileys', 'manage_attachments', 'moderate_forum'],
204 2
				'areas' => [
205
					'manageboards' => [
206
						'label' => $txt['admin_boards'],
207
						'controller' => ManageBoards::class,
208
						'function' => 'action_index',
209 2
						'class' => 'i-directory i-admin',
210
						'permission' => ['manage_boards'],
211
						'subsections' => [
212
							'main' => [$txt['boardsEdit']],
213 2
							'newcat' => [$txt['mboards_new_cat']],
214 2
							'settings' => [$txt['settings'], 'admin_forum'],
215 2
						],
216 2
					],
217 2
					'postsettings' => [
218
						'label' => $txt['manageposts'],
219
						'controller' => ManagePosts::class,
220 2
						'function' => 'action_index',
221 2
						'permission' => ['admin_forum'],
222 2
						'class' => 'i-post-text i-admin',
223 2
						'subsections' => [
224 2
							'posts' => [$txt['manageposts_settings']],
225
							'censor' => [$txt['admin_censored_words']],
226 2
							'topics' => [$txt['manageposts_topic_settings']],
227 2
							'sig' => [$txt['signature_settings']],
228 2
						],
229 2
					],
230 2
					'editor' => [
231 2
						'label' => $txt['editor_manage'],
232 2
						'controller' => ManageEditor::class,
233 2
						'function' => 'action_index',
234
						'class' => 'i-modify i-admin',
235
						'permission' => ['manage_bbc'],
236
					],
237 2
					'smileys' => [
238 2
						'label' => $txt['smileys_manage'],
239 2
						'controller' => ManageSmileys::class,
240 2
						'function' => 'action_index',
241 2
						'class' => 'i-smiley-blank i-admin',
242
						'permission' => ['manage_smileys'],
243 2
						'subsections' => [
244 2
							'editsets' => [$txt['smiley_sets']],
245 2
							'addsmiley' => [$txt['smileys_add']],
246 2
							'editsmileys' => [$txt['smileys_edit']],
247 2
							'setorder' => [$txt['smileys_set_order']],
248 2
							'editicons' => [$txt['icons_edit_message_icons'], 'enabled' => !empty($modSettings['messageIcons_enable'])],
249
							'settings' => [$txt['settings']],
250
						],
251
					],
252 2
					'manageattachments' => [
253 2
						'label' => $txt['attachments_avatars'],
254 2
						'controller' => ManageAttachments::class,
255 2
						'function' => 'action_index',
256 2
						'class' => 'i-paperclip i-admin',
257
						'permission' => ['manage_attachments'],
258 2
						'subsections' => [
259 2
							'browse' => [$txt['attachment_manager_browse']],
260 2
							'attachments' => [$txt['attachment_manager_settings']],
261 2
							'avatars' => [$txt['attachment_manager_avatar_settings']],
262
							'attachpaths' => [$txt['attach_directories']],
263
							'maintenance' => [$txt['attachment_manager_maintenance']],
264
						],
265 2
					],
266 2
					'managesearch' => [
267 2
						'label' => $txt['manage_search'],
268 2
						'controller' => ManageSearch::class,
269 2
						'function' => 'action_index',
270 2
						'class' => 'i-search i-admin',
271
						'permission' => ['admin_forum'],
272 2
						'subsections' => [
273 2
							'method' => [$txt['search_method']],
274 2
							'weights' => [$txt['search_weights']],
275 2
							'managesphinxql' => [$txt['search_sphinx']],
276 2
							'managemanticore' => [$txt['search_manticore']],
277 2
							'settings' => [$txt['settings']],
278
						],
279
					],
280
					'likes' => [
281 2
						'label' => $txt['likes'],
282 2
						'enabled' => featureEnabled('l'),
283 2
						'controller' => ManageLikes::class,
284 2
						'class' => 'i-thumbsup i-admin',
285 2
						'function' => 'action_index',
286 2
						'permission' => 'admin_forum',
287
					],
288
				],
289 2
			],
290 2
			'members' => [
291 2
				'title' => $txt['admin_manage_members'],
292 2
				'permission' => ['moderate_forum', 'manage_membergroups', 'manage_bans', 'manage_permissions', 'admin_forum'],
293 2
				'areas' => [
294
					'viewmembers' => [
295 2
						'label' => $txt['admin_users'],
296
						'controller' => ManageMembers::class,
297 2
						'function' => 'action_index',
298
						'class' => 'i-user i-admin',
299
						'permission' => ['moderate_forum'],
300
					],
301 2
					'membergroups' => [
302 2
						'label' => $txt['admin_groups'],
303 2
						'controller' => ManageMembergroups::class,
304 2
						'function' => 'action_index',
305 2
						'class' => 'i-users',
306
						'permission' => ['manage_membergroups'],
307 2
						'subsections' => [
308
							'index' => [$txt['membergroups_edit_groups'], 'manage_membergroups'],
309
							'add' => [$txt['membergroups_new_group'], 'manage_membergroups'],
310
							'settings' => [$txt['settings'], 'admin_forum'],
311
						],
312
					],
313 2
					'permissions' => [
314
						'label' => $txt['edit_permissions'],
315
						'controller' => ManagePermissions::class,
316
						'function' => 'action_index',
317 2
						'class' => 'i-key i-admin',
318 2
						'permission' => ['manage_permissions'],
319 2
						'subsections' => [
320 2
							'index' => [$txt['permissions_groups'], 'manage_permissions'],
321 2
							'board' => [$txt['permissions_boards'], 'manage_permissions'],
322
							'profiles' => [$txt['permissions_profiles'], 'manage_permissions'],
323
							'postmod' => [$txt['permissions_post_moderation'], 'manage_permissions', 'enabled' => $modSettings['postmod_active']],
324 2
							'settings' => [$txt['settings'], 'admin_forum'],
325 2
						],
326 2
					],
327
					'ban' => [
328
						'label' => $txt['ban_title'],
329
						'controller' => ManageBans::class,
330 2
						'function' => 'action_index',
331 2
						'class' => 'i-thumbdown i-admin',
332 2
						'permission' => 'manage_bans',
333
						'subsections' => [
334 2
							'list' => [$txt['ban_edit_list']],
335 2
							'add' => [$txt['ban_add_new']],
336
							'browse' => [$txt['ban_trigger_browse']],
337 2
							'log' => [$txt['ban_log']],
338 2
						],
339 2
					],
340 2
					'warnings' => [
341
						'label' => $txt['moderation_warning_short'],
342
						'class' => 'i-warning i-admin',
343
						'enabled' => featureEnabled('w'),
344 2
						'controller' => ManageWarnings::class,
345 2
						'function' => 'action_index',
346 2
						'permission' => 'admin_forum',
347 2
					],
348 2
					'regcenter' => [
349
						'label' => $txt['registration_center'],
350
						'controller' => ManageRegistration::class,
351
						'function' => 'action_index',
352 2
						'class' => 'i-user-plus i-admin',
353 2
						'permission' => ['admin_forum', 'moderate_forum'],
354 2
						'subsections' => [
355 2
							'register' => [$txt['admin_browse_register_new'], 'moderate_forum'],
356 2
							'agreement' => [$txt['registration_agreement'], 'admin_forum'],
357
							'privacypol' => [$txt['privacy_policy'], 'admin_forum'],
358
							'reservednames' => [$txt['admin_reserved_set'], 'admin_forum'],
359 2
							'settings' => [$txt['settings'], 'admin_forum'],
360 2
						],
361 2
					],
362 2
					'paidsubscribe' => [
363 2
						'label' => $txt['paid_subscriptions'],
364 2
						'enabled' => featureEnabled('ps'),
365
						'controller' => ManagePaid::class,
366
						'class' => 'i-credit i-admin',
367
						'function' => 'action_index',
368 2
						'permission' => 'admin_forum',
369 2
						'subsections' => [
370 2
							'view' => [$txt['paid_subs_view']],
371 2
							'settings' => [$txt['settings']],
372 2
						],
373
					],
374
					'karma' => [
375 2
						'label' => $txt['karma'],
376 2
						'enabled' => featureEnabled('k'),
377 2
						'controller' => ManageKarma::class,
378 2
						'class' => 'i-karma i-admin',
379 2
						'function' => 'action_index',
380
						'permission' => 'admin_forum',
381
					],
382
				],
383 2
			],
384 2
			'settings' => [
385 2
				'title' => $txt['admin_config'],
386 2
				'permission' => ['admin_forum'],
387 2
				'areas' => [
388
					'application' => [
389
						'label' => $txt['core_settings_title'],
390 2
						'controller' => CoreFeatures::class,
391 2
						'function' => 'action_index',
392 2
						'class' => 'i-switch-on i-admin',
393 2
					],
394
					'featuresettings' => [
395
						'label' => $txt['core_settings'],
396
						'controller' => ManageFeatures::class,
397
						'function' => 'action_index',
398
						'class' => 'i-tools i-admin',
399 2
						'subsections' => [
400
							'basic' => [$txt['general_settings']],
401
							'profile' => [$txt['custom_profile_shorttitle'], 'enabled' => featureEnabled('cp')],
402
							'pmsettings' => [$txt['personal_messages'], 'controller' => ManagePmSettings::class],
403 2
							'pwa' => [$txt['pwa_settings'], 'controller' => ManagePwa::class],
404 2
							'mentions' => [$txt['notifications'], 'controller' => ManageMentions::class],
405 2
						],
406 2
					],
407 2
					'layout' => [
408
						'label' => $txt['mods_cat_layout'],
409
						'controller' => ManageLayout::class,
410 2
						'function' => 'action_index',
411 2
						'class' => 'i-paint i-admin',
412
					],
413
					'themes' => [
414
						'label' => $txt['theme_admin'],
415 2
						'controller' => ManageThemes::class,
416 2
						'function' => 'action_index',
417 2
						'class' => 'i-modify i-admin',
418 2
						'subsections' => [
419 2
							'admin' => [$txt['themeadmin_admin_title']],
420
							'list' => [$txt['themeadmin_list_title']],
421
							'reset' => [$txt['themeadmin_reset_title']],
422 2
						],
423 2
					],
424 2
					'languages' => [
425
						'label' => $txt['language_configuration'],
426
						'controller' => ManageLanguages::class,
427
						'function' => 'action_index',
428 2
						'class' => 'i-language i-admin',
429 2
						'subsections' => [
430 2
							'edit' => [$txt['language_edit']],
431 2
							'settings' => [$txt['language_settings']],
432 2
						],
433
					],
434
				],
435 2
			],
436 2
			'system_moderation' => [
437 2
				'title' => $txt['admin_system_moderation'],
438 2
				'permission' => ['admin_forum'],
439 2
				'areas' => [
440
					'serversettings' => [
441
						'label' => $txt['admin_server_settings'],
442
						'controller' => ManageServer::class,
443 2
						'function' => 'action_index',
444 2
						'class' => 'i-menu i-admin',
445 2
						'subsections' => [
446 2
							'general' => [$txt['general_settings']],
447 2
							'database' => [$txt['database_paths_settings']],
448 2
							'cookie' => [$txt['cookies_sessions_settings']],
449
							'cache' => [$txt['caching_settings']],
450 2
							'loads' => [$txt['loadavg_settings']],
451 2
							'phpinfo' => [$txt['phpinfo_settings']],
452 2
						],
453 2
					],
454
					'securitysettings' => [
455
						'label' => $txt['admin_security_moderation'],
456
						'controller' => ManageSecurity::class,
457 2
						'function' => 'action_index',
458 2
						'class' => 'i-key i-admin',
459 2
						'subsections' => [
460 2
							'general' => [$txt['mods_cat_security_general']],
461 2
							'spam' => [$txt['antispam_title']],
462
						],
463
					],
464 2
					'maintain' => [
465 2
						'label' => $txt['maintain_title'],
466 2
						'controller' => Maintenance::class,
467 2
						'function' => 'action_index',
468 2
						'class' => 'i-cog i-admin',
469
						'subsections' => [
470
							'routine' => [$txt['maintain_sub_routine'], 'admin_forum'],
471
							'database' => [$txt['maintain_sub_database'], 'admin_forum'],
472 2
							'members' => [$txt['maintain_sub_members'], 'admin_forum'],
473 2
							'topics' => [$txt['maintain_sub_topics'], 'admin_forum'],
474 2
							'hooks' => [$txt['maintain_sub_hooks_list'], 'admin_forum'],
475 2
							'attachments' => [$txt['maintain_sub_attachments'], 'admin_forum'],
476 2
						],
477 2
					],
478 2
					'logs' => [
479
						'label' => $txt['logs'],
480 2
						'controller' => AdminLog::class,
481 2
						'function' => 'action_index',
482 2
						'class' => 'i-comments i-admin',
483 2
						'subsections' => [
484
							'errorlog' => [$txt['errlog'], 'admin_forum', 'enabled' => !empty($modSettings['enableErrorLogging'])],
485
							'adminlog' => [$txt['admin_log'], 'admin_forum', 'enabled' => featureEnabled('ml')],
486
							'modlog' => [$txt['moderation_log'], 'admin_forum', 'enabled' => featureEnabled('ml')],
487 2
							'banlog' => [$txt['ban_log'], 'manage_bans'],
488 2
							'spiderlog' => [$txt['spider_logs'], 'admin_forum', 'enabled' => featureEnabled('sp')],
489 2
							'tasklog' => [$txt['scheduled_log'], 'admin_forum'],
490 2
							'pruning' => [$txt['settings'], 'admin_forum'],
491 2
						],
492 2
					],
493 2
					'scheduledtasks' => [
494
						'label' => $txt['maintain_tasks'],
495 2
						'controller' => ManageScheduledTasks::class,
496 2
						'function' => 'action_index',
497
						'class' => 'i-calendar i-admin',
498
						'subsections' => [
499
							'tasks' => [$txt['maintain_tasks'], 'admin_forum'],
500
							'tasklog' => [$txt['scheduled_log'], 'admin_forum'],
501
						],
502 2
					],
503
					'sengines' => [
504
						'label' => $txt['search_engines'],
505
						'enabled' => featureEnabled('sp'),
506 2
						'controller' => ManageSearchEngines::class,
507 2
						'function' => 'action_index',
508 2
						'class' => 'i-website i-admin',
509 2
						'permission' => 'admin_forum',
510 2
						'subsections' => [
511
							'stats' => [$txt['spider_stats']],
512 2
							'logs' => [$txt['spider_logs']],
513 2
							'spiders' => [$txt['spiders']],
514 2
							'settings' => [$txt['settings']],
515 2
						],
516 2
					],
517 2
					'reports' => [
518
						'label' => $txt['generate_reports'],
519
						'controller' => Reports::class,
520
						'function' => 'action_index',
521 2
						'class' => 'i-pie-chart i-admin',
522 2
						'enabled' => featureEnabled('rg'),
523 2
					],
524 2
					'repairboards' => [
525 2
						'label' => $txt['admin_repair'],
526
						'controller' => RepairBoards::class,
527 2
						'function' => 'action_repairboards',
528 2
						'select' => 'maintain',
529 2
						'hidden' => true,
530 2
					],
531 2
				],
532 2
			],
533 2
			'addons' => [
534 2
				'title' => $txt['admin_modifications'],
535
				'permission' => ['admin_forum'],
536
				'areas' => [
537
					'packages' => [
538 2
						'label' => $txt['package'],
539 2
						'controller' => Packages::class,
540 2
						'function' => 'action_index',
541 2
						'permission' => ['admin_forum'],
542 2
						'class' => 'i-package i-admin',
543
						'subsections' => [
544 2
							'browse' => [$txt['browse_packages']],
545 2
							'servers' => [$txt['add_packages']],
546
							'options' => [$txt['package_settings']],
547
						],
548
					],
549 2
					'packageservers' => [
550 2
						'label' => $txt['package_servers'],
551 2
						'controller' => PackageServers::class,
552 2
						'function' => 'action_index',
553 2
						'permission' => ['admin_forum'],
554
						'class' => 'i-package i-admin',
555 2
						'hidden' => true,
556 2
					],
557
					'addonsettings' => [
558
						'label' => $txt['admin_modifications_settings'],
559
						'controller' => AddonSettings::class,
560 2
						'function' => 'action_index',
561 2
						'class' => 'i-puzzle i-admin',
562 2
						'subsections' => [
563 2
							'general' => [$txt['mods_cat_modifications_misc']],
564 2
						],
565 2
					],
566
				],
567
			],
568 2
		];
569 2
570 2
		$this->_events->trigger('addMenu', ['admin_areas' => &$admin_areas]);
571 2
572
		// Any files to include for administration?
573
		call_integration_include_hook('integrate_admin_include');
574
575
		$menuOptions = [
576
			'hook' => 'admin',
577
		];
578 2
579
		// Actually create the admin menu!
580
		$admin_include_data = (new Menu())
581 2
			->addMenuData($admin_areas)
582
			->addOptions($menuOptions)
583
			->prepareMenu()
584 2
			->setContext()
585
			->getIncludeData();
586
587
		unset($admin_areas);
588 2
589 2
		// Make a note of the Unique ID for this menu.
590 2
		$context['admin_menu_id'] = $context['max_menu_id'];
591 2
		$context['admin_menu_name'] = 'menu_data_' . $context['admin_menu_id'];
592 2
593 2
		// Where in the admin are we?
594
		$context['admin_area'] = $admin_include_data['current_area'];
595
596 2
		return $admin_include_data;
597 2
	}
598
599
	/**
600 2
	 * Builds out the navigation link tree for the admin area
601
	 *
602 2
	 * @param array $admin_include_data
603
	 */
604
	private function buildBreadCrumbs(array $admin_include_data): void
605
	{
606
		global $txt, $context;
607
608
		// Build the link tree.
609
		$context['breadcrumbs'][] = [
610
			'url' => getUrl('admin', ['action' => 'admin']),
611
			'name' => $txt['admin_center'],
612
		];
613
614
		if (isset($admin_include_data['current_area']) && $admin_include_data['current_area'] !== 'index')
615
		{
616
			$context['breadcrumbs'][] = [
617
				'url' => getUrl('admin', ['action' => 'admin', 'area' => $admin_include_data['current_area'], '{session_data}']),
618
				'name' => $admin_include_data['label'],
619
			];
620
		}
621
622
		if (!isset($admin_include_data['current_subsection'], $admin_include_data['subsections'][$admin_include_data['current_subsection']]))
623
		{
624
			return;
625
		}
626
627
		if ($admin_include_data['subsections'][$admin_include_data['current_subsection']]['label'] === $admin_include_data['label'])
628
		{
629
			return;
630
		}
631
632
		$context['breadcrumbs'][] = [
633
			'url' => getUrl('admin', ['action' => 'admin', 'area' => $admin_include_data['current_area'], 'sa' => $admin_include_data['current_subsection'], '{session_data}']),
634
			'name' => $admin_include_data['subsections'][$admin_include_data['current_subsection']]['label'],
635
		];
636
	}
637
638
	/**
639
	 * The main administration section.
640
	 *
641
	 * What it does:
642
	 *
643
	 * - It prepares all the data necessary for the administration front page.
644
	 * - It uses the Admin template along with the admin sub template.
645
	 * - It requires the moderate_forum, manage_membergroups, manage_bans,
646
	 * admin_forum, manage_permissions, manage_attachments, manage_smileys,
647
	 * manage_boards, edit_news, or send_mail permission.
648
	 * - It uses the index administrative area.
649
	 * - Accessed by ?action=admin.
650
	 */
651
	public function action_home(): void
652
	{
653
		global $txt, $context;
654
655
		// We need a little help
656
		require_once(SUBSDIR . '/Membergroups.subs.php');
657
658
		// You have to be able to do at least one of the below to see this page.
659
		isAllowedTo(['admin_forum', 'manage_permissions', 'moderate_forum', 'manage_membergroups', 'manage_bans', 'send_mail', 'edit_news', 'manage_boards', 'manage_smileys', 'manage_attachments']);
660
661
		// Find all of this forum's administrators...
662
		if (listMembergroupMembers_Href($context['administrators'], 1, 32) && allowedTo('manage_membergroups'))
663
		{
664
			// Add a 'more'-link if there are more than 32.
665
			$context['more_admins_link'] = '<a href="' . getUrl('moderate', ['action' => 'moderate', 'area' => 'viewgroups', 'sa' => 'members', 'group' => 1]) . '">' . $txt['more'] . '</a>';
666
		}
667
668
		// This makes it easier to get the latest news with your time format.
669
		$context['time_format'] = urlencode($this->user->time_format);
0 ignored issues
show
Bug introduced by
It seems like $this->user->time_format can also be of type null; however, parameter $string of urlencode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

669
		$context['time_format'] = urlencode(/** @scrutinizer ignore-type */ $this->user->time_format);
Loading history...
Bug Best Practice introduced by
The property time_format does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
670
		$context['forum_version'] = FORUM_VERSION;
671
672
		// Get a list of current server versions.
673
		$context['current_versions'] = getServerVersions($this->_checkFor);
674
		$context['can_admin'] = allowedTo('admin_forum');
675
		$context['sub_template'] = 'admin';
676
		$context['page_title'] = $txt['admin_center'];
677
		$context[$context['admin_menu_name']]['object']->prepareTabData([
678
			'title' => 'admin_center',
679
			'description' => '
680
				<span class="bbc_strong">' . $txt['hello_guest'] . ' ' . $context['user']['name'] . '!</span>
681
				' . sprintf($txt['admin_main_welcome'], $txt['admin_control_panel']),
682
		]);
683
684
		// Load in the admin quick tasks
685
		$context['quick_admin_tasks'] = getQuickAdminTasks();
686
	}
687
688
	/**
689
	 * The credits section in admin panel.
690
	 *
691
	 * What it does:
692
	 *
693
	 * - Determines the current level of support functions from the server, such as
694
	 * current level of caching engine or graphics library's installed.
695
	 * - Accessed by ?action=admin;area=credits
696
	 */
697
	public function action_credits(): void
698
	{
699
		global $txt, $context;
700
701
		// You have to be able to do at least one of the below to see this page.
702
		isAllowedTo(['admin_forum', 'manage_permissions', 'moderate_forum', 'manage_membergroups', 'manage_bans', 'send_mail', 'edit_news', 'manage_boards', 'manage_smileys', 'manage_attachments']);
703
704
		// We need a little help from our friends
705
		require_once(SUBSDIR . '/Membergroups.subs.php');
706
		require_once(SUBSDIR . '/Who.subs.php');
707
		require_once(SUBSDIR . '/Admin.subs.php');
708
		require_once(SUBSDIR . '/About.subs.php');
709
710
		// Find all of this forum's administrators...
711
		if (listMembergroupMembers_Href($context['administrators'], 1, 32) && allowedTo('manage_membergroups'))
712
		{
713
			// Add a 'more'-link if there are more than 32.
714
			$context['more_admins_link'] = '<a href="' . getUrl('moderate', ['action' => 'moderate', 'area' => 'viewgroups', 'sa' => 'members', 'group' => 1]) . '">' . $txt['more'] . '</a>';
715
		}
716
717
		// Load credits.
718
		$context[$context['admin_menu_name']]['object']->prepareTabData([
719
			'title' => 'support_credits_title',
720
			'description' => 'support_credits_desc',
721
		]);
722
723
		Txt::load('About');
724
		$context += prepareCreditsData();
725
726
		// This makes it easier to get the latest news with your time format.
727
		$context['time_format'] = urlencode($this->user->time_format);
0 ignored issues
show
Bug introduced by
It seems like $this->user->time_format can also be of type null; however, parameter $string of urlencode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

727
		$context['time_format'] = urlencode(/** @scrutinizer ignore-type */ $this->user->time_format);
Loading history...
Bug Best Practice introduced by
The property time_format does not exist on ElkArte\Helper\ValuesContainer. Since you implemented __get, consider adding a @property annotation.
Loading history...
728
		$context['forum_version'] = FORUM_VERSION;
729
730
		// Get a list of current server versions.
731
		$context['current_versions'] = getServerVersions($this->_checkFor);
732
		$context['can_admin'] = allowedTo('admin_forum');
733
		$context['sub_template'] = 'credits';
734
		$context['page_title'] = $txt['support_credits_title'];
735
736
		// Load in the admin quick tasks
737
		$context['quick_admin_tasks'] = getQuickAdminTasks();
738
739
		$index = 'new_in_' . str_replace(['ElkArte ', '.'], ['', '_'], FORUM_VERSION);
740
		if (isset($txt[$index]))
741
		{
742
			$context['latest_updates'] = replaceBasicActionUrl($txt[$index]);
743
			require_once(SUBSDIR . '/Themes.subs.php');
744
745
			updateThemeOptions([1, $this->user->id, 'dismissed_' . $index, 1]);
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...
746
		}
747
	}
748
749
	/**
750
	 * This function allocates out all the search stuff.
751
	 *
752
	 * What it does:
753
	 *
754
	 * - Accessed with /index.php?action=admin;area=search[;search_type=x]
755
	 * - Sets up an array of applicable sub-actions (search types) and the function that goes with each
756
	 * - Search type specified by "search_type" request variable (either from a
757
	 * form or from the query string) Defaults to 'internal'
758
	 * - Calls the appropriate sub action based on the search_type
759
	 */
760
	public function action_search(): void
761
	{
762
		global $txt, $context;
763
764
		// What can we search for?
765
		$subActions = [
766
			'internal' => [$this, 'action_search_internal', 'permission' => 'admin_forum'],
767
			'online' => [$this, 'action_search_doc', 'permission' => 'admin_forum'],
768
			'member' => [$this, 'action_search_member', 'permission' => 'admin_forum'],
769
		];
770
771
		// Set the subaction
772
		$action = new Action('admin_search');
773
		$subAction = $action->initialize($subActions, 'internal');
774
775
		// Keep track of what the admin wants in terms of advanced or not
776
		if (empty($context['admin_preferences']['sb']) || $context['admin_preferences']['sb'] !== $subAction)
777
		{
778
			$context['admin_preferences']['sb'] = $subAction;
779
780
			// Update the preferences.
781
			require_once(SUBSDIR . '/Admin.subs.php');
782
			updateAdminPreferences();
783
		}
784
785
		// Setup for the template
786
		$context['search_type'] = $subAction;
787
		$context['search_term'] = $this->_req->getPost('search_term', 'trim|Util::htmlspecialchars[ENT_QUOTES]');
788
		$context['sub_template'] = 'admin_search_results';
789
		$context['page_title'] = $txt['admin_search_results'];
790
791
		// You did remember to enter something to search for, otherwise it's easy
792
		if ($context['search_term'] === '')
793
		{
794
			$context['search_results'] = [];
795
		}
796
		else
797
		{
798
			$action->dispatch($subAction);
799
		}
800
	}
801
802
	/**
803
	 * A complicated but relatively quick internal search.
804
	 *
805
	 * What it does:
806
	 *
807
	 * - Can be accessed with /index.php?action=admin;sa=search;search_term=x) or from the admin search form ("Task/Setting" option).
808
	 * - Polls the controllers for their configuration settings.
809
	 * - Calls integrate_admin_search to allow addons to add search configs.
810
	 * - Loads up the "Help" language file and all "Manage" language files.
811
	 * - Loads up information about each item it found for the template.
812
	 *
813
	 * @event integrate_admin_search Allows integration to add areas to the internal admin search
814
	 * @event search Allows active modules registered to search to add settings for internal search
815
	 */
816
	public function action_search_internal(): void
817 2
	{
818
		global $context, $txt;
819 2
820
		// Try to get some more memory.
821
		detectServer()->setMemoryLimit('128M');
822 2
823
		// Load a lot of language files.
824
		$language_files = [
825
			'Help', 'ManageMail', 'ManageSettings', 'ManageBoards', 'ManagePaid', 'ManagePermissions', 'Search',
826 2
			'Login', 'ManageSmileys', 'Maillist', 'Mentions', 'Addons'
827
		];
828
829
		// All the files we need to include to search for settings
830
		$include_files = [];
831 2
832
		// This is a special array of functions that contain setting data
833
		// - we query all these to simply pull all setting bits!
834
		$settings_search = [
835
			['settings_search', 'area=addonsettings;sa=general', AddonSettings::class],
836 2
			['settings_search', 'area=logs;sa=pruning', AdminLog::class],
837
			['config_vars', 'area=corefeatures', CoreFeatures::class],
838
			['settings_search', 'area=manageattachments;sa=attachments', ManageAttachments::class],
839
			['settings_search', 'area=manageattachments;sa=avatars', ManageAvatars::class],
840
			['settings_search', 'area=manageboards;sa=settings', ManageBoards::class],
841
			['settings_search', 'area=postsettings;sa=bbc', ManageEditor::class],
842
			['basicSettings_search', 'area=featuresettings;sa=basic', ManageFeatures::class],
843
			['layoutSettings_search', 'area=featuresettings;sa=layout', ManageLayout::class],
844
			['pwaSettings_search', 'area=featuresettings;sa=pwa', ManagePwa::class],
845
			['karmaSettings_search', 'area=karma', ManageKarma::class],
846
			['pmSettings_search', 'area=featuresettings;sa=pmsettings', ManagePmSettings::class],
847
			['likesSettings_search', 'area=likes', ManageLikes::class],
848
			['mentionSettings_search', 'area=featuresettings;sa=mentions', ManageMentions::class],
849
			['signatureSettings_search', 'area=featuresettings;sa=sig', ManageSignature::class],
850
			['settings_search', 'area=languages;sa=settings', ManageLanguages::class],
851
			['settings_search', 'area=mailqueue;sa=settings', ManageMail::class],
852
			['settings_search', 'area=maillist;sa=emailsettings', ManageMaillist::class],
853
			['filter_search', 'area=maillist;sa=emailsettings', ManageMaillist::class],
854
			['parser_search', 'area=maillist;sa=emailsettings', ManageMaillist::class],
855
			['settings_search', 'area=membergroups;sa=settings', ManageMembergroups::class],
856
			['settings_search', 'area=news;sa=settings', ManageNews::class],
857
			['settings_search', 'area=paidsubscribe;sa=settings', ManagePaid::class],
858
			['settings_search', 'area=permissions;sa=settings', ManagePermissions::class],
859
			['settings_search', 'area=postsettings;sa=posts', ManagePosts::class],
860
			['settings_search', 'area=regcenter;sa=settings', ManageRegistration::class],
861
			['settings_search', 'area=managesearch;sa=settings', ManageSearch::class],
862
			['settings_search', 'area=sengines;sa=settings', ManageSearchEngines::class],
863
			['securitySettings_search', 'area=securitysettings;sa=general', ManageSecurity::class],
864
			['spamSettings_search', 'area=securitysettings;sa=spam', ManageSecurity::class],
865
			['warningSettings_search', 'area=warnings', ManageWarnings::class],
866
			['generalSettings_search', 'area=serversettings;sa=general', ManageServer::class],
867
			['databaseSettings_search', 'area=serversettings;sa=database', ManageServer::class],
868
			['cookieSettings_search', 'area=serversettings;sa=cookie', ManageServer::class],
869
			['cacheSettings_search', 'area=serversettings;sa=cache', ManageServer::class],
870
			['balancingSettings_search', 'area=serversettings;sa=loads', ManageServer::class],
871
			['settings_search', 'area=smileys;sa=settings', ManageSmileys::class],
872
			['settings_search', 'area=postsettings;sa=topics', ManageTopics::class],
873
		];
874 2
875
		// Allow integration to add settings to search
876
		call_integration_hook('integrate_admin_search', [&$language_files, &$include_files, &$settings_search]);
877 2
878
		// Allow active modules to add settings for internal search
879
		$this->_events->trigger('addSearch', ['language_files' => &$language_files, 'include_files' => &$include_files, 'settings_search' => &$settings_search]);
880 2
881 2
		// Go through all the search data trying to find this text!
882 2
		$context['search_results'] = [];
883 2
		if (isset($context['search_term']))
884
		{
885
			$search_term = strtolower(un_htmlspecialchars($context['search_term']));
886
			$search = new AdminSettingsSearch($language_files, $include_files, $settings_search);
887 2
			$search->initSearch($context['admin_menu_name'], [
888 2
				['COPPA', 'area=regcenter;sa=settings'],
889 2
				['CAPTCHA', 'area=securitysettings;sa=spam'],
890
			]);
891
			$context['search_results'] = $search->doSearch($search_term);
892
		}
893
894
		$context['page_title'] = $txt['admin_search_results'];
895
	}
896
897
	/**
898
	 * All this does is pass-through to manage members.
899
	 */
900
	public function action_search_member(): void
901
	{
902
		global $context;
903
904
		// @todo once Action.class is changed
905
		$_REQUEST['sa'] = 'query';
906
907
		// Set the query values
908
		$this->_req->post->sa = 'query';
909
		$this->_req->post->membername = un_htmlspecialchars($context['search_term']);
910
		$this->_req->post->types = '';
911
912
		$manageMembers = new ManageMembers(new EventManager());
913
		$manageMembers->setUser(User::$info);
914
		$manageMembers->pre_dispatch();
915
		$manageMembers->action_index();
916
	}
917
918
	/**
919
	 * This file allows the user to search the wiki documentation for a little help.
920
	 *
921
	 * What it does:
922
	 *   - Creates an exception since GitHub does not yet support API wiki searches, so the connection
923
	 * will fail.
924
	 */
925
	public function action_search_doc(): void
926
	{
927
		global $context;
928
929
		$context['doc_apiurl'] = 'https://github.com/elkarte/Elkarte/wiki/api.php';
930
		$context['doc_scripturl'] = 'https://github.com/elkarte/Elkarte/wiki/';
931
932
		// Set all the parameters search might expect.
933
		$postVars = explode(' ', $context['search_term']);
934
935
		// Encode the search data.
936
		foreach ($postVars as $k => $v)
937
		{
938
			$postVars[$k] = urlencode($v);
939
		}
940
941
		// This is what we will send.
942
		$postVars = implode('+', $postVars);
943
944
		// Get the results from the doc site.
945
		require_once(SUBSDIR . '/Package.subs.php');
946
		// Demo URL:
947
		// https://github.com/elkarte/Elkarte/wiki/api.php?action=query&list=search&srprop=timestamp|snippet&format=xml&srwhat=text&srsearch=template+eval
948
		$search_results = fetch_web_data($context['doc_apiurl'] . '?action=query&list=search&srprop=timestamp|snippet&format=xml&srwhat=text&srsearch=' . $postVars);
949
950
		// If we didn't get any XML back, we are in trouble - perhaps the doc site is overloaded?
951
		if (!$search_results || preg_match('~<\?xml\sversion="\d+\.\d+"\?>\s*(<api>.+?</api>)~is', $search_results, $matches) !== 1)
952
		{
953
			throw new Exception('cannot_connect_doc_site');
954
		}
955
956
		$search_results = empty($matches[1]) ? '' : $matches[1];
957
958
		// Otherwise we simply walk through the XML and stick it in context for display.
959
		$context['search_results'] = [];
960
961
		// Get the results loaded into an array for processing!
962
		$results = new XmlArray($search_results, false);
963
964
		// Move through the api layer.
965
		if (!$results->exists('api'))
966
		{
967
			throw new Exception('cannot_connect_doc_site');
968
		}
969
970
		// Are there actually some results?
971
		if ($results->exists('api/query/search/p'))
972
		{
973
			$relevance = 0;
974
			foreach ($results->set('api/query/search/p') as $result)
975
			{
976
				$title = $result->fetch('@title');
977
				$context['search_results'][$title] = [
978
					'title' => $title,
979
					'relevance' => $relevance++,
980
					'snippet' => str_replace("class='searchmatch'", 'class="highlight"', un_htmlspecialchars($result->fetch('@snippet'))),
981
				];
982
			}
983
		}
984
	}
985
986
	/**
987
	 * This ends an admin session, requiring authentication to access the ACP again.
988
	 */
989
	public function action_endsession(): void
990
	{
991
		// This is so easy!
992
		unset($_SESSION['admin_time']);
993
994
		// Clean any admin tokens as well.
995
		cleanTokens(false, '-admin');
996
997
		if (isset($this->_req->query->redir, $_SERVER['HTTP_REFERER']))
998
		{
999
			redirectexit($_SERVER['HTTP_REFERER']);
1000
		}
1001
1002
		redirectexit();
1003
	}
1004
}
1005