Issues (1686)

sources/ElkArte/AdminController/Admin.php (5 issues)

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

641
		$context['time_format'] = urlencode(/** @scrutinizer ignore-type */ $this->user->time_format);
Loading history...
642
		$context['forum_version'] = FORUM_VERSION;
643
644
		// Get a list of current server versions.
645
		$context['current_versions'] = getServerVersions($this->_checkFor);
646
		$context['can_admin'] = allowedTo('admin_forum');
647
		$context['sub_template'] = 'admin';
648
		$context['page_title'] = $txt['admin_center'];
649
		$context[$context['admin_menu_name']]['object']->prepareTabData([
650
			'title' => 'admin_center',
651
			'description' => '
652
				<span class="bbc_strong">' . $txt['hello_guest'] . ' ' . $context['user']['name'] . '!</span>
653
				' . sprintf($txt['admin_main_welcome'], $txt['admin_control_panel']),
654
		]);
655
656
		// Load in the admin quick tasks
657
		$context['quick_admin_tasks'] = getQuickAdminTasks();
658
	}
659
660
	/**
661
	 * The credits section in admin panel.
662
	 *
663
	 * What it does:
664
	 *
665
	 * - Determines the current level of support functions from the server, such as
666
	 * current level of caching engine or graphics library's installed.
667
	 * - Accessed by ?action=admin;area=credits
668
	 */
669
	public function action_credits()
670
	{
671
		global $txt, $context;
672
673
		// We need a little help from our friends
674
		require_once(SUBSDIR . '/Membergroups.subs.php');
675
		require_once(SUBSDIR . '/Who.subs.php');
676
		require_once(SUBSDIR . '/Admin.subs.php');
677
678
		// You have to be able to do at least one of the below to see this page.
679
		isAllowedTo(array('admin_forum', 'manage_permissions', 'moderate_forum', 'manage_membergroups', 'manage_bans', 'send_mail', 'edit_news', 'manage_boards', 'manage_smileys', 'manage_attachments'));
680
681
		// Find all of this forum's administrators...
682
		if (listMembergroupMembers_Href($context['administrators'], 1, 32) && allowedTo('manage_membergroups'))
683
		{
684
			// Add a 'more'-link if there are more than 32.
685
			$context['more_admins_link'] = '<a href="' . getUrl('moderate', ['action' => 'moderate', 'area' => 'viewgroups', 'sa' => 'members', 'group' => 1]) . '">' . $txt['more'] . '</a>';
686
		}
687
688
		// Load credits.
689
		$context[$context['admin_menu_name']]['object']->prepareTabData([
690
			'title' => 'support_credits_title',
691
			'description' => 'support_credits_desc',
692
		]);
693
		Txt::load('About');
694
		require_once(SUBSDIR . '/About.subs.php');
695
		$context += prepareCreditsData();
696
697
		// This makes it easier to get the latest news with your time format.
698
		$context['time_format'] = urlencode($this->user->time_format);
0 ignored issues
show
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...
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

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