Passed
Pull Request — development (#3540)
by Emanuele
07:11
created

getFileVersions()   F

Complexity

Conditions 21
Paths 512

Size

Total Lines 139
Code Lines 74

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 462

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 74
dl 0
loc 139
rs 0.6777
c 1
b 0
f 0
cc 21
nc 512
nop 1
ccs 0
cts 112
cp 0
crap 462

2 Methods

Rating   Name   Duplication   Size   Complexity  
B emailAdmins() 0 73 8
A custom_profiles_toggle_callback() 0 18 2

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
 * Functions to support admin controller
5
 *
6
 * @package   ElkArte Forum
7
 * @copyright ElkArte Forum contributors
8
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
9
 *
10
 * This file contains code covered by:
11
 * copyright: 2011 Simple Machines (http://www.simplemachines.org)
12
 *
13
 * @version 2.0 dev
14
 *
15
 * This file contains functions that are specifically done by administrators.
16
 *
17
 */
18
19
use ElkArte\Cache\Cache;
20
use ElkArte\Languages\Txt;
21
use ElkArte\User;
22
23
/**
24
 * Get a list of versions that are currently installed on the server.
25
 *
26
 * @param string[] $checkFor
27
 *
28
 * @return array
29
 * @package Admin
30
 */
31
function getServerVersions($checkFor)
32
{
33
	global $txt;
34
35
	$db = database();
36
37
	Txt::load('Admin');
38
39
	$versions = array();
40
41
	// Is GD available?  If it is, we should show version information for it too.
42
	if (in_array('gd', $checkFor) && function_exists('gd_info'))
43
	{
44
		$temp = gd_info();
45
		$versions['gd'] = array('title' => $txt['support_versions_gd'], 'version' => $temp['GD Version']);
46
	}
47
48
	// Why not have a look at ImageMagick? If it is, we should show version information for it too.
49
	if (in_array('imagick', $checkFor) && class_exists('Imagick'))
50
	{
51
		$temp = new Imagick();
52
		$temp2 = $temp->getVersion();
53
		$versions['imagick'] = array('title' => $txt['support_versions_imagick'], 'version' => $temp2['versionString']);
54
	}
55
56
	// Now lets check for the Database.
57
	if (in_array('db_server', $checkFor))
58
	{
59
		$conn = $db->connection();
60
		if (empty($conn))
61
		{
62
			trigger_error('getServerVersions(): you need to be connected to the database in order to get its server version', E_USER_NOTICE);
63
		}
64
		else
65
		{
66
			$versions['db_server'] = array('title' => sprintf($txt['support_versions_db'], $db->title()), 'version' => '');
67
			$versions['db_server']['version'] = $db->server_version();
68
		}
69
	}
70
71
	require_once(SUBSDIR . '/Cache.subs.php');
72
	$cache_engines = loadCacheEngines();
73
	foreach ($cache_engines as $name => $details)
74
	{
75
		if (in_array($name, $checkFor))
76
		{
77
			$versions[$name] = $details;
78
		}
79
	}
80
81
	if (in_array('opcache', $checkFor) && extension_loaded('Zend OPcache'))
82
	{
83
		$opcache_config = @opcache_get_configuration();
84
		if (!empty($opcache_config['directives']['opcache.enable']))
85
		{
86
			$versions['opcache'] = array('title' => $opcache_config['version']['opcache_product_name'], 'version' => $opcache_config['version']['version']);
87
		}
88
	}
89
90
	// PHP Version
91
	if (in_array('php', $checkFor))
92
	{
93
		$versions['php'] = array('title' => 'PHP', 'version' => PHP_VERSION . ' (' . php_sapi_name() . ')', 'more' => '?action=admin;area=serversettings;sa=phpinfo');
94
	}
95
96
	// Server info
97
	if (in_array('server', $checkFor))
98
	{
99
		$req = request();
100
		$versions['server'] = array('title' => $txt['support_versions_server'], 'version' => $req->server_software());
101
102
		// Compute some system info, if we can
103
		$versions['server_name'] = array('title' => $txt['support_versions'], 'version' => php_uname());
104
		require_once(SUBSDIR . '/Server.subs.php');
105
		$loading = detectServerLoad();
106
		if ($loading !== false)
107
		{
108
			$versions['server_load'] = array('title' => $txt['loadavg'], 'version' => $loading);
109
		}
110
	}
111
112
	return $versions;
113
}
114
115
/**
116
 * Builds the available tasks for this admin / moderator
117
 *
118
 * What it does:
119
 *
120
 * - Sets up the support resource txt stings
121
 * - Called from Admin.controller action_home and action_credits
122
 *
123
 * @package Admin
124
 */
125
function getQuickAdminTasks()
126
{
127
	global $txt, $context;
128
129
	// The format of this array is: permission, action, title, description, icon.
130
	$quick_admin_tasks = array(
131
		array('', 'credits', 'support_credits_title', 'support_credits_info', 'support_and_credits.png'),
132
		array('admin_forum', 'featuresettings', 'modSettings_title', 'modSettings_info', 'features_and_options.png'),
133
		array('admin_forum', 'maintain', 'maintain_title', 'maintain_info', 'forum_maintenance.png'),
134
		array('manage_permissions', 'permissions', 'edit_permissions', 'edit_permissions_info', 'permissions_lg.png'),
135
		array('admin_forum', 'theme;sa=admin;' . $context['session_var'] . '=' . $context['session_id'], 'theme_admin', 'theme_admin_info', 'themes_and_layout.png'),
136
		array('admin_forum', 'packages', 'package', 'package_info', 'packages_lg.png'),
137
		array('manage_smileys', 'smileys', 'smileys_manage', 'smileys_manage_info', 'smilies_and_messageicons.png'),
138
		array('moderate_forum', 'viewmembers', 'admin_users', 'member_center_info', 'members_lg.png'),
139
	);
140
141
	$available_admin_tasks = array();
142
	foreach ($quick_admin_tasks as $task)
143
	{
144
		if (!empty($task[0]) && !allowedTo($task[0]))
145
		{
146
			continue;
147
		}
148
149
		$available_admin_tasks[] = array(
150
			'href' => getUrl('admin', ['action' => 'admin', 'area' => $task[1]]),
151
			'link' => '<a href="' . getUrl('admin', ['action' => 'admin', 'area' => $task[1]]) . '">' . $txt[$task[2]] . '</a>',
152
			'title' => $txt[$task[2]],
153
			'description' => $txt[$task[3]],
154
			'icon' => $task[4],
155
			'is_last' => false
156
		);
157
	}
158
159
	if (count($available_admin_tasks) % 2 === 1)
160
	{
161
		$available_admin_tasks[] = array(
162
			'href' => '',
163
			'link' => '',
164
			'title' => '',
165
			'description' => '',
166
			'is_last' => true
167
		);
168
		$available_admin_tasks[count($available_admin_tasks) - 2]['is_last'] = true;
169
	}
170
	elseif (count($available_admin_tasks) !== 0)
171
	{
172
		$available_admin_tasks[count($available_admin_tasks) - 1]['is_last'] = true;
173
		$available_admin_tasks[count($available_admin_tasks) - 2]['is_last'] = true;
174
	}
175
176
	// Lastly, fill in the blanks in the support resources paragraphs.
177
	$txt['support_resources_p1'] = sprintf($txt['support_resources_p1'],
178
		'https://github.com/elkarte/Elkarte/wiki',
179
		'https://github.com/elkarte/Elkarte/wiki/features',
180
		'https://github.com/elkarte/Elkarte/wiki/options',
181
		'https://github.com/elkarte/Elkarte/wiki/themes',
182
		'https://github.com/elkarte/Elkarte/wiki/packages'
183
	);
184
	$txt['support_resources_p2'] = sprintf($txt['support_resources_p2'],
185
		'https://www.elkarte.net/',
186
		'https://www.elkarte.net/redirect/support',
187
		'https://www.elkarte.net/redirect/customize_support'
188
	);
189
190
	return $available_admin_tasks;
191
}
192
193
/**
194
 * Saves the admins current preferences to the database.
195
 *
196
 * @package Admin
197
 */
198
function updateAdminPreferences()
199
{
200
	global $options, $context, $settings;
201
202
	// This must exist!
203
	if (!isset($context['admin_preferences']))
204
	{
205
		return false;
206
	}
207
208
	// This is what we'll be saving.
209
	$options['admin_preferences'] = json_encode($context['admin_preferences']);
210
211
	require_once(SUBSDIR . '/Themes.subs.php');
212
213
	// Just check we haven't ended up with something theme exclusive somehow.
214
	removeThemeOptions('custom', 'all', 'admin_preferences');
215
216
	updateThemeOptions(array(1, User::$info->id, 'admin_preferences', $options['admin_preferences']));
217
218
	// Make sure we invalidate any cache.
219
	Cache::instance()->put('theme_settings-' . $settings['theme_id'] . ':' . User::$info->id, null, 0);
220
221
	return true;
222
}
223
224
/**
225
 * Send all the administrators a lovely email.
226
 *
227
 * What it does:
228
 *
229
 * - It loads all users who are admins or have the admin forum permission.
230
 * - It uses the email template and replacements passed in the parameters.
231
 * - It sends them an email.
232
 *
233
 * @param string $template
234
 * @param mixed[] $replacements
235
 * @param int[] $additional_recipients
236
 * @package Admin
237
 */
238
function emailAdmins($template, $replacements = array(), $additional_recipients = array())
239
{
240
	global $language, $modSettings;
241
242
	$db = database();
243
244
	// We certainly want this.
245
	require_once(SUBSDIR . '/Mail.subs.php');
246
247
	// Load all groups which are effectively admins.
248
	$groups = $db->fetchQuery('
249
		SELECT id_group
250
		FROM {db_prefix}permissions
251
		WHERE permission = {string:admin_forum}
252
			AND add_deny = {int:add_deny}
253
			AND id_group != {int:id_group}',
254
		array(
255
			'add_deny' => 1,
256
			'id_group' => 0,
257
			'admin_forum' => 'admin_forum',
258
		)
259
	)->fetch_all();
260
	$groups[] = 1;
261
	$groups = array_unique($groups);
262
263
	$emails_sent = $db->fetchQuery('
264
		SELECT id_member, member_name, real_name, lngfile, email_address
265
		FROM {db_prefix}members
266
		WHERE (id_group IN ({array_int:group_list}) OR FIND_IN_SET({raw:group_array_implode}, additional_groups) != 0)
267
			AND notify_types != {int:notify_types}
268
		ORDER BY lngfile',
269
		array(
270
			'group_list' => $groups,
271
			'notify_types' => 4,
272
			'group_array_implode' => implode(', additional_groups) != 0 OR FIND_IN_SET(', $groups),
273
		)
274
	)->fetch_callback(
275
		function ($row) use ($replacements, $modSettings, $language, $template) {
276
			// Stick their particulars in the replacement data.
277
			$replacements['IDMEMBER'] = $row['id_member'];
278
			$replacements['REALNAME'] = $row['member_name'];
279
			$replacements['USERNAME'] = $row['real_name'];
280
281
			// Load the data from the template.
282
			$emaildata = loadEmailTemplate($template, $replacements, empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile']);
283
284
			// Then send the actual email.
285
			sendmail($row['email_address'], $emaildata['subject'], $emaildata['body'], null, null, false, 1);
286
287
			// Track who we emailed so we don't do it twice.
288
			return $row['email_address'];
289
		}
290
	);
291
292
	// Any additional users we must email this to?
293
	if (!empty($additional_recipients))
294
	{
295
		foreach ($additional_recipients as $recipient)
296
		{
297
			if (in_array($recipient['email'], $emails_sent))
298
			{
299
				continue;
300
			}
301
302
			$replacements['IDMEMBER'] = $recipient['id'];
303
			$replacements['REALNAME'] = $recipient['name'];
304
			$replacements['USERNAME'] = $recipient['name'];
305
306
			// Load the template again.
307
			$emaildata = loadEmailTemplate($template, $replacements, empty($recipient['lang']) || empty($modSettings['userLanguage']) ? $language : $recipient['lang']);
308
309
			// Send off the email.
310
			sendmail($recipient['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 1);
311
		}
312
	}
313
}
314
315
/**
316
 * Callback used in the core features page when the custom profiles
317
 * are enabled or disabled.
318
 *
319
 * @param bool $value the "new" status of the profile fields
320
 * (true => enabled, false => disabled)
321
 * @package Admin
322
 */
323
function custom_profiles_toggle_callback($value)
324
{
325
	$db = database();
326
327
	if (!$value)
328
	{
329
		// Disable all fields. Wouldn't want any to show when the feature is disabled.
330
		$db->query('', '
331
			UPDATE {db_prefix}custom_fields
332
			SET 
333
				active = 0'
334
		);
335
	}
336
	else
337
	{
338
		// Set the display cache for the custom profile fields.
339
		require_once(SUBSDIR . '/ManageFeatures.subs.php');
340
		updateDisplayCache();
341
	}
342
}
343
344
/**
345
 * Callback used in the core features page when the paid subscriptions
346
 * are enabled or disabled.
347
 *
348
 * @param bool $value the "new" status of the paid subscriptions
349
 * (true => enabled, false => disabled)
350
 * @package Admin
351
 */
352
function subscriptions_toggle_callback($value)
353
{
354
	require_once(SUBSDIR . '/ScheduledTasks.subs.php');
355
	toggleTaskStatusByName('paid_subscriptions', $value);
356
357
	// Should we calculate next trigger?
358
	if ($value)
359
	{
360
		calculateNextTrigger('paid_subscriptions');
361
	}
362
}
363
364
/**
365
 * Callback used in the core features page when the post-by-email feature
366
 * is enabled or disabled.
367
 *
368
 * @param bool $value the "new" status of the post-by-email
369
 * (true => enabled, false => disabled)
370
 * @package Admin
371
 */
372
function postbyemail_toggle_callback($value)
373
{
374
	require_once(SUBSDIR . '/ScheduledTasks.subs.php');
375
	toggleTaskStatusByName('maillist_fetch_IMAP', $value);
376
377
	// Should we calculate next trigger?
378
	if ($value)
379
	{
380
		calculateNextTrigger('maillist_fetch_IMAP');
381
	}
382
}
383
384
/**
385
 * Enables a certain module on a set of controllers
386
 *
387
 * @param string $module the name of the module (e.g. drafts)
388
 * @param string[] $controllers list of controllers on which the module is
389
 *                 activated
390
 * @package Admin
391
 */
392
function enableModules($module, $controllers)
393
{
394
	global $modSettings;
395
396
	foreach ((array) $controllers as $controller)
397
	{
398
		if (!empty($modSettings['modules_' . $controller]))
399
		{
400
			$existing = explode(',', $modSettings['modules_' . $controller]);
401
		}
402
		else
403
		{
404
			$existing = array();
405
		}
406
407
		$existing[] = $module;
408
		$existing = array_filter(array_unique($existing));
409
		updateSettings(array('modules_' . $controller => implode(',', $existing)));
410
	}
411
}
412
413
/**
414
 * Disable a certain module on a set of controllers
415
 *
416
 * @param string $module the name of the module (e.g. drafts)
417
 * @param string[] $controllers list of controllers on which the module is
418
 *                 activated
419
 * @package Admin
420
 */
421
function disableModules($module, $controllers)
422
{
423
	global $modSettings;
424
425
	foreach ((array) $controllers as $controller)
426
	{
427
		if (!empty($modSettings['modules_' . $controller]))
428
		{
429
			$existing = explode(',', $modSettings['modules_' . $controller]);
430
		}
431
		else
432
		{
433
			$existing = array();
434
		}
435
436
		$existing = array_diff($existing, (array) $module);
437
		updateSettings(array('modules_' . $controller => implode(',', $existing)));
438
	}
439
}
440
441
/**
442
 * @param string $module the name of the module
443
 *
444
 * @return bool
445
 */
446
function isModuleEnabled($module)
447
{
448
	global $modSettings;
449
450
	$module = strtolower($module);
451
	foreach ($modSettings as $key => $val)
452
	{
453
		if (substr($key, 0, 8) === 'modules_')
454
		{
455
			$modules = explode(',', $val);
456
			if (in_array($module, $modules))
457
			{
458
				return true;
459
			}
460
		}
461
	}
462
463
	return false;
464
}
465