Passed
Push — development ( 924c99...c29c1d )
by Spuds
01:04 queued 20s
created

ManageServer::action_loadavgSettings_display()   B

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

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