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

Admin.php ➔ AdminMain()   F

Complexity

Conditions 15
Paths 1024

Size

Total Lines 472
Code Lines 362

Duplication

Lines 15
Ratio 3.18 %

Importance

Changes 0
Metric Value
cc 15
eloc 362
nc 1024
nop 0
dl 15
loc 472
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * This file, unpredictable as this might be, handles basic administration.
5
 *
6
 * Simple Machines Forum (SMF)
7
 *
8
 * @package SMF
9
 * @author Simple Machines http://www.simplemachines.org
10
 * @copyright 2017 Simple Machines and individual contributors
11
 * @license http://www.simplemachines.org/about/smf/license.php BSD
12
 *
13
 * @version 2.1 Beta 4
14
 */
15
16
if (!defined('SMF'))
17
	die('No direct access...');
18
19
/**
20
 * The main admin handling function.<br>
21
 * It initialises all the basic context required for the admin center.<br>
22
 * It passes execution onto the relevant admin section.<br>
23
 * If the passed section is not found it shows the admin home page.
24
 */
25
function AdminMain()
26
{
27
	global $txt, $context, $scripturl, $modSettings, $settings;
28
	global $smcFunc, $sourcedir, $options, $boarddir;
29
30
	// Load the language and templates....
31
	loadLanguage('Admin');
32
	loadTemplate('Admin');
33
	loadJavaScriptFile('admin.js', array(), 'smf_admin');
34
	loadCSSFile('admin.css', array(), 'smf_admin');
35
36
	// No indexing evil stuff.
37
	$context['robot_no_index'] = true;
38
39
	require_once($sourcedir . '/Subs-Menu.php');
40
41
	// Some preferences.
42
	$context['admin_preferences'] = !empty($options['admin_preferences']) ? $smcFunc['json_decode']($options['admin_preferences'], true) : array();
43
44
	/** @var array $admin_areas Defines the menu structure for the admin center. See {@link Subs-Menu.php Subs-Menu.php} for details! */
45
	$admin_areas = array(
46
		'forum' => array(
47
			'title' => $txt['admin_main'],
48
			'permission' => array('admin_forum', 'manage_permissions', 'moderate_forum', 'manage_membergroups', 'manage_bans', 'send_mail', 'edit_news', 'manage_boards', 'manage_smileys', 'manage_attachments'),
49
			'areas' => array(
50
				'index' => array(
51
					'label' => $txt['admin_center'],
52
					'function' => 'AdminHome',
53
					'icon' => 'administration',
54
				),
55
				'credits' => array(
56
					'label' => $txt['support_credits_title'],
57
					'function' => 'AdminHome',
58
					'icon' => 'support',
59
				),
60
				'news' => array(
61
					'label' => $txt['news_title'],
62
					'file' => 'ManageNews.php',
63
					'function' => 'ManageNews',
64
					'icon' => 'news',
65
					'permission' => array('edit_news', 'send_mail', 'admin_forum'),
66
					'subsections' => array(
67
						'editnews' => array($txt['admin_edit_news'], 'edit_news'),
68
						'mailingmembers' => array($txt['admin_newsletters'], 'send_mail'),
69
						'settings' => array($txt['settings'], 'admin_forum'),
70
					),
71
				),
72
				'packages' => array(
73
					'label' => $txt['package'],
74
					'file' => 'Packages.php',
75
					'function' => 'Packages',
76
					'permission' => array('admin_forum'),
77
					'icon' => 'packages',
78
					'subsections' => array(
79
						'browse' => array($txt['browse_packages']),
80
						'packageget' => array($txt['download_packages'], 'url' => $scripturl . '?action=admin;area=packages;sa=packageget;get'),
81
						'perms' => array($txt['package_file_perms']),
82
						'options' => array($txt['package_settings']),
83
					),
84
				),
85
				'search' => array(
86
					'function' => 'AdminSearch',
87
					'permission' => array('admin_forum'),
88
					'select' => 'index'
89
				),
90
				'adminlogoff' => array(
91
					'label' => $txt['admin_logoff'],
92
					'function' => 'AdminEndSession',
93
					'enabled' => empty($modSettings['securityDisable']),
94
					'icon' => 'exit',
95
				),
96
97
			),
98
		),
99
		'config' => array(
100
			'title' => $txt['admin_config'],
101
			'permission' => array('admin_forum'),
102
			'areas' => array(
103
				'featuresettings' => array(
104
					'label' => $txt['modSettings_title'],
105
					'file' => 'ManageSettings.php',
106
					'function' => 'ModifyFeatureSettings',
107
					'icon' => 'features',
108
					'subsections' => array(
109
						'basic' => array($txt['mods_cat_features']),
110
						'bbc' => array($txt['manageposts_bbc_settings']),
111
						'layout' => array($txt['mods_cat_layout']),
112
						'sig' => array($txt['signature_settings_short']),
113
						'profile' => array($txt['custom_profile_shorttitle']),
114
						'likes' => array($txt['likes']),
115
						'mentions' => array($txt['mentions']),
116
						'alerts' => array($txt['notifications']),
117
					),
118
				),
119
				'antispam' => array(
120
					'label' => $txt['antispam_title'],
121
					'file' => 'ManageSettings.php',
122
					'function' => 'ModifyAntispamSettings',
123
					'icon' => 'security',
124
				),
125
				'languages' => array(
126
					'label' => $txt['language_configuration'],
127
					'file' => 'ManageLanguages.php',
128
					'function' => 'ManageLanguages',
129
					'icon' => 'languages',
130
					'subsections' => array(
131
						'edit' => array($txt['language_edit']),
132
						'add' => array($txt['language_add']),
133
						'settings' => array($txt['language_settings']),
134
					),
135
				),
136
				'current_theme' => array(
137
					'label' => $txt['theme_current_settings'],
138
					'file' => 'Themes.php',
139
					'function' => 'ThemesMain',
140
					'custom_url' => $scripturl . '?action=admin;area=theme;sa=list;th=' . $settings['theme_id'],
141
					'icon' => 'current_theme',
142
				),
143
				'theme' => array(
144
					'label' => $txt['theme_admin'],
145
					'file' => 'Themes.php',
146
					'function' => 'ThemesMain',
147
					'custom_url' => $scripturl . '?action=admin;area=theme',
148
					'icon' => 'themes',
149
					'subsections' => array(
150
						'admin' => array($txt['themeadmin_admin_title']),
151
						'list' => array($txt['themeadmin_list_title']),
152
						'reset' => array($txt['themeadmin_reset_title']),
153
						'edit' => array($txt['themeadmin_edit_title']),
154
					),
155
				),
156
				'modsettings' => array(
157
					'label' => $txt['admin_modifications'],
158
					'file' => 'ManageSettings.php',
159
					'function' => 'ModifyModSettings',
160
					'icon' => 'modifications',
161
					'subsections' => array(
162
						'general' => array($txt['mods_cat_modifications_misc']),
163
						// Mod Authors for a "ADD AFTER" on this line. Ensure you end your change with a comma. For example:
164
						// 'shout' => array($txt['shout']),
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
165
						// Note the comma!! The setting with automatically appear with the first mod to be added.
166
					),
167
				),
168
			),
169
		),
170
		'layout' => array(
171
			'title' => $txt['layout_controls'],
172
			'permission' => array('manage_boards', 'admin_forum', 'manage_smileys', 'manage_attachments', 'moderate_forum'),
173
			'areas' => array(
174
				'manageboards' => array(
175
					'label' => $txt['admin_boards'],
176
					'file' => 'ManageBoards.php',
177
					'function' => 'ManageBoards',
178
					'icon' => 'boards',
179
					'permission' => array('manage_boards'),
180
					'subsections' => array(
181
						'main' => array($txt['boardsEdit']),
182
						'newcat' => array($txt['mboards_new_cat']),
183
						'settings' => array($txt['settings'], 'admin_forum'),
184
					),
185
				),
186
				'postsettings' => array(
187
					'label' => $txt['manageposts'],
188
					'file' => 'ManagePosts.php',
189
					'function' => 'ManagePostSettings',
190
					'permission' => array('admin_forum'),
191
					'icon' => 'posts',
192
					'subsections' => array(
193
						'posts' => array($txt['manageposts_settings']),
194
						'censor' => array($txt['admin_censored_words']),
195
						'topics' => array($txt['manageposts_topic_settings']),
196
						'drafts' => array($txt['manage_drafts']),
197
					),
198
				),
199
				'managecalendar' => array(
200
					'label' => $txt['manage_calendar'],
201
					'file' => 'ManageCalendar.php',
202
					'function' => 'ManageCalendar',
203
					'icon' => 'calendar',
204
					'permission' => array('admin_forum'),
205
					'inactive' => empty($modSettings['cal_enabled']),
206
					'subsections' => empty($modSettings['cal_enabled']) ? array() : array(
207
						'holidays' => array($txt['manage_holidays'], 'admin_forum'),
208
						'settings' => array($txt['calendar_settings'], 'admin_forum'),
209
					),
210
				),
211
				'managesearch' => array(
212
					'label' => $txt['manage_search'],
213
					'file' => 'ManageSearch.php',
214
					'function' => 'ManageSearch',
215
					'icon' => 'search',
216
					'permission' => array('admin_forum'),
217
					'subsections' => array(
218
						'weights' => array($txt['search_weights']),
219
						'method' => array($txt['search_method']),
220
						'settings' => array($txt['settings']),
221
					),
222
				),
223
				'smileys' => array(
224
					'label' => $txt['smileys_manage'],
225
					'file' => 'ManageSmileys.php',
226
					'function' => 'ManageSmileys',
227
					'icon' => 'smiley',
228
					'permission' => array('manage_smileys'),
229
					'subsections' => array(
230
						'editsets' => array($txt['smiley_sets']),
231
						'addsmiley' => array($txt['smileys_add'], 'enabled' => !empty($modSettings['smiley_enable'])),
232
						'editsmileys' => array($txt['smileys_edit'], 'enabled' => !empty($modSettings['smiley_enable'])),
233
						'setorder' => array($txt['smileys_set_order'], 'enabled' => !empty($modSettings['smiley_enable'])),
234
						'editicons' => array($txt['icons_edit_message_icons'], 'enabled' => !empty($modSettings['messageIcons_enable'])),
235
						'settings' => array($txt['settings']),
236
					),
237
				),
238
				'manageattachments' => array(
239
					'label' => $txt['attachments_avatars'],
240
					'file' => 'ManageAttachments.php',
241
					'function' => 'ManageAttachments',
242
					'icon' => 'attachment',
243
					'permission' => array('manage_attachments'),
244
					'subsections' => array(
245
						'browse' => array($txt['attachment_manager_browse']),
246
						'attachments' => array($txt['attachment_manager_settings']),
247
						'avatars' => array($txt['attachment_manager_avatar_settings']),
248
						'attachpaths' => array($txt['attach_directories']),
249
						'maintenance' => array($txt['attachment_manager_maintenance']),
250
					),
251
				),
252
				'sengines' => array(
253
					'label' => $txt['search_engines'],
254
					'inactive' => empty($modSettings['spider_mode']),
255
					'file' => 'ManageSearchEngines.php',
256
					'icon' => 'engines',
257
					'function' => 'SearchEngines',
258
					'permission' => 'admin_forum',
259
					'subsections' => empty($modSettings['spider_mode']) ? array() : array(
260
						'stats' => array($txt['spider_stats']),
261
						'logs' => array($txt['spider_logs']),
262
						'spiders' => array($txt['spiders']),
263
						'settings' => array($txt['settings']),
264
					),
265
				),
266
			),
267
		),
268
		'members' => array(
269
			'title' => $txt['admin_manage_members'],
270
			'permission' => array('moderate_forum', 'manage_membergroups', 'manage_bans', 'manage_permissions', 'admin_forum'),
271
			'areas' => array(
272
				'viewmembers' => array(
273
					'label' => $txt['admin_users'],
274
					'file' => 'ManageMembers.php',
275
					'function' => 'ViewMembers',
276
					'icon' => 'members',
277
					'permission' => array('moderate_forum'),
278
					'subsections' => array(
279
						'all' => array($txt['view_all_members']),
280
						'search' => array($txt['mlist_search']),
281
					),
282
				),
283
				'membergroups' => array(
284
					'label' => $txt['admin_groups'],
285
					'file' => 'ManageMembergroups.php',
286
					'function' => 'ModifyMembergroups',
287
					'icon' => 'membergroups',
288
					'permission' => array('manage_membergroups'),
289
					'subsections' => array(
290
						'index' => array($txt['membergroups_edit_groups'], 'manage_membergroups'),
291
						'add' => array($txt['membergroups_new_group'], 'manage_membergroups'),
292
						'settings' => array($txt['settings'], 'admin_forum'),
293
					),
294
				),
295
				'permissions' => array(
296
					'label' => $txt['edit_permissions'],
297
					'file' => 'ManagePermissions.php',
298
					'function' => 'ModifyPermissions',
299
					'icon' => 'permissions',
300
					'permission' => array('manage_permissions'),
301
					'subsections' => array(
302
						'index' => array($txt['permissions_groups'], 'manage_permissions'),
303
						'board' => array($txt['permissions_boards'], 'manage_permissions'),
304
						'profiles' => array($txt['permissions_profiles'], 'manage_permissions'),
305
						'postmod' => array($txt['permissions_post_moderation'], 'manage_permissions'),
306
						'settings' => array($txt['settings'], 'admin_forum'),
307
					),
308
				),
309
				'regcenter' => array(
310
					'label' => $txt['registration_center'],
311
					'file' => 'ManageRegistration.php',
312
					'function' => 'RegCenter',
313
					'icon' => 'regcenter',
314
					'permission' => array('admin_forum', 'moderate_forum'),
315
					'subsections' => array(
316
						'register' => array($txt['admin_browse_register_new'], 'moderate_forum'),
317
						'agreement' => array($txt['registration_agreement'], 'admin_forum'),
318
						'reservednames' => array($txt['admin_reserved_set'], 'admin_forum'),
319
						'settings' => array($txt['settings'], 'admin_forum'),
320
					),
321
				),
322
				'warnings' => array(
323
					'label' => $txt['warnings'],
324
					'file' => 'ManageSettings.php',
325
					'function' => 'ModifyWarningSettings',
326
					'icon' => 'warning',
327
					'inactive' => $modSettings['warning_settings'][0] == 0,
328
					'permission' => array('admin_forum'),
329
				),
330
				'ban' => array(
331
					'label' => $txt['ban_title'],
332
					'file' => 'ManageBans.php',
333
					'function' => 'Ban',
334
					'icon' => 'ban',
335
					'permission' => 'manage_bans',
336
					'subsections' => array(
337
						'list' => array($txt['ban_edit_list']),
338
						'add' => array($txt['ban_add_new']),
339
						'browse' => array($txt['ban_trigger_browse']),
340
						'log' => array($txt['ban_log']),
341
					),
342
				),
343
				'paidsubscribe' => array(
344
					'label' => $txt['paid_subscriptions'],
345
					'inactive' => empty($modSettings['paid_enabled']),
346
					'file' => 'ManagePaid.php',
347
					'icon' => 'paid',
348
					'function' => 'ManagePaidSubscriptions',
349
					'permission' => 'admin_forum',
350
					'subsections' => empty($modSettings['paid_enabled']) ? array() : array(
351
						'view' => array($txt['paid_subs_view']),
352
						'settings' => array($txt['settings']),
353
					),
354
				),
355
			),
356
		),
357
		'maintenance' => array(
358
			'title' => $txt['admin_maintenance'],
359
			'permission' => array('admin_forum'),
360
			'areas' => array(
361
				'serversettings' => array(
362
					'label' => $txt['admin_server_settings'],
363
					'file' => 'ManageServer.php',
364
					'function' => 'ModifySettings',
365
					'icon' => 'server',
366
					'subsections' => array(
367
						'general' => array($txt['general_settings']),
368
						'database' => array($txt['database_settings']),
369
						'cookie' => array($txt['cookies_sessions_settings']),
370
						'security' => array($txt['security_settings']),
371
						'cache' => array($txt['caching_settings']),
372
						'loads' => array($txt['load_balancing_settings']),
373
						'phpinfo' => array($txt['phpinfo_settings']),
374
					),
375
				),
376
				'maintain' => array(
377
					'label' => $txt['maintain_title'],
378
					'file' => 'ManageMaintenance.php',
379
					'icon' => 'maintain',
380
					'function' => 'ManageMaintenance',
381
					'subsections' => array(
382
						'routine' => array($txt['maintain_sub_routine'], 'admin_forum'),
383
						'database' => array($txt['maintain_sub_database'], 'admin_forum'),
384
						'members' => array($txt['maintain_sub_members'], 'admin_forum'),
385
						'topics' => array($txt['maintain_sub_topics'], 'admin_forum'),
386
						'hooks' => array($txt['hooks_title_list'], 'admin_forum'),
387
					),
388
				),
389
				'scheduledtasks' => array(
390
					'label' => $txt['maintain_tasks'],
391
					'file' => 'ManageScheduledTasks.php',
392
					'icon' => 'scheduled',
393
					'function' => 'ManageScheduledTasks',
394
					'subsections' => array(
395
						'tasks' => array($txt['maintain_tasks'], 'admin_forum'),
396
						'tasklog' => array($txt['scheduled_log'], 'admin_forum'),
397
					),
398
				),
399
				'mailqueue' => array(
400
					'label' => $txt['mailqueue_title'],
401
					'file' => 'ManageMail.php',
402
					'function' => 'ManageMail',
403
					'icon' => 'mail',
404
					'subsections' => array(
405
						'browse' => array($txt['mailqueue_browse'], 'admin_forum'),
406
						'settings' => array($txt['mailqueue_settings'], 'admin_forum'),
407
					),
408
				),
409
				'reports' => array(
410
					'label' => $txt['generate_reports'],
411
					'file' => 'Reports.php',
412
					'function' => 'ReportsMain',
413
					'icon' => 'reports',
414
				),
415
				'logs' => array(
416
					'label' => $txt['logs'],
417
					'function' => 'AdminLogs',
418
					'icon' => 'logs',
419
					'subsections' => array(
420
						'errorlog' => array($txt['errlog'], 'admin_forum', 'enabled' => !empty($modSettings['enableErrorLogging']), 'url' => $scripturl . '?action=admin;area=logs;sa=errorlog;desc'),
421
						'adminlog' => array($txt['admin_log'], 'admin_forum', 'enabled' => !empty($modSettings['adminlog_enabled'])),
422
						'modlog' => array($txt['moderation_log'], 'admin_forum', 'enabled' => !empty($modSettings['modlog_enabled'])),
423
						'banlog' => array($txt['ban_log'], 'manage_bans'),
424
						'spiderlog' => array($txt['spider_logs'], 'admin_forum', 'enabled' => !empty($modSettings['spider_mode'])),
425
						'tasklog' => array($txt['scheduled_log'], 'admin_forum'),
426
						'settings' => array($txt['log_settings'], 'admin_forum'),
427
					),
428
				),
429
				'repairboards' => array(
430
					'label' => $txt['admin_repair'],
431
					'file' => 'RepairBoards.php',
432
					'function' => 'RepairBoards',
433
					'select' => 'maintain',
434
					'hidden' => true,
435
				),
436
			),
437
		),
438
	);
439
440
	// Any files to include for administration?
441 View Code Duplication
	if (!empty($modSettings['integrate_admin_include']))
442
	{
443
		$admin_includes = explode(',', $modSettings['integrate_admin_include']);
444
		foreach ($admin_includes as $include)
445
		{
446
			$include = strtr(trim($include), array('$boarddir' => $boarddir, '$sourcedir' => $sourcedir, '$themedir' => $settings['theme_dir']));
447
			if (file_exists($include))
448
				require_once($include);
449
		}
450
	}
451
452
	// Make sure the administrator has a valid session...
453
	validateSession();
454
455
	// Actually create the menu!
456
	$admin_include_data = createMenu($admin_areas, array('do_big_icons' => true));
457
	unset($admin_areas);
458
459
	// Nothing valid?
460
	if ($admin_include_data == false)
461
		fatal_lang_error('no_access', false);
462
463
	// Build the link tree.
464
	$context['linktree'][] = array(
465
		'url' => $scripturl . '?action=admin',
466
		'name' => $txt['admin_center'],
467
	);
468
	if (isset($admin_include_data['current_area']) && $admin_include_data['current_area'] != 'index')
469
		$context['linktree'][] = array(
470
			'url' => $scripturl . '?action=admin;area=' . $admin_include_data['current_area'] . ';' . $context['session_var'] . '=' . $context['session_id'],
471
			'name' => $admin_include_data['label'],
472
		);
473 View Code Duplication
	if (!empty($admin_include_data['current_subsection']) && $admin_include_data['subsections'][$admin_include_data['current_subsection']][0] != $admin_include_data['label'])
474
		$context['linktree'][] = array(
475
			'url' => $scripturl . '?action=admin;area=' . $admin_include_data['current_area'] . ';sa=' . $admin_include_data['current_subsection'] . ';' . $context['session_var'] . '=' . $context['session_id'],
476
			'name' => $admin_include_data['subsections'][$admin_include_data['current_subsection']][0],
477
		);
478
479
	// Make a note of the Unique ID for this menu.
480
	$context['admin_menu_id'] = $context['max_menu_id'];
481
	$context['admin_menu_name'] = 'menu_data_' . $context['admin_menu_id'];
482
483
	// Where in the admin are we?
484
	$context['admin_area'] = $admin_include_data['current_area'];
485
486
	// Now - finally - call the right place!
487
	if (isset($admin_include_data['file']))
488
		require_once($sourcedir . '/' . $admin_include_data['file']);
489
490
	// Get the right callable.
491
	$call = call_helper($admin_include_data['function'], true);
492
493
	// Is it valid?
494
	if (!empty($call))
495
		call_user_func($call);
496
}
497
498
/**
499
 * The main administration section.
500
 * It prepares all the data necessary for the administration front page.
501
 * It uses the Admin template along with the admin sub template.
502
 * It requires the moderate_forum, manage_membergroups, manage_bans,
503
 *  admin_forum, manage_permissions, manage_attachments, manage_smileys,
504
 *  manage_boards, edit_news, or send_mail permission.
505
 *  It uses the index administrative area.
506
 *  It can be found by going to ?action=admin.
507
*/
508
function AdminHome()
509
{
510
	global $sourcedir, $forum_version, $txt, $scripturl, $context, $user_info;
511
512
	// You have to be able to do at least one of the below to see this page.
513
	isAllowedTo(array('admin_forum', 'manage_permissions', 'moderate_forum', 'manage_membergroups', 'manage_bans', 'send_mail', 'edit_news', 'manage_boards', 'manage_smileys', 'manage_attachments'));
514
515
	// Find all of this forum's administrators...
516
	require_once($sourcedir . '/Subs-Membergroups.php');
517
	if (listMembergroupMembers_Href($context['administrators'], 1, 32) && allowedTo('manage_membergroups'))
518
	{
519
		// Add a 'more'-link if there are more than 32.
520
		$context['more_admins_link'] = '<a href="' . $scripturl . '?action=moderate;area=viewgroups;sa=members;group=1">' . $txt['more'] . '</a>';
521
	}
522
523
	// Load the credits stuff.
524
	require_once($sourcedir . '/Who.php');
525
	Credits(true);
526
527
	// This makes it easier to get the latest news with your time format.
528
	$context['time_format'] = urlencode($user_info['time_format']);
529
	$context['forum_version'] = $forum_version;
530
531
	// Get a list of current server versions.
532
	require_once($sourcedir . '/Subs-Admin.php');
533
	$checkFor = array(
534
		'gd',
535
		'imagemagick',
536
		'db_server',
537
		'phpa',
538
		'apc',
539
		'memcache',
540
		'xcache',
541
		'php',
542
		'server',
543
	);
544
	$context['current_versions'] = getServerVersions($checkFor);
545
546
	$context['can_admin'] = allowedTo('admin_forum');
547
548
	$context['sub_template'] = $context['admin_area'] == 'credits' ? 'credits' : 'admin';
549
	$context['page_title'] = $context['admin_area'] == 'credits' ? $txt['support_credits_title'] : $txt['admin_center'];
550
	if ($context['admin_area'] != 'credits')
551
		$context[$context['admin_menu_name']]['tab_data'] = array(
552
			'title' => $txt['admin_center'],
553
			'help' => '',
554
			'description' => '<strong>' . $txt['hello_guest'] . ' ' . $context['user']['name'] . '!</strong>
555
						' . sprintf($txt['admin_main_welcome'], $txt['admin_center'], $txt['help'], $txt['help']),
556
		);
557
558
	// Lastly, fill in the blanks in the support resources paragraphs.
559
	$txt['support_resources_p1'] = sprintf($txt['support_resources_p1'],
560
		'https://wiki.simplemachines.org/',
561
		'https://wiki.simplemachines.org/smf/features2',
562
		'https://wiki.simplemachines.org/smf/options2',
563
		'https://wiki.simplemachines.org/smf/themes2',
564
		'https://wiki.simplemachines.org/smf/packages2'
565
	);
566
	$txt['support_resources_p2'] = sprintf($txt['support_resources_p2'],
567
		'https://www.simplemachines.org/community/',
568
		'https://www.simplemachines.org/redirect/english_support',
569
		'https://www.simplemachines.org/redirect/international_support_boards',
570
		'https://www.simplemachines.org/redirect/smf_support',
571
		'https://www.simplemachines.org/redirect/customize_support'
572
	);
573
574
	if ($context['admin_area'] == 'admin')
575
		loadJavaScriptFile('admin.js', array('defer' => false), 'smf_admin');
576
}
577
578
/**
579
 * Get one of the admin information files from Simple Machines.
580
 */
581
function DisplayAdminFile()
582
{
583
	global $context, $modSettings, $smcFunc;
584
585
	setMemoryLimit('32M');
586
587
	if (empty($_REQUEST['filename']) || !is_string($_REQUEST['filename']))
588
		fatal_lang_error('no_access', false);
589
590
	// Strip off the forum cache part or we won't find it...
591
	$_REQUEST['filename'] = str_replace($modSettings['browser_cache'], '', $_REQUEST['filename']);
592
593
	$request = $smcFunc['db_query']('', '
594
		SELECT data, filetype
595
		FROM {db_prefix}admin_info_files
596
		WHERE filename = {string:current_filename}
597
		LIMIT 1',
598
		array(
599
			'current_filename' => $_REQUEST['filename'],
600
		)
601
	);
602
603
	if ($smcFunc['db_num_rows']($request) == 0)
604
		fatal_lang_error('admin_file_not_found', true, array($_REQUEST['filename']), 404);
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string|false.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
605
606
	list ($file_data, $filetype) = $smcFunc['db_fetch_row']($request);
607
	$smcFunc['db_free_result']($request);
608
609
	// @todo Temp
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
610
	// Figure out if sesc is still being used.
611
	if (strpos($file_data, ';sesc=') !== false && $filetype == 'text/javascript')
612
		$file_data = '
613
if (!(\'smfForum_sessionvar\' in window))
614
	window.smfForum_sessionvar = \'sesc\';
615
' . strtr($file_data, array(';sesc=' => ';\' + window.smfForum_sessionvar + \'='));
616
617
	$context['template_layers'] = array();
618
	// Lets make sure we aren't going to output anything nasty.
619
	@ob_end_clean();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
620
	if (!empty($modSettings['enableCompressedOutput']))
621
		@ob_start('ob_gzhandler');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
622
	else
623
		@ob_start();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
624
625
	// Make sure they know what type of file we are.
626
	header('Content-Type: ' . $filetype);
627
	echo $file_data;
628
	obExit(false);
629
}
630
631
/**
632
 * This function allocates out all the search stuff.
633
 */
634
function AdminSearch()
635
{
636
	global $txt, $context, $smcFunc, $sourcedir;
637
638
	isAllowedTo('admin_forum');
639
640
	// What can we search for?
641
	$subActions = array(
642
		'internal' => 'AdminSearchInternal',
643
		'online' => 'AdminSearchOM',
644
		'member' => 'AdminSearchMember',
645
	);
646
647
	$context['search_type'] = !isset($_REQUEST['search_type']) || !isset($subActions[$_REQUEST['search_type']]) ? 'internal' : $_REQUEST['search_type'];
648
	$context['search_term'] = isset($_REQUEST['search_term']) ? $smcFunc['htmlspecialchars']($_REQUEST['search_term'], ENT_QUOTES) : '';
649
650
	$context['sub_template'] = 'admin_search_results';
651
	$context['page_title'] = $txt['admin_search_results'];
652
653
	// Keep track of what the admin wants.
654
	if (empty($context['admin_preferences']['sb']) || $context['admin_preferences']['sb'] != $context['search_type'])
655
	{
656
		$context['admin_preferences']['sb'] = $context['search_type'];
657
658
		// Update the preferences.
659
		require_once($sourcedir . '/Subs-Admin.php');
660
		updateAdminPreferences();
661
	}
662
663
	if (trim($context['search_term']) == '')
664
		$context['search_results'] = array();
665
	else
666
		call_helper($subActions[$context['search_type']]);
667
}
668
669
/**
670
 * A complicated but relatively quick internal search.
671
 */
672
function AdminSearchInternal()
673
{
674
	global $context, $txt, $helptxt, $scripturl, $sourcedir;
675
676
	// Try to get some more memory.
677
	setMemoryLimit('128M');
678
679
	// Load a lot of language files.
680
	$language_files = array(
681
		'Help', 'ManageMail', 'ManageSettings', 'ManageCalendar', 'ManageBoards', 'ManagePaid', 'ManagePermissions', 'Search',
682
		'Login', 'ManageSmileys', 'Drafts',
683
	);
684
685
	// All the files we need to include.
686
	$include_files = array(
687
		'ManageSettings', 'ManageBoards', 'ManageNews', 'ManageAttachments', 'ManageCalendar', 'ManageMail', 'ManagePaid', 'ManagePermissions',
688
		'ManagePosts', 'ManageRegistration', 'ManageSearch', 'ManageSearchEngines', 'ManageServer', 'ManageSmileys', 'ManageLanguages',
689
	);
690
691
	// This is a special array of functions that contain setting data - we query all these to simply pull all setting bits!
692
	$settings_search = array(
693
		array('ModifyBasicSettings', 'area=featuresettings;sa=basic'),
694
		array('ModifyBBCSettings', 'area=featuresettings;sa=bbc'),
695
		array('ModifyLayoutSettings', 'area=featuresettings;sa=layout'),
696
		array('ModifyLikesSettings', 'area=featuresettings;sa=likes'),
697
		array('ModifyMentionsSettings', 'area=featuresettings;sa=mentions'),
698
		array('ModifySignatureSettings', 'area=featuresettings;sa=sig'),
699
		array('ModifyAntispamSettings', 'area=antispam'),
700
		array('ModifyWarningSettings', 'area=warnings'),
701
		array('ModifyGeneralModSettings', 'area=modsettings;sa=general'),
702
		// Mod authors if you want to be "real freaking good" then add any setting pages for your mod BELOW this line!
703
		array('ManageAttachmentSettings', 'area=manageattachments;sa=attachments'),
704
		array('ManageAvatarSettings', 'area=manageattachments;sa=avatars'),
705
		array('ModifyCalendarSettings', 'area=managecalendar;sa=settings'),
706
		array('EditBoardSettings', 'area=manageboards;sa=settings'),
707
		array('ModifyMailSettings', 'area=mailqueue;sa=settings'),
708
		array('ModifyNewsSettings', 'area=news;sa=settings'),
709
		array('GeneralPermissionSettings', 'area=permissions;sa=settings'),
710
		array('ModifyPostSettings', 'area=postsettings;sa=posts'),
711
		array('ModifyTopicSettings', 'area=postsettings;sa=topics'),
712
		array('ModifyDraftSettings', 'area=postsettings;sa=drafts'),
713
		array('EditSearchSettings', 'area=managesearch;sa=settings'),
714
		array('EditSmileySettings', 'area=smileys;sa=settings'),
715
		array('ModifyGeneralSettings', 'area=serversettings;sa=general'),
716
		array('ModifyDatabaseSettings', 'area=serversettings;sa=database'),
717
		array('ModifyCookieSettings', 'area=serversettings;sa=cookie'),
718
		array('ModifyGeneralSecuritySettings', 'area=serversettings;sa=security'),
719
		array('ModifyCacheSettings', 'area=serversettings;sa=cache'),
720
		array('ModifyLanguageSettings', 'area=languages;sa=settings'),
721
		array('ModifyRegistrationSettings', 'area=regcenter;sa=settings'),
722
		array('ManageSearchEngineSettings', 'area=sengines;sa=settings'),
723
		array('ModifySubscriptionSettings', 'area=paidsubscribe;sa=settings'),
724
		array('ModifyLogSettings', 'area=logs;sa=settings'),
725
	);
726
727
	call_integration_hook('integrate_admin_search', array(&$language_files, &$include_files, &$settings_search));
728
729
	loadLanguage(implode('+', $language_files));
730
731
	foreach ($include_files as $file)
732
		require_once($sourcedir . '/' . $file . '.php');
733
734
	/* This is the huge array that defines everything... it's a huge array of items formatted as follows:
735
		0 = Language index (Can be array of indexes) to search through for this setting.
736
		1 = URL for this indexes page.
737
		2 = Help index for help associated with this item (If different from 0)
738
	*/
739
740
	$search_data = array(
741
		// All the major sections of the forum.
742
		'sections' => array(
743
		),
744
		'settings' => array(
745
			array('COPPA', 'area=regcenter;sa=settings'),
746
			array('CAPTCHA', 'area=antispam'),
747
		),
748
	);
749
750
	// Go through the admin menu structure trying to find suitably named areas!
751
	foreach ($context[$context['admin_menu_name']]['sections'] as $section)
752
	{
753
		foreach ($section['areas'] as $menu_key => $menu_item)
754
		{
755
			$search_data['sections'][] = array($menu_item['label'], 'area=' . $menu_key);
756
			if (!empty($menu_item['subsections']))
757
				foreach ($menu_item['subsections'] as $key => $sublabel)
758
				{
759
					if (isset($sublabel['label']))
760
						$search_data['sections'][] = array($sublabel['label'], 'area=' . $menu_key . ';sa=' . $key);
761
				}
762
		}
763
	}
764
765
	foreach ($settings_search as $setting_area)
766
	{
767
		// Get a list of their variables.
768
		$config_vars = $setting_area[0](true);
769
770
		foreach ($config_vars as $var)
771
			if (!empty($var[1]) && !in_array($var[0], array('permissions', 'switch', 'desc')))
772
				$search_data['settings'][] = array($var[(isset($var[2]) && in_array($var[2], array('file', 'db'))) ? 0 : 1], $setting_area[1]);
773
	}
774
775
	$context['page_title'] = $txt['admin_search_results'];
776
	$context['search_results'] = array();
777
778
	$search_term = strtolower(un_htmlspecialchars($context['search_term']));
779
	// Go through all the search data trying to find this text!
780
	foreach ($search_data as $section => $data)
781
	{
782
		foreach ($data as $item)
783
		{
784
			$found = false;
785
			if (!is_array($item[0]))
786
				$item[0] = array($item[0]);
787
			foreach ($item[0] as $term)
788
			{
789
				if (stripos($term, $search_term) !== false || (isset($txt[$term]) && stripos($txt[$term], $search_term) !== false) || (isset($txt['setting_' . $term]) && stripos($txt['setting_' . $term], $search_term) !== false))
790
				{
791
					$found = $term;
792
					break;
793
				}
794
			}
795
796
			if ($found)
797
			{
798
				// Format the name - and remove any descriptions the entry may have.
799
				$name = isset($txt[$found]) ? $txt[$found] : (isset($txt['setting_' . $found]) ? $txt['setting_' . $found] : $found);
800
				$name = preg_replace('~<(?:div|span)\sclass="smalltext">.+?</(?:div|span)>~', '', $name);
801
802
				$context['search_results'][] = array(
803
					'url' => (substr($item[1], 0, 4) == 'area' ? $scripturl . '?action=admin;' . $item[1] : $item[1]) . ';' . $context['session_var'] . '=' . $context['session_id'] . ((substr($item[1], 0, 4) == 'area' && $section == 'settings' ? '#' . $item[0][0] : '')),
804
					'name' => $name,
805
					'type' => $section,
806
					'help' => shorten_subject(isset($item[2]) ? strip_tags($helptxt[$item[2]]) : (isset($helptxt[$found]) ? strip_tags($helptxt[$found]) : ''), 255),
807
				);
808
			}
809
		}
810
	}
811
}
812
813
/**
814
 * All this does is pass through to manage members.
815
 * {@see ViewMembers()}
816
 */
817
function AdminSearchMember()
818
{
819
	global $context, $sourcedir;
820
821
	require_once($sourcedir . '/ManageMembers.php');
822
	$_REQUEST['sa'] = 'query';
823
824
	$_POST['membername'] = un_htmlspecialchars($context['search_term']);
825
	$_POST['types'] = '';
826
827
	ViewMembers();
828
}
829
830
/**
831
 * This file allows the user to search the SM online manual for a little of help.
832
 */
833
function AdminSearchOM()
834
{
835
	global $context, $sourcedir;
836
837
	$context['doc_apiurl'] = 'https://wiki.simplemachines.org/api.php';
838
	$context['doc_scripturl'] = 'https://wiki.simplemachines.org/smf/';
839
840
	// Set all the parameters search might expect.
841
	$postVars = explode(' ', $context['search_term']);
842
843
	// Encode the search data.
844
	foreach ($postVars as $k => $v)
845
		$postVars[$k] = urlencode($v);
846
847
	// This is what we will send.
848
	$postVars = implode('+', $postVars);
849
850
	// Get the results from the doc site.
851
	require_once($sourcedir . '/Subs-Package.php');
852
	// Demo URL:
853
	// https://wiki.simplemachines.org/api.php?action=query&list=search&srprop=timestamp|snippet&format=xml&srwhat=text&srsearch=template+eval
854
	$search_results = fetch_web_data($context['doc_apiurl'] . '?action=query&list=search&srprop=timestamp|snippet&format=xml&srwhat=text&srsearch=' . $postVars);
855
856
	// If we didn't get any xml back we are in trouble - perhaps the doc site is overloaded?
857
	if (!$search_results || preg_match('~<' . '\?xml\sversion="\d+\.\d+"\?' . '>\s*(<api>.+?</api>)~is', $search_results, $matches) != true)
0 ignored issues
show
Bug Best Practice introduced by
The expression $search_results of type string|false is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Bug Best Practice introduced by
It seems like you are loosely comparing preg_match('~<' . '\\?xm...arch_results, $matches) of type integer to the boolean true. If you are specifically checking for 0, consider using something more explicit like === 0 instead.
Loading history...
858
		fatal_lang_error('cannot_connect_doc_site');
859
860
	$search_results = $matches[1];
0 ignored issues
show
Bug introduced by
The variable $matches does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
861
862
	// Otherwise we simply walk through the XML and stick it in context for display.
863
	$context['search_results'] = array();
864
	require_once($sourcedir . '/Class-Package.php');
865
866
	// Get the results loaded into an array for processing!
867
	$results = new xmlArray($search_results, false);
868
869
	// Move through the api layer.
870
	if (!$results->exists('api'))
871
		fatal_lang_error('cannot_connect_doc_site');
872
873
	// Are there actually some results?
874
	if ($results->exists('api/query/search/p'))
875
	{
876
		$relevance = 0;
877
		foreach ($results->set('api/query/search/p') as $result)
878
		{
879
			$context['search_results'][$result->fetch('@title')] = array(
880
				'title' => $result->fetch('@title'),
881
				'relevance' => $relevance++,
882
				'snippet' => str_replace('class=\'searchmatch\'', 'class="highlight"', un_htmlspecialchars($result->fetch('@snippet'))),
0 ignored issues
show
Security Bug introduced by
It seems like $result->fetch('@snippet') targeting xmlArray::fetch() can also be of type false; however, un_htmlspecialchars() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
883
			);
884
		}
885
	}
886
}
887
888
/**
889
 * This function decides which log to load.
890
 */
891
function AdminLogs()
892
{
893
	global $sourcedir, $context, $txt, $scripturl, $modSettings;
894
895
	// These are the logs they can load.
896
	$log_functions = array(
897
		'errorlog' => array('ManageErrors.php', 'ViewErrorLog'),
898
		'adminlog' => array('Modlog.php', 'ViewModlog', 'disabled' => empty($modSettings['adminlog_enabled'])),
899
		'modlog' => array('Modlog.php', 'ViewModlog', 'disabled' => empty($modSettings['modlog_enabled'])),
900
		'banlog' => array('ManageBans.php', 'BanLog'),
901
		'spiderlog' => array('ManageSearchEngines.php', 'SpiderLogs'),
902
		'tasklog' => array('ManageScheduledTasks.php', 'TaskLog'),
903
		'settings' => array('ManageSettings.php', 'ModifyLogSettings'),
904
	);
905
906
	// If it's not got a sa set it must have come here for first time, pretend error log should be reversed.
907
	if (!isset($_REQUEST['sa']))
908
		$_REQUEST['desc'] = true;
909
910
	// Setup some tab stuff.
911
	$context[$context['admin_menu_name']]['tab_data'] = array(
912
		'title' => $txt['logs'],
913
		'help' => '',
914
		'description' => $txt['maintain_info'],
915
		'tabs' => array(
916
			'errorlog' => array(
917
				'url' => $scripturl . '?action=admin;area=logs;sa=errorlog;desc',
918
				'description' => sprintf($txt['errlog_desc'], $txt['remove']),
919
			),
920
			'adminlog' => array(
921
				'description' => $txt['admin_log_desc'],
922
			),
923
			'modlog' => array(
924
				'description' => $txt['moderation_log_desc'],
925
			),
926
			'banlog' => array(
927
				'description' => $txt['ban_log_description'],
928
			),
929
			'spiderlog' => array(
930
				'description' => $txt['spider_log_desc'],
931
			),
932
			'tasklog' => array(
933
				'description' => $txt['scheduled_log_desc'],
934
			),
935
			'settings' => array(
936
				'description' => $txt['log_settings_desc'],
937
			),
938
		),
939
	);
940
941
	call_integration_hook('integrate_manage_logs', array(&$log_functions));
942
943
	$subAction = isset($_REQUEST['sa']) && isset($log_functions[$_REQUEST['sa']]) && empty($log_functions[$_REQUEST['sa']]['disabled']) ? $_REQUEST['sa'] : 'errorlog';
944
945
	require_once($sourcedir . '/' . $log_functions[$subAction][0]);
946
	call_helper($log_functions[$subAction][1]);
947
}
948
949
/**
950
 * This ends a admin session, requiring authentication to access the ACP again.
951
 */
952
function AdminEndSession()
953
{
954
	// This is so easy!
955
	unset($_SESSION['admin_time']);
956
957
	// Clean any admin tokens as well.
958 View Code Duplication
	foreach ($_SESSION['token'] as $key => $token)
959
		if (strpos($key, '-admin') !== false)
960
			unset($_SESSION['token'][$key]);
961
962
	redirectexit();
963
}
964
965
?>