ManageServer::action_loadavgSettings_display()   B
last analyzed

Complexity

Conditions 10
Paths 2

Size

Total Lines 50
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 28.0553

Importance

Changes 0
Metric Value
cc 10
eloc 23
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 50
rs 7.6666
ccs 10
cts 23
cp 0.4348
crap 28.0553

How to fix   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
 * Contains all the functionality required to be able to edit the core server settings.
5
 * This includes anything from which an error may result in the forum destroying
6
 * itself in a firey fury.
7
 *
8
 * @package   ElkArte Forum
9
 * @copyright ElkArte Forum contributors
10
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
11
 *
12
 * This file contains code covered by:
13
 * copyright: 2011 Simple Machines (http://www.simplemachines.org)
14
 *
15
 * @version 2.0 dev
16
 *
17
 */
18
19
namespace ElkArte\AdminController;
20
21
use ElkArte\AbstractController;
22
use ElkArte\Action;
23
use ElkArte\Cache\CacheMethod\AbstractCacheMethod;
24
use ElkArte\Exceptions\Exception;
25
use ElkArte\SettingsForm\SettingsForm;
26
use ElkArte\Languages\Txt;
27
use ElkArte\User;
28
29
/**
30
 * ManageServer administration pages controller.
31
 *
32
 * This handles several screens, with low-level essential settings such as
33
 * database settings, cache, general forum settings, and others.
34
 * It sends the data for display, and it allows the admin to change it.
35
 */
36
class ManageServer extends AbstractController
37
{
38
	/**
39
	 * This is the main dispatcher. Sets up all the available sub-actions, all the tabs and selects
40
	 * the appropriate one based on the sub-action.
41
	 *
42
	 * What it does:
43
	 *
44
	 * - Requires the admin_forum permission.
45
	 * - Redirects to the appropriate function based on the sub-action.
46
	 *
47
	 * @event integrate_sa_server_settings
48
	 * @uses edit_settings adminIndex.
49
	 * @see AbstractController::action_index()
50
	 */
51
	public function action_index()
52
	{
53
		global $context, $txt;
54
55
		// The settings are in here, I swear!
56
		Txt::load('ManageSettings');
57
58
		// This is just to keep the database password more secure.
59
		isAllowedTo('admin_forum');
60
		checkSession('request');
61
62
		$subActions = [
63
			'general' => [$this, 'action_generalSettings_display', 'permission' => 'admin_forum'],
64
			'database' => [$this, 'action_databaseSettings_display', 'permission' => 'admin_forum'],
65
			'cookie' => [$this, 'action_cookieSettings_display', 'permission' => 'admin_forum'],
66
			'cache' => [$this, 'action_cacheSettings_display', 'permission' => 'admin_forum'],
67
			'loads' => [$this, 'action_loadavgSettings_display', 'permission' => 'admin_forum'],
68
			'phpinfo' => [$this, 'action_phpinfo', 'permission' => 'admin_forum'],
69
		];
70
71
		$action = new Action('server_settings');
72
73
		// By default we're editing the core settings, call integrate_sa_server_settings
74
		$subAction = $action->initialize($subActions, 'general');
75
76
		// Last things for the template
77
		$context['sub_action'] = $subAction;
78
		$context['page_title'] = $txt['admin_server_settings'];
79
		$context['sub_template'] = 'show_settings';
80
81
		// Load up all the tabs...
82
		$context[$context['admin_menu_name']]['object']->prepareTabData([
83
			'title' => 'admin_server_settings',
84
			'help' => 'serversettings',
85
			'description' => 'admin_basic_settings',
86
		]);
87
88
		// Any messages to speak of?
89
		$context['settings_message'] = (isset($this->_req->query->msg, $txt[$this->_req->query->msg])) ? $txt[$this->_req->query->msg] : '';
90
91
		// Warn the user if there's any relevant information regarding Settings.php.
92
		$settings_not_writable = !is_writable(BOARDDIR . '/Settings.php');
93
94
		// Warn the user if the backup of Settings.php failed.
95
		$settings_backup_fail = !@is_writable(BOARDDIR . '/Settings_bak.php') || !@copy(BOARDDIR . '/Settings.php', BOARDDIR . '/Settings_bak.php');
96
97
		if ($settings_not_writable)
98
		{
99
			$context['settings_message'] = $txt['settings_not_writable'];
100
			$context['error_type'] = 'notice';
101
		}
102
		elseif ($settings_backup_fail)
103
		{
104
			$context['settings_message'] = $txt['admin_backup_fail'];
105
			$context['error_type'] = 'notice';
106
		}
107
108
		$context['settings_not_writable'] = $settings_not_writable;
109
110
		// Call the right function for this sub-action.
111
		$action->dispatch($subAction);
112
	}
113
114
	/**
115
	 * General forum settings - forum name, maintenance mode, etc.
116
	 *
117
	 * Practically, this shows an interface for the settings in Settings.php to
118
	 * be changed. The method handles the display, allows to edit, and saves
119
	 * the result for generalSettings form.
120
	 *
121
	 * What it does:
122
	 *
123
	 * - Requires the admin_forum permission.
124
	 * - Uses the edit_settings administration area.
125
	 * - Contains the actual array of settings to show from Settings.php.
126
	 * - Accessed from ?action=admin;area=serversettings;sa=general.
127
	 *
128
	 * @event integrate_save_general_settings
129
	 */
130
	public function action_generalSettings_display(): void
131
	{
132
		global $context, $txt;
133
134
		// Initialize the form
135
		$settingsForm = new SettingsForm(SettingsForm::FILE_ADAPTER);
136
137
		// Initialize it with our settings
138
		$settingsForm->setConfigVars($this->_generalSettings());
139
140
		// Setup the template stuff.
141
		$context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'serversettings', 'sa' => 'general', 'save']);
142
		$context['settings_title'] = $txt['general_settings'];
143
144
		// Saving settings?
145
		if (isset($this->_req->query->save))
146
		{
147
			call_integration_hook('integrate_save_general_settings');
148
149
			// Reset this in the event the server has changed, it will get set again if needed.
150
			updateSettings(['host_to_dis' => 0]);
151
152
			$settingsForm->setConfigValues((array) $this->_req->post);
153
			$settingsForm->save();
154
			redirectexit('action=admin;area=serversettings;sa=general;' . $context['session_var'] . '=' . $context['session_id'] . ';msg=' . (empty($context['settings_message']) ? 'core_settings_saved' : $context['settings_message']));
155
		}
156
157
		// Fill the config array for the template and all that.
158
		$settingsForm->prepare();
159
	}
160
161 2
	/**
162
	 * This function returns all general settings.
163 2
	 *
164
	 * @event integrate_modify_general_settings
165
	 */
166
	private function _generalSettings()
167 2
	{
168 2
		global $txt;
169 2
170 2
		// initialize configuration
171 2
		$config_vars = [
172 2
			['mbname', $txt['admin_title'], 'file', 'text', 30],
173 2
			'',
174 2
			['maintenance', $txt['admin_maintain'], 'file', 'check'],
175 2
			['mtitle', $txt['maintenance_subject'], 'file', 'text', 36],
176 2
			['mmessage', $txt['maintenance_message'], 'file', 'large_text', 6],
177 2
			'',
178
			['webmaster_email', $txt['admin_webmaster_email'], 'file', 'text', 30],
179
			'',
180
			['enableCompressedOutput', $txt['enableCompressedOutput'], 'db', 'check', null, 'enableCompressedOutput'],
181 2
			['disableHostnameLookup', $txt['disableHostnameLookup'], 'db', 'check', null, 'disableHostnameLookup'],
182
			// This is not really a server setting, it's here for convenience so its saved in Settings.php
183 2
			['url_format', $txt['url_format'], 'file', 'select', ['standard' => $txt['url_format_standard'], 'semantic' => $txt['url_format_semantic'], 'queryless' => $txt['url_format_queryless']]],
184
		];
185
186
		// Notify the integration
187
		call_integration_hook('integrate_modify_general_settings', [&$config_vars]);
188
189
		return $config_vars;
190
	}
191
192
	/**
193
	 * Basic database and paths settings - database name, host, etc.
194
	 *
195
	 * This method handles the display, allows to edit, and saves the results
196
	 * for _databaseSettings.
197
	 *
198
	 * What it does:
199
	 *
200
	 * - It shows an interface for the settings in Settings.php to be changed.
201
	 * - It contains the actual array of settings to show from Settings.php.
202
	 * - Requires the admin_forum permission.
203
	 * - Uses the edit_settings administration area.
204
	 * - Accessed from ?action=admin;area=serversettings;sa=database.
205
	 *
206
	 * @event integrate_save_database_settings
207
	 */
208
	public function action_databaseSettings_display(): void
209
	{
210
		global $context, $txt;
211
212
		// Initialize the form
213
		$settingsForm = new SettingsForm(SettingsForm::FILE_ADAPTER);
214
215
		// Initialize it with our settings
216
		$settingsForm->setConfigVars($this->_databaseSettings());
217
218
		// Setup the template stuff.
219
		$context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'serversettings', 'sa' => 'database', 'save']);
220
		$context['settings_title'] = $txt['database_paths_settings'];
221
		$context['save_disabled'] = $context['settings_not_writable'];
222
223
		// Saving settings?
224
		if (isset($this->_req->query->save))
225
		{
226
			call_integration_hook('integrate_save_database_settings');
227
228
			$settingsForm->setConfigValues((array) $this->_req->post);
229
			$settingsForm->save();
230
			redirectexit('action=admin;area=serversettings;sa=database;' . $context['session_var'] . '=' . $context['session_id'] . ';msg=' . (empty($context['settings_message']) ? 'core_settings_saved' : $context['settings_message']));
231
		}
232
233
		// Fill the config array for the template.
234
		$settingsForm->prepare();
235
	}
236 2
237
	/**
238 2
	 * This function returns database settings.
239
	 *
240
	 * @event integrate_modify_database_settings
241
	 */
242 2
	private function _databaseSettings()
243 2
	{
244 2
		global $txt;
245 2
246 2
		// initialize settings
247 2
		$config_vars = [
248 2
			['db_server', $txt['database_server'], 'file', 'text'],
249 2
			['db_user', $txt['database_user'], 'file', 'text'],
250 2
			['db_passwd', $txt['database_password'], 'file', 'password'],
251 2
			['db_name', $txt['database_name'], 'file', 'text'],
252 2
			['db_prefix', $txt['database_prefix'], 'file', 'text'],
253 2
			['db_persist', $txt['db_persist'], 'file', 'check', null, 'db_persist'],
254 2
			['db_error_send', $txt['db_error_send'], 'file', 'check'],
255 2
			['ssi_db_user', $txt['ssi_db_user'], 'file', 'text', null, 'ssi_db_user'],
256 2
			['ssi_db_passwd', $txt['ssi_db_passwd'], 'file', 'password'],
257 2
			'',
258 2
			['autoFixDatabase', $txt['autoFixDatabase'], 'db', 'check', false, 'autoFixDatabase'],
259
			['autoOptMaxOnline', $txt['autoOptMaxOnline'], 'subtext' => $txt['zero_for_no_limit'], 'db', 'int'],
260
			'',
261
			['boardurl', $txt['admin_url'], 'file', 'text', 36],
262 2
			['boarddir', $txt['boarddir'], 'file', 'text', 36],
263
			['sourcedir', $txt['sourcesdir'], 'file', 'text', 36],
264 2
			['cachedir', $txt['cachedir'], 'file', 'text', 36],
265
		];
266
267
		// Notify the integration
268
		call_integration_hook('integrate_modify_database_settings', [&$config_vars]);
269
270
		return $config_vars;
271
	}
272
273
	/**
274
	 * Modify cookies settings.
275
	 *
276
	 * This method handles the display, allows to edit, and saves the result
277
	 * for the _cookieSettings form.
278
	 *
279
	 * @event integrate_save_cookie_settings
280
	 */
281
	public function action_cookieSettings_display(): void
282
	{
283
		global $context, $txt, $modSettings, $cookiename, $boardurl;
284
285
		// Initialize the form
286
		$settingsForm = new SettingsForm(SettingsForm::FILE_ADAPTER);
287
288
		// Initialize it with our settings
289
		$settingsForm->setConfigVars($this->_cookieSettings());
290
291
		$context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'serversettings', 'sa' => 'cookie', 'save']);
292
		$context['settings_title'] = $txt['cookies_sessions_settings'];
293
294
		// Saving settings?
295
		if (isset($this->_req->query->save))
296
		{
297
			call_integration_hook('integrate_save_cookie_settings');
298
299
			// Its either local or global cookies
300
			if (!empty($this->_req->post->localCookies) && !empty($this->_req->post->globalCookies))
301
			{
302
				unset($this->_req->post->globalCookies);
303
			}
304
305
			if (!empty($this->_req->post->globalCookiesDomain) && strpos($boardurl, (string) $this->_req->post->globalCookiesDomain) === false)
306
			{
307
				throw new Exception('invalid_cookie_domain', false);
308
			}
309
310
			if ($this->_req->getPost('cookiename', 'trim', '') === '')
311
			{
312
				$this->_req->post->cookiename = $cookiename;
313
			}
314
315
			$settingsForm->setConfigValues((array) $this->_req->post);
316
			$settingsForm->save();
317
318
			// If the cookie name was changed, reset the cookie.
319
			if ($cookiename !== $this->_req->post->cookiename)
320
			{
321
				require_once(SUBSDIR . '/Auth.subs.php');
322
323
				$original_session_id = $context['session_id'];
324
325
				// Remove the old cookie, nom nom nom
326
				setLoginCookie(-3600, 0);
327
328
				// Set the new one.
329
				$cookiename = $this->_req->post->cookiename;
330
				setLoginCookie(60 * $modSettings['cookieTime'], (int) User::$settings['id_member'], hash('sha256', User::$settings['passwd'] . User::$settings['password_salt']));
331
332
				redirectexit('action=admin;area=serversettings;sa=cookie;' . $context['session_var'] . '=' . $original_session_id);
333
			}
334
335
			redirectexit('action=admin;area=serversettings;sa=cookie;' . $context['session_var'] . '=' . $context['session_id'] . ';msg=' . (empty($context['settings_message']) ? 'core_settings_saved' : $context['settings_message']));
336
		}
337
338
		theme()->addInlineJavascript('
339
		// Initial state
340
		hideGlobalCookies();
341
342
		// Update when clicked
343
		document.querySelectorAll("#localCookies, #globalCookies").forEach(function(element) {
344
             element.addEventListener("click", function() {
345 2
			    hideGlobalCookies();
346
              });
347 2
		});', true);
348
349
		// Fill the config array.
350
		$settingsForm->prepare();
351
	}
352 2
353 2
	/**
354 2
	 * This little function returns all cookie settings.
355 2
	 *
356 2
	 * @event integrate_modify_cookie_settings
357 2
	 */
358 2
	private function _cookieSettings()
359 2
	{
360
		global $txt;
361 2
362 2
		// Define the variables we want to edit or show in the cookie form.
363 2
		$config_vars = [
364
			// Cookies...
365
			['cookiename', $txt['cookie_name'], 'file', 'text', 20],
366
			['cookieTime', $txt['cookieTime'], 'db', 'int', 'postinput' => $txt['minutes']],
367 2
			['localCookies', $txt['localCookies'], 'subtext' => $txt['localCookies_note'], 'db', 'check', false, 'localCookies'],
368
			['globalCookies', $txt['globalCookies'], 'subtext' => $txt['globalCookies_note'], 'db', 'check', false, 'globalCookies'],
369
			['globalCookiesDomain', $txt['globalCookiesDomain'], 'subtext' => $txt['globalCookiesDomain_note'], 'db', 'text', false, 'globalCookiesDomain'],
370 2
			['secureCookies', $txt['secureCookies'], 'subtext' => $txt['secureCookies_note'], 'db', 'check', false, 'secureCookies', 'disabled' => !isset($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) !== 'on' && strtolower($_SERVER['HTTPS']) != '1'],
371
			['httponlyCookies', $txt['httponlyCookies'], 'subtext' => $txt['httponlyCookies_note'], 'db', 'check', false, 'httponlyCookies'],
372
			'',
373
			// Sessions
374
			['databaseSession_enable', $txt['databaseSession_enable'], 'db', 'check', false, 'databaseSession_enable'],
375
			['databaseSession_loose', $txt['databaseSession_loose'], 'db', 'check', false, 'databaseSession_loose'],
376
			['databaseSession_lifetime', $txt['databaseSession_lifetime'], 'db', 'int', false, 'databaseSession_lifetime', 'postinput' => $txt['seconds']],
377
		];
378
379
		// Notify the integration
380
		call_integration_hook('integrate_modify_cookie_settings', [&$config_vars]);
381
382
		// Set them vars for our settings form
383
		return $config_vars;
384
	}
385
386
	/**
387
	 * Cache settings editing and submission.
388
	 *
389
	 * This method handles the display, allows to edit, and saves the result
390
	 * for _cacheSettings form.
391
	 *
392
	 * @event integrate_save_cache_settings
393
	 */
394
	public function action_cacheSettings_display(): void
395
	{
396
		global $context, $txt;
397
398
		// Initialize the form
399
		$settingsForm = new SettingsForm(SettingsForm::FILE_ADAPTER);
400
401
		// Initialize it with our settings
402
		$settingsForm->setConfigVars($this->_cacheSettings());
403
404
		// Saving again?
405
		if (isset($this->_req->query->save))
406
		{
407
			call_integration_hook('integrate_save_cache_settings');
408
409
			// Move accelerator servers to the cache_servers value
410
			$var = 'cache_servers_' . $this->_req->post->cache_accelerator;
411
			if (isset($this->_req->post->$var))
412
			{
413
				$this->_req->post->cache_servers = $this->_req->post->$var;
414
			}
415
416
			$settingsForm->setConfigValues((array) $this->_req->post);
417
			$settingsForm->save();
418
419
			// we need to save the $cache_enable to $modSettings as well
420
			updateSettings(['cache_enable' => (int) $this->_req->post->cache_enable]);
421
422
			// exit so we reload our new settings on the page
423
			redirectexit('action=admin;area=serversettings;sa=cache;' . $context['session_var'] . '=' . $context['session_id']);
424
		}
425
426
		Txt::load('Maintenance');
427
		createToken('admin-maint');
428
		theme()->getLayers()->add('clean_cache_button');
429
430
		// Some javascript to enable / disable certain settings if the option is not selected
431
		theme()->addInlineJavascript('
432
			let cache_type = document.getElementById(\'cache_accelerator\');
433
434 2
			cache_type.addEventListener("change", showCache);
435
			cache_type.addEventListener("change", toggleCache);
436 2
			
437
			let event = new Event("change");
438
			cache_type.dispatchEvent(event);
439 2
			', true);
440 2
441 2
		$context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'serversettings', 'sa' => 'cache', 'save']);
442 2
		$context['settings_title'] = $txt['caching_settings'];
443
		$context['settings_message'] = $txt['caching_information'] . '<br /><br />' . $txt['cache_settings_message'];
444 2
445
		// Prepare the template.
446 2
		createToken('admin-ssc');
447
448 2
		// Prepare settings for display in the template.
449
		$settingsForm->prepare();
450 2
	}
451
452
	/**
453
	 * This little function returns all cache settings.
454 2
	 *
455
	 * @event integrate_modify_cache_settings
456
	 */
457 2
	private function _cacheSettings()
458 2
	{
459
		global $txt, $cache_accelerator, $context;
460
461
		// Detect all available cache engines
462
		require_once(SUBSDIR . '/Cache.subs.php');
463 2
		$detected = loadCacheEngines(false);
464 2
		$detected_names = [];
465
		$detected_supported = [];
466
467
		/** @var $value AbstractCacheMethod */
468 2
		foreach ($detected as $key => $value)
469
		{
470 2
			$detected_names[] = $value->title();
471
472 2
			if (!empty($value->isAvailable()))
473
			{
474
				$detected_supported[$key] = $value->title();
475
				if ($key === $cache_accelerator)
476
				{
477 2
					$context['cache_accelerator_stats'] = $value->getStats();
478
				}
479 2
			}
480
		}
481
482
		$txt['caching_information'] = str_replace('{supported_accelerators}', '<i>' . implode(', ', $detected_names) . '</i><br />', $txt['caching_information']);
483
484
		// Set our values to show what, if anything, we found
485
		$txt['cache_settings_message'] = sprintf($txt['detected_accelerators'], implode(', ', $detected_supported));
486
		$cache_level = [$txt['cache_off'], $txt['cache_level1'], $txt['cache_level2'], $txt['cache_level3']];
487
488
		// Define the variables we want to edit.
489
		$config_vars = [
490
			// Only a few settings, but they are important
491
			['cache_enable', $txt['cache_enable'], 'file', 'select', $cache_level, 'cache_enable'],
492
			['cache_accelerator', $txt['cache_accelerator'], 'file', 'select', $detected_supported],
493
		];
494
495
		// If the cache engine has any specific settings, add them in
496
		foreach ($detected as $engine)
497
		{
498
			/** @var $engine AbstractCacheMethod */
499
			if ($engine->isAvailable())
500
			{
501
				$engine->settings($config_vars);
502
			}
503
		}
504
505
		// Notify the integration that we're preparing to mess with cache settings...
506
		call_integration_hook('integrate_modify_cache_settings', [&$config_vars]);
507
508
		return $config_vars;
509
	}
510
511
	/**
512
	 * Allows to edit load management settings.
513
	 *
514
	 * This method handles the display, allows to edit, and saves the result
515
	 * for the _loadavgSettings form.
516
	 *
517
	 * @event integrate_loadavg_settings
518
	 * @event integrate_save_loadavg_settings
519
	 */
520
	public function action_loadavgSettings_display(): void
521
	{
522
		global $txt, $context;
523
524
		// Initialize the form
525
		$settingsForm = new SettingsForm(SettingsForm::DB_ADAPTER);
526
527
		// Initialize it with our settings
528
		$settingsForm->setConfigVars($this->_loadavgSettings());
529
530
		call_integration_hook('integrate_loadavg_settings');
531
532
		$context['post_url'] = getUrl('admin', ['action' => 'admin', 'area' => 'serversettings', 'sa' => 'loads', 'save']);
533
		$context['settings_title'] = $txt['loadavg_settings'];
534
535
		// Saving?
536
		if (isset($this->_req->query->save))
537
		{
538
			// Stupidity is not allowed.
539
			foreach ($this->_req->post as $key => $value)
540
			{
541
				if (strpos($key, 'loadavg') === 0 || $key === 'loadavg_enable')
542
				{
543
					continue;
544
				}
545
546
				if ($key === 'loadavg_auto_opt' && $value <= 1)
547
				{
548 2
					$this->_req->post->loadavg_auto_opt = '1.0';
549
				}
550 2
				elseif ($key === 'loadavg_forum' && $value < 10)
551
				{
552
					$this->_req->post->loadavg_forum = '10.0';
553 2
				}
554 2
				elseif ($value < 2)
555
				{
556
					$this->_req->{$key} = '2.0';
557 2
				}
558
			}
559
560
			call_integration_hook('integrate_save_loadavg_settings');
561
562
			$settingsForm->setConfigValues((array) $this->_req->post);
563 2
			$settingsForm->save();
564 2
			redirectexit('action=admin;area=serversettings;sa=loads;' . $context['session_var'] . '=' . $context['session_id']);
565
		}
566 2
567
		createToken('admin-ssc');
568 2
		createToken('admin-dbsc');
569 2
		$settingsForm->prepare();
570
	}
571
572
	/**
573
	 * This little function returns load management settings.
574
	 *
575 2
	 * @event integrate_modify_loadavg_settings
576
	 */
577
	private function _loadavgSettings()
578
	{
579
		global $txt, $modSettings, $context;
580 2
581
		// Initialize settings for the form to show, disabled by default.
582
		$disabled = true;
583
		$context['settings_message'] = $txt['loadavg_disabled_conf'];
584
585
		// Don't say you're using that win-thing, no cookies for you :P
586
		if (strpos(PHP_OS_FAMILY, 'Win') === 0)
587
		{
588
			$context['settings_message'] = $txt['loadavg_disabled_windows'];
589
		}
590
		else
591 2
		{
592
			require_once(SUBSDIR . '/Server.subs.php');
593
			$modSettings['load_average'] = detectServerLoad();
594 2
595 2
			if ($modSettings['load_average'] !== false)
596
			{
597
				$disabled = false;
598
				$context['settings_message'] = sprintf($txt['loadavg_warning'], $modSettings['load_average']);
599 2
			}
600
		}
601 2
602
		// Start with a simple checkbox.
603
		$config_vars = [
604
			['check', 'loadavg_enable', 'disabled' => $disabled],
605
		];
606
607
		// Set the default values for each option.
608
		$default_values = [
609
			'loadavg_auto_opt' => '1.0',
610
			'loadavg_search' => '2.5',
611
			'loadavg_allunread' => '2.0',
612
			'loadavg_unreadreplies' => '3.5',
613
			'loadavg_show_posts' => '2.0',
614
			'loadavg_userstats' => '10.0',
615
			'loadavg_bbc' => '30.0',
616
			'loadavg_forum' => '40.0',
617
		];
618
619
		// Loop through the settings.
620
		foreach ($default_values as $name => $value)
621
		{
622
			// Use the default value if the setting isn't set yet.
623
			$value = $modSettings[$name] ?? $value;
624
			$config_vars[] = ['text', $name, 'value' => $value, 'disabled' => $disabled];
625
		}
626
627
		// Notify the integration that we're preparing to mess with load management settings...
628
		call_integration_hook('integrate_modify_loadavg_settings', [&$config_vars]);
629
630
		return $config_vars;
631
	}
632
633
	/**
634
	 * Allows us to see the servers php settings
635
	 *
636
	 * What it does:
637
	 *
638
	 * - loads the settings into an array for display in a template
639
	 * - drops cookie values just in case
640
	 *
641
	 * @uses sub-template php_info
642
	 */
643
	public function action_phpinfo(): void
644
	{
645
		global $context, $txt;
646
647
		$category = $txt['phpinfo_settings'];
648
		$pinfo = [];
649
650
		// Get the data
651
		ob_start();
652
		phpinfo();
653
654
		// We only want it for its body, pigs that we are
655
		$info_lines = preg_replace('~^.*<body>(.*)</body>.*$~', '$1', ob_get_contents());
656
		$info_lines = explode("\n", strip_tags($info_lines, '<tr><td><h2>'));
657
		@ob_end_clean();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for ob_end_clean(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

657
		/** @scrutinizer ignore-unhandled */ @ob_end_clean();

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...
658
659
		// Remove things that could be considered sensitive
660
		$remove = '_COOKIE|Cookie|_GET|_REQUEST|REQUEST_URI|QUERY_STRING|REQUEST_URL|HTTP_REFERER';
661
662
		// Put all of it into an array
663
		foreach ($info_lines as $line)
664
		{
665
			if (preg_match('~(' . $remove . ')~', $line))
666
			{
667 2
				continue;
668
			}
669 2
670
			// New category?
671
			if (strpos($line, '<h2>') !== false)
672
			{
673
				$category = preg_match('~<h2>(.*)</h2>~', $line, $title) ? $title[1] : $category;
674
			}
675 2
676
			// Load it as setting => value or the old setting local master
677 2
			if (preg_match('~<tr><td[^>]+>([^<]*)</td><td[^>]+>([^<]*)</td></tr>~', $line, $val))
678
			{
679
				$pinfo[$category][$val[1]] = $val[2];
680
			}
681
			elseif (preg_match('~<tr><td[^>]+>([^<]*)</td><td[^>]+>([^<]*)</td><td[^>]+>([^<]*)</td></tr>~', $line, $val))
682
			{
683 2
				$pinfo[$category][$val[1]] = [$txt['phpinfo_localsettings'] => $val[2], $txt['phpinfo_defaultsettings'] => $val[3]];
684
			}
685 2
		}
686
687
		// Load it in to context and display it
688
		$context['pinfo'] = $pinfo;
689
		$context['page_title'] = $txt['admin_server_settings'];
690
		$context['sub_template'] = 'php_info';
691 2
	}
692
693 2
	/**
694
	 * Return the search settings for use in admin search
695
	 */
696
	public function generalSettings_search()
697
	{
698
		return $this->_generalSettings();
699 2
	}
700
701 2
	/**
702
	 * Return the search settings for use in admin search
703
	 */
704
	public function databaseSettings_search()
705
	{
706
		return $this->_databaseSettings();
707
	}
708
709
	/**
710
	 * Return the search settings for use in admin search
711
	 */
712
	public function cookieSettings_search()
713
	{
714
		return $this->_cookieSettings();
715
	}
716
717
	/**
718
	 * Return the search settings for use in admin search
719
	 */
720
	public function cacheSettings_search()
721
	{
722
		return $this->_cacheSettings();
723
	}
724
725
	/**
726
	 * Return the search settings for use in admin search
727
	 */
728
	public function balancingSettings_search()
729
	{
730
		return $this->_loadavgSettings();
731
	}
732
}
733