RegCenter()   B
last analyzed

Complexity

Conditions 7
Paths 16

Size

Total Lines 54
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 30
nc 16
nop 0
dl 0
loc 54
rs 8.5066
c 0
b 0
f 0

How to fix   Long Method   

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 helps the administrator setting registration settings and policy
5
 * as well as allow the administrator to register new members themselves.
6
 *
7
 * Simple Machines Forum (SMF)
8
 *
9
 * @package SMF
10
 * @author Simple Machines https://www.simplemachines.org
11
 * @copyright 2022 Simple Machines and individual contributors
12
 * @license https://www.simplemachines.org/about/smf/license.php BSD
13
 *
14
 * @version 2.1.0
15
 */
16
17
if (!defined('SMF'))
18
	die('No direct access...');
19
20
/**
21
 * Entrance point for the registration center, it checks permissions and forwards
22
 * to the right function based on the subaction.
23
 * Accessed by ?action=admin;area=regcenter.
24
 * Requires either the moderate_forum or the admin_forum permission.
25
 *
26
 * Uses Login language file
27
 * Uses Register template.
28
 */
29
function RegCenter()
30
{
31
	global $context, $txt;
32
33
	// Old templates might still request this.
34
	if (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'browse')
35
		redirectexit('action=admin;area=viewmembers;sa=browse' . (isset($_REQUEST['type']) ? ';type=' . $_REQUEST['type'] : ''));
36
37
	$subActions = array(
38
		'register' => array('AdminRegister', 'moderate_forum'),
39
		'agreement' => array('EditAgreement', 'admin_forum'),
40
		'policy' => array('EditPrivacyPolicy', 'admin_forum'),
41
		'reservednames' => array('SetReserved', 'admin_forum'),
42
		'settings' => array('ModifyRegistrationSettings', 'admin_forum'),
43
	);
44
45
	// Work out which to call...
46
	$context['sub_action'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : (allowedTo('moderate_forum') ? 'register' : 'settings');
47
48
	// Must have sufficient permissions.
49
	isAllowedTo($subActions[$context['sub_action']][1]);
50
51
	// Loading, always loading.
52
	loadLanguage('Login');
53
	loadTemplate('Register');
54
55
	// Next create the tabs for the template.
56
	$context[$context['admin_menu_name']]['tab_data'] = array(
57
		'title' => $txt['registration_center'],
58
		'help' => 'registrations',
59
		'description' => $txt['admin_settings_desc'],
60
		'tabs' => array(
61
			'register' => array(
62
				'description' => $txt['admin_register_desc'],
63
			),
64
			'agreement' => array(
65
				'description' => $txt['registration_agreement_desc'],
66
			),
67
			'policy' => array(
68
				'description' => $txt['privacy_policy_desc'],
69
			),
70
			'reservednames' => array(
71
				'description' => $txt['admin_reserved_desc'],
72
			),
73
			'settings' => array(
74
				'description' => $txt['admin_settings_desc'],
75
			)
76
		)
77
	);
78
79
	call_integration_hook('integrate_manage_registrations', array(&$subActions));
80
81
	// Finally, get around to calling the function...
82
	call_helper($subActions[$context['sub_action']][0]);
83
}
84
85
/**
86
 * This function allows the admin to register a new member by hand.
87
 * It also allows assigning a primary group to the member being registered.
88
 * Accessed by ?action=admin;area=regcenter;sa=register
89
 * Requires the moderate_forum permission.
90
 *
91
 * @uses template_admin_register()
92
 */
93
function AdminRegister()
94
{
95
	global $txt, $context, $sourcedir, $scripturl, $smcFunc;
96
97
	// Are there any custom profile fields required during registration?
98
	require_once($sourcedir . '/Profile.php');
99
	loadCustomFields(0, 'register');
100
101
	if (!empty($_POST['regSubmit']))
102
	{
103
		checkSession();
104
		validateToken('admin-regc');
105
106
		foreach ($_POST as $key => $value)
107
			if (!is_array($_POST[$key]))
108
				$_POST[$key] = htmltrim__recursive(str_replace(array("\n", "\r"), '', $smcFunc['normalize']($_POST[$key])));
109
110
		$regOptions = array(
111
			'interface' => 'admin',
112
			'username' => $_POST['user'],
113
			'email' => $_POST['email'],
114
			'password' => $_POST['password'],
115
			'password_check' => $_POST['password'],
116
			'check_reserved_name' => true,
117
			'check_password_strength' => false,
118
			'check_email_ban' => false,
119
			'send_welcome_email' => isset($_POST['emailPassword']) || empty($_POST['password']),
120
			'require' => isset($_POST['emailActivate']) ? 'activation' : 'nothing',
121
			'memberGroup' => empty($_POST['group']) || !allowedTo('manage_membergroups') ? 0 : (int) $_POST['group'],
122
		);
123
124
		require_once($sourcedir . '/Subs-Members.php');
125
		$memberID = registerMember($regOptions);
126
		if (!empty($memberID))
127
		{
128
			// We'll do custom fields after as then we get to use the helper function!
129
			if (!empty($_POST['customfield']))
130
			{
131
				require_once($sourcedir . '/Profile-Modify.php');
132
				makeCustomFieldChanges($memberID, 'register');
133
			}
134
135
			$context['new_member'] = array(
136
				'id' => $memberID,
137
				'name' => $_POST['user'],
138
				'href' => $scripturl . '?action=profile;u=' . $memberID,
139
				'link' => '<a href="' . $scripturl . '?action=profile;u=' . $memberID . '">' . $_POST['user'] . '</a>',
140
			);
141
			$context['registration_done'] = sprintf($txt['admin_register_done'], $context['new_member']['link']);
142
		}
143
	}
144
145
	// Load the assignable member groups.
146
	if (allowedTo('manage_membergroups'))
147
	{
148
		$request = $smcFunc['db_query']('', '
149
			SELECT group_name, id_group
150
			FROM {db_prefix}membergroups
151
			WHERE id_group != {int:moderator_group}
152
				AND min_posts = {int:min_posts}' . (allowedTo('admin_forum') ? '' : '
153
				AND id_group != {int:admin_group}
154
				AND group_type != {int:is_protected}') . '
155
				AND hidden != {int:hidden_group}
156
			ORDER BY min_posts, CASE WHEN id_group < {int:newbie_group} THEN id_group ELSE 4 END, group_name',
157
			array(
158
				'moderator_group' => 3,
159
				'min_posts' => -1,
160
				'admin_group' => 1,
161
				'is_protected' => 1,
162
				'hidden_group' => 2,
163
				'newbie_group' => 4,
164
			)
165
		);
166
		$context['member_groups'] = array(0 => $txt['admin_register_group_none']);
167
		while ($row = $smcFunc['db_fetch_assoc']($request))
168
			$context['member_groups'][$row['id_group']] = $row['group_name'];
169
		$smcFunc['db_free_result']($request);
170
	}
171
	else
172
		$context['member_groups'] = array();
173
174
	// Basic stuff.
175
	$context['sub_template'] = 'admin_register';
176
	$context['page_title'] = $txt['registration_center'];
177
	createToken('admin-regc');
178
	loadJavaScriptFile('register.js', array('defer' => false, 'minimize' => true), 'smf_register');
179
}
180
181
/**
182
 * Allows the administrator to edit the registration agreement, and choose whether
183
 * it should be shown or not. It writes and saves the agreement to the agreement.txt
184
 * file.
185
 * Accessed by ?action=admin;area=regcenter;sa=agreement.
186
 * Requires the admin_forum permission.
187
 *
188
 * @uses template_edit_agreement()
189
 */
190
function EditAgreement()
191
{
192
	// I hereby agree not to be a lazy bum.
193
	global $txt, $boarddir, $context, $modSettings, $smcFunc, $user_info;
194
195
	// By default we look at agreement.txt.
196
	$context['current_agreement'] = '';
197
198
	// Is there more than one to edit?
199
	$context['editable_agreements'] = array(
200
		'' => $txt['admin_agreement_default'],
201
	);
202
203
	// Get our languages.
204
	getLanguages();
205
206
	// Try to figure out if we have more agreements.
207
	foreach ($context['languages'] as $lang)
208
	{
209
		if (file_exists($boarddir . '/agreement.' . $lang['filename'] . '.txt'))
210
		{
211
			$context['editable_agreements']['.' . $lang['filename']] = $lang['name'];
212
			// Are we editing this?
213
			if (isset($_POST['agree_lang']) && $_POST['agree_lang'] == '.' . $lang['filename'])
214
				$context['current_agreement'] = '.' . $lang['filename'];
215
		}
216
	}
217
218
	$agreement_lang = empty($context['current_agreement']) ? 'default' : substr($context['current_agreement'], 1);
219
220
	$context['agreement'] = file_exists($boarddir . '/agreement' . $context['current_agreement'] . '.txt') ? str_replace("\r", '', file_get_contents($boarddir . '/agreement' . $context['current_agreement'] . '.txt')) : '';
221
222
	if (isset($_POST['agreement']) && str_replace("\r", '', $_POST['agreement']) != $context['agreement'])
223
	{
224
		checkSession();
225
		validateToken('admin-rega');
226
227
		$_POST['agreement'] = $smcFunc['normalize']($_POST['agreement']);
228
229
		// Off it goes to the agreement file.
230
		$to_write = str_replace("\r", '', $_POST['agreement']);
231
		$bytes = file_put_contents($boarddir . '/agreement' . $context['current_agreement'] . '.txt', $to_write, LOCK_EX);
232
233
		$agreement_settings['agreement_updated_' . $agreement_lang] = time();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$agreement_settings was never initialized. Although not strictly required by PHP, it is generally a good practice to add $agreement_settings = array(); before regardless.
Loading history...
234
235
		if ($bytes == strlen($to_write))
236
			$context['saved_successful'] = true;
237
		else
238
			$context['could_not_save'] = true;
239
240
		// Writing it counts as agreeing to it, right?
241
		$smcFunc['db_insert']('replace',
242
			'{db_prefix}themes',
243
			array('id_member' => 'int', 'id_theme' => 'int', 'variable' => 'string', 'value' => 'string'),
244
			array($user_info['id'], 1, 'agreement_accepted', time()),
245
			array('id_member', 'id_theme', 'variable')
246
		);
247
		logAction('agreement_updated', array('language' => $context['editable_agreements'][$context['current_agreement']]), 'admin');
248
		logAction('agreement_accepted', array('applicator' => $user_info['id']), 'user');
249
250
		updateSettings($agreement_settings);
251
252
		$context['agreement'] = str_replace("\r", '', $_POST['agreement']);
253
	}
254
255
	$context['agreement_info'] = sprintf($txt['admin_agreement_info'], empty($modSettings['agreement_updated_' . $agreement_lang]) ? $txt['never'] : timeformat($modSettings['agreement_updated_' . $agreement_lang]));
256
257
	$context['agreement'] = $smcFunc['htmlspecialchars']($context['agreement']);
258
	$context['warning'] = is_writable($boarddir . '/agreement' . $context['current_agreement'] . '.txt') ? '' : $txt['agreement_not_writable'];
259
260
	$context['sub_template'] = 'edit_agreement';
261
	$context['page_title'] = $txt['registration_agreement'];
262
263
	createToken('admin-rega');
264
}
265
266
/**
267
 * Set the names under which users are not allowed to register.
268
 * Accessed by ?action=admin;area=regcenter;sa=reservednames.
269
 * Requires the admin_forum permission.
270
 *
271
 * @uses template_edit_reserved_words()
272
 */
273
function SetReserved()
274
{
275
	global $txt, $context, $modSettings, $smcFunc;
276
277
	// Submitting new reserved words.
278
	if (!empty($_POST['save_reserved_names']))
279
	{
280
		checkSession();
281
		validateToken('admin-regr');
282
283
		$_POST['reserved'] = $smcFunc['normalize']($_POST['reserved']);
284
285
		// Set all the options....
286
		updateSettings(array(
287
			'reserveWord' => (isset($_POST['matchword']) ? '1' : '0'),
288
			'reserveCase' => (isset($_POST['matchcase']) ? '1' : '0'),
289
			'reserveUser' => (isset($_POST['matchuser']) ? '1' : '0'),
290
			'reserveName' => (isset($_POST['matchname']) ? '1' : '0'),
291
			'reserveNames' => str_replace("\r", '', $_POST['reserved'])
292
		));
293
		$context['saved_successful'] = true;
294
	}
295
296
	// Get the reserved word options and words.
297
	$modSettings['reserveNames'] = str_replace('\n', "\n", $modSettings['reserveNames']);
298
	$context['reserved_words'] = explode("\n", $modSettings['reserveNames']);
299
	$context['reserved_word_options'] = array();
300
	$context['reserved_word_options']['match_word'] = $modSettings['reserveWord'] == '1';
301
	$context['reserved_word_options']['match_case'] = $modSettings['reserveCase'] == '1';
302
	$context['reserved_word_options']['match_user'] = $modSettings['reserveUser'] == '1';
303
	$context['reserved_word_options']['match_name'] = $modSettings['reserveName'] == '1';
304
305
	// Ready the template......
306
	$context['sub_template'] = 'edit_reserved_words';
307
	$context['page_title'] = $txt['admin_reserved_set'];
308
	createToken('admin-regr');
309
}
310
311
/**
312
 * This function handles registration settings, and provides a few pretty stats too while it's at it.
313
 * General registration settings and Coppa compliance settings.
314
 * Accessed by ?action=admin;area=regcenter;sa=settings.
315
 * Requires the admin_forum permission.
316
 *
317
 * @param bool $return_config Whether or not to return the config_vars array (used for admin search)
318
 * @return void|array Returns nothing or returns the $config_vars array if $return_config is true
319
 */
320
function ModifyRegistrationSettings($return_config = false)
321
{
322
	global $txt, $context, $scripturl, $modSettings, $sourcedir, $smcFunc;
323
	global $language, $boarddir;
324
325
	// This is really quite wanting.
326
	require_once($sourcedir . '/ManageServer.php');
327
328
	// Do we have at least default versions of the agreement and privacy policy?
329
	$agreement = file_exists($boarddir . '/agreement.' . $language . '.txt') || file_exists($boarddir . '/agreement.txt');
330
	$policy = !empty($modSettings['policy_' . $language]);
331
332
	$config_vars = array(
333
		array('select', 'registration_method', array($txt['setting_registration_standard'], $txt['setting_registration_activate'], $txt['setting_registration_approval'], $txt['setting_registration_disabled'])),
334
		array('check', 'send_welcomeEmail'),
335
	'',
336
		array('check', 'requireAgreement', 'text_label' => $txt['admin_agreement'], 'value' => !empty($modSettings['requireAgreement'])),
337
		array('warning', empty($agreement) ? 'error_no_agreement' : ''),
338
		array('check', 'requirePolicyAgreement', 'text_label' => $txt['admin_privacy_policy'], 'value' => !empty($modSettings['requirePolicyAgreement'])),
339
		array('warning', empty($policy) ? 'error_no_privacy_policy' : ''),
340
	'',
341
		array('int', 'coppaAge', 'subtext' => $txt['zero_to_disable'], 'onchange' => 'checkCoppa();'),
342
		array('select', 'coppaType', array($txt['setting_coppaType_reject'], $txt['setting_coppaType_approval']), 'onchange' => 'checkCoppa();'),
343
		array('large_text', 'coppaPost', 'subtext' => $txt['setting_coppaPost_desc']),
344
		array('text', 'coppaFax'),
345
		array('text', 'coppaPhone'),
346
	);
347
348
	call_integration_hook('integrate_modify_registration_settings', array(&$config_vars));
349
350
	if ($return_config)
351
		return $config_vars;
352
353
	// Setup the template
354
	$context['sub_template'] = 'show_settings';
355
	$context['page_title'] = $txt['registration_center'];
356
357
	if (isset($_GET['save']))
358
	{
359
		checkSession();
360
361
		// Are there some contacts missing?
362
		if (!empty($_POST['coppaAge']) && !empty($_POST['coppaType']) && empty($_POST['coppaPost']) && empty($_POST['coppaFax']))
363
			fatal_lang_error('admin_setting_coppa_require_contact');
364
365
		// Post needs to take into account line breaks.
366
		$_POST['coppaPost'] = str_replace("\n", '<br>', empty($_POST['coppaPost']) ? '' : $smcFunc['normalize']($_POST['coppaPost']));
367
368
		call_integration_hook('integrate_save_registration_settings');
369
370
		saveDBSettings($config_vars);
371
		$_SESSION['adm-save'] = true;
372
		redirectexit('action=admin;area=regcenter;sa=settings');
373
	}
374
375
	$context['post_url'] = $scripturl . '?action=admin;area=regcenter;save;sa=settings';
376
	$context['settings_title'] = $txt['settings'];
377
378
	// Define some javascript for COPPA.
379
	$context['settings_post_javascript'] = '
380
		function checkCoppa()
381
		{
382
			var coppaDisabled = document.getElementById(\'coppaAge\').value == 0;
383
			document.getElementById(\'coppaType\').disabled = coppaDisabled;
384
385
			var disableContacts = coppaDisabled || document.getElementById(\'coppaType\').options[document.getElementById(\'coppaType\').selectedIndex].value != 1;
386
			document.getElementById(\'coppaPost\').disabled = disableContacts;
387
			document.getElementById(\'coppaFax\').disabled = disableContacts;
388
			document.getElementById(\'coppaPhone\').disabled = disableContacts;
389
		}
390
		checkCoppa();';
391
392
	// Turn the postal address into something suitable for a textbox.
393
	$modSettings['coppaPost'] = !empty($modSettings['coppaPost']) ? preg_replace('~<br ?/?' . '>~', "\n", $modSettings['coppaPost']) : '';
394
395
	prepareDBSettingContext($config_vars);
396
}
397
398
// Sure, you can sell my personal info for profit (...or not)
399
function EditPrivacyPolicy()
400
{
401
	global $txt, $boarddir, $context, $modSettings, $smcFunc, $user_info;
402
403
	// By default, edit the current language's policy
404
	$context['current_policy_lang'] = $user_info['language'];
405
406
	// We need a policy for every language
407
	getLanguages();
408
409
	foreach ($context['languages'] as $lang)
410
	{
411
		$context['editable_policies'][$lang['filename']] = $lang['name'];
412
413
		// Are we editing this one?
414
		if (isset($_POST['policy_lang']) && $_POST['policy_lang'] == $lang['filename'])
415
			$context['current_policy_lang'] = $lang['filename'];
416
	}
417
418
	$context['privacy_policy'] = empty($modSettings['policy_' . $context['current_policy_lang']]) ? '' : $modSettings['policy_' . $context['current_policy_lang']];
419
420
	if (isset($_POST['policy']))
421
	{
422
		checkSession();
423
		validateToken('admin-regp');
424
425
		// Make sure there are no creepy-crawlies in it
426
		$policy_text = $smcFunc['htmlspecialchars'](str_replace("\r", '', $_POST['policy']));
427
428
		$policy_settings = array(
429
			'policy_' . $context['current_policy_lang'] => $policy_text,
430
		);
431
432
		$policy_settings['policy_updated_' . $context['current_policy_lang']] = time();
433
434
		// Writing it counts as agreeing to it, right?
435
		$smcFunc['db_insert']('replace',
436
			'{db_prefix}themes',
437
			array('id_member' => 'int', 'id_theme' => 'int', 'variable' => 'string', 'value' => 'string'),
438
			array($user_info['id'], 1, 'policy_accepted', time()),
439
			array('id_member', 'id_theme', 'variable')
440
		);
441
		logAction('policy_updated', array('language' => $context['editable_policies'][$context['current_policy_lang']]), 'admin');
442
		logAction('policy_accepted', array('applicator' => $user_info['id']), 'user');
443
444
		if ($context['privacy_policy'] !== $policy_text)
445
			$context['saved_successful'] = true;
446
447
		updateSettings($policy_settings);
448
449
		$context['privacy_policy'] = $policy_text;
450
	}
451
452
	$context['privacy_policy_info'] = sprintf($txt['admin_agreement_info'], empty($modSettings['policy_updated_' . $context['current_policy_lang']]) ? $txt['never'] : timeformat($modSettings['policy_updated_' . $context['current_policy_lang']]));
453
454
	$context['sub_template'] = 'edit_privacy_policy';
455
	$context['page_title'] = $txt['privacy_policy'];
456
457
	createToken('admin-regp');
458
}
459
460
?>