albertlast /
SMF2.1
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 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 http://www.simplemachines.org |
||
| 11 | * @copyright 2017 Simple Machines and individual contributors |
||
| 12 | * @license http://www.simplemachines.org/about/smf/license.php BSD |
||
| 13 | * |
||
| 14 | * @version 2.1 Beta 4 |
||
| 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 | 'reservednames' => array('SetReserved', 'admin_forum'), |
||
| 41 | 'settings' => array('ModifyRegistrationSettings', 'admin_forum'), |
||
| 42 | ); |
||
| 43 | |||
| 44 | // Work out which to call... |
||
| 45 | $context['sub_action'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : (allowedTo('moderate_forum') ? 'register' : 'settings'); |
||
| 46 | |||
| 47 | // Must have sufficient permissions. |
||
| 48 | isAllowedTo($subActions[$context['sub_action']][1]); |
||
| 49 | |||
| 50 | // Loading, always loading. |
||
| 51 | loadLanguage('Login'); |
||
| 52 | loadTemplate('Register'); |
||
| 53 | |||
| 54 | // Next create the tabs for the template. |
||
| 55 | $context[$context['admin_menu_name']]['tab_data'] = array( |
||
| 56 | 'title' => $txt['registration_center'], |
||
| 57 | 'help' => 'registrations', |
||
| 58 | 'description' => $txt['admin_settings_desc'], |
||
| 59 | 'tabs' => array( |
||
| 60 | 'register' => array( |
||
| 61 | 'description' => $txt['admin_register_desc'], |
||
| 62 | ), |
||
| 63 | 'agreement' => array( |
||
| 64 | 'description' => $txt['registration_agreement_desc'], |
||
| 65 | ), |
||
| 66 | 'reservednames' => array( |
||
| 67 | 'description' => $txt['admin_reserved_desc'], |
||
| 68 | ), |
||
| 69 | 'settings' => array( |
||
| 70 | 'description' => $txt['admin_settings_desc'], |
||
| 71 | ) |
||
| 72 | ) |
||
| 73 | ); |
||
| 74 | |||
| 75 | call_integration_hook('integrate_manage_registrations', array(&$subActions)); |
||
| 76 | |||
| 77 | // Finally, get around to calling the function... |
||
| 78 | call_helper($subActions[$context['sub_action']][0]); |
||
| 79 | } |
||
| 80 | |||
| 81 | /** |
||
| 82 | * This function allows the admin to register a new member by hand. |
||
| 83 | * It also allows assigning a primary group to the member being registered. |
||
| 84 | * Accessed by ?action=admin;area=regcenter;sa=register |
||
| 85 | * Requires the moderate_forum permission. |
||
| 86 | * |
||
| 87 | * @uses Register template, admin_register sub-template. |
||
| 88 | */ |
||
| 89 | function AdminRegister() |
||
| 90 | { |
||
| 91 | global $txt, $context, $sourcedir, $scripturl, $smcFunc; |
||
| 92 | |||
| 93 | // Are there any custom profile fields required during registration? |
||
| 94 | require_once($sourcedir . '/Profile.php'); |
||
| 95 | loadCustomFields(0, 'register'); |
||
| 96 | |||
| 97 | if (!empty($_POST['regSubmit'])) |
||
| 98 | { |
||
| 99 | checkSession(); |
||
| 100 | validateToken('admin-regc'); |
||
| 101 | |||
| 102 | View Code Duplication | foreach ($_POST as $key => $value) |
|
|
0 ignored issues
–
show
|
|||
| 103 | if (!is_array($_POST[$key])) |
||
| 104 | $_POST[$key] = htmltrim__recursive(str_replace(array("\n", "\r"), '', $_POST[$key])); |
||
| 105 | |||
| 106 | $regOptions = array( |
||
| 107 | 'interface' => 'admin', |
||
| 108 | 'username' => $_POST['user'], |
||
| 109 | 'email' => $_POST['email'], |
||
| 110 | 'password' => $_POST['password'], |
||
| 111 | 'password_check' => $_POST['password'], |
||
| 112 | 'check_reserved_name' => true, |
||
| 113 | 'check_password_strength' => false, |
||
| 114 | 'check_email_ban' => false, |
||
| 115 | 'send_welcome_email' => isset($_POST['emailPassword']) || empty($_POST['password']), |
||
| 116 | 'require' => isset($_POST['emailActivate']) ? 'activation' : 'nothing', |
||
| 117 | 'memberGroup' => empty($_POST['group']) || !allowedTo('manage_membergroups') ? 0 : (int) $_POST['group'], |
||
| 118 | ); |
||
| 119 | |||
| 120 | require_once($sourcedir . '/Subs-Members.php'); |
||
| 121 | $memberID = registerMember($regOptions); |
||
| 122 | if (!empty($memberID)) |
||
| 123 | { |
||
| 124 | // We'll do custom fields after as then we get to use the helper function! |
||
| 125 | if (!empty($_POST['customfield'])) |
||
| 126 | { |
||
| 127 | require_once($sourcedir . '/Profile-Modify.php'); |
||
| 128 | makeCustomFieldChanges($memberID, 'register'); |
||
| 129 | } |
||
| 130 | |||
| 131 | $context['new_member'] = array( |
||
| 132 | 'id' => $memberID, |
||
| 133 | 'name' => $_POST['user'], |
||
| 134 | 'href' => $scripturl . '?action=profile;u=' . $memberID, |
||
| 135 | 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $memberID . '">' . $_POST['user'] . '</a>', |
||
| 136 | ); |
||
| 137 | $context['registration_done'] = sprintf($txt['admin_register_done'], $context['new_member']['link']); |
||
| 138 | } |
||
| 139 | } |
||
| 140 | |||
| 141 | |||
| 142 | // Load the assignable member groups. |
||
| 143 | if (allowedTo('manage_membergroups')) |
||
| 144 | { |
||
| 145 | $request = $smcFunc['db_query']('', ' |
||
| 146 | SELECT group_name, id_group |
||
| 147 | FROM {db_prefix}membergroups |
||
| 148 | WHERE id_group != {int:moderator_group} |
||
| 149 | AND min_posts = {int:min_posts}' . (allowedTo('admin_forum') ? '' : ' |
||
| 150 | AND id_group != {int:admin_group} |
||
| 151 | AND group_type != {int:is_protected}') . ' |
||
| 152 | AND hidden != {int:hidden_group} |
||
| 153 | ORDER BY min_posts, CASE WHEN id_group < {int:newbie_group} THEN id_group ELSE 4 END, group_name', |
||
| 154 | array( |
||
| 155 | 'moderator_group' => 3, |
||
| 156 | 'min_posts' => -1, |
||
| 157 | 'admin_group' => 1, |
||
| 158 | 'is_protected' => 1, |
||
| 159 | 'hidden_group' => 2, |
||
| 160 | 'newbie_group' => 4, |
||
| 161 | ) |
||
| 162 | ); |
||
| 163 | $context['member_groups'] = array(0 => $txt['admin_register_group_none']); |
||
| 164 | View Code Duplication | while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 165 | $context['member_groups'][$row['id_group']] = $row['group_name']; |
||
| 166 | $smcFunc['db_free_result']($request); |
||
| 167 | } |
||
| 168 | else |
||
| 169 | $context['member_groups'] = array(); |
||
| 170 | |||
| 171 | // Basic stuff. |
||
| 172 | $context['sub_template'] = 'admin_register'; |
||
| 173 | $context['page_title'] = $txt['registration_center']; |
||
| 174 | createToken('admin-regc'); |
||
| 175 | loadJavaScriptFile('register.js', array('defer' => false), 'smf_register'); |
||
| 176 | } |
||
| 177 | |||
| 178 | /** |
||
| 179 | * Allows the administrator to edit the registration agreement, and choose whether |
||
| 180 | * it should be shown or not. It writes and saves the agreement to the agreement.txt |
||
| 181 | * file. |
||
| 182 | * Accessed by ?action=admin;area=regcenter;sa=agreement. |
||
| 183 | * Requires the admin_forum permission. |
||
| 184 | * |
||
| 185 | * @uses Admin template and the edit_agreement sub template. |
||
| 186 | */ |
||
| 187 | function EditAgreement() |
||
| 188 | { |
||
| 189 | // I hereby agree not to be a lazy bum. |
||
| 190 | global $txt, $boarddir, $context, $modSettings, $smcFunc; |
||
| 191 | |||
| 192 | // By default we look at agreement.txt. |
||
| 193 | $context['current_agreement'] = ''; |
||
| 194 | |||
| 195 | // Is there more than one to edit? |
||
| 196 | $context['editable_agreements'] = array( |
||
| 197 | '' => $txt['admin_agreement_default'], |
||
| 198 | ); |
||
| 199 | |||
| 200 | // Get our languages. |
||
| 201 | getLanguages(); |
||
| 202 | |||
| 203 | // Try to figure out if we have more agreements. |
||
| 204 | foreach ($context['languages'] as $lang) |
||
| 205 | { |
||
| 206 | if (file_exists($boarddir . '/agreement.' . $lang['filename'] . '.txt')) |
||
| 207 | { |
||
| 208 | $context['editable_agreements']['.' . $lang['filename']] = $lang['name']; |
||
| 209 | // Are we editing this? |
||
| 210 | if (isset($_POST['agree_lang']) && $_POST['agree_lang'] == '.' . $lang['filename']) |
||
| 211 | $context['current_agreement'] = '.' . $lang['filename']; |
||
| 212 | } |
||
| 213 | } |
||
| 214 | |||
| 215 | if (isset($_POST['agreement'])) |
||
| 216 | { |
||
| 217 | checkSession(); |
||
| 218 | validateToken('admin-rega'); |
||
| 219 | |||
| 220 | // Off it goes to the agreement file. |
||
| 221 | $to_write = str_replace("\r", '', $_POST['agreement']); |
||
| 222 | $bytes = file_put_contents($boarddir . '/agreement' . $context['current_agreement'] . '.txt', $to_write, LOCK_EX); |
||
| 223 | |||
| 224 | updateSettings(array('requireAgreement' => !empty($_POST['requireAgreement']))); |
||
| 225 | |||
| 226 | if ($bytes == strlen($to_write)) |
||
| 227 | $context['saved_successful'] = true; |
||
| 228 | else |
||
| 229 | $context['could_not_save'] = true; |
||
| 230 | } |
||
| 231 | |||
| 232 | $context['agreement'] = file_exists($boarddir . '/agreement' . $context['current_agreement'] . '.txt') ? $smcFunc['htmlspecialchars'](file_get_contents($boarddir . '/agreement' . $context['current_agreement'] . '.txt')) : ''; |
||
| 233 | $context['warning'] = is_writable($boarddir . '/agreement' . $context['current_agreement'] . '.txt') ? '' : $txt['agreement_not_writable']; |
||
| 234 | $context['require_agreement'] = !empty($modSettings['requireAgreement']); |
||
| 235 | |||
| 236 | $context['sub_template'] = 'edit_agreement'; |
||
| 237 | $context['page_title'] = $txt['registration_agreement']; |
||
| 238 | createToken('admin-rega'); |
||
| 239 | } |
||
| 240 | |||
| 241 | /** |
||
| 242 | * Set the names under which users are not allowed to register. |
||
| 243 | * Accessed by ?action=admin;area=regcenter;sa=reservednames. |
||
| 244 | * Requires the admin_forum permission. |
||
| 245 | * |
||
| 246 | * @uses Register template, reserved_words sub-template. |
||
| 247 | */ |
||
| 248 | function SetReserved() |
||
| 249 | { |
||
| 250 | global $txt, $context, $modSettings; |
||
| 251 | |||
| 252 | // Submitting new reserved words. |
||
| 253 | if (!empty($_POST['save_reserved_names'])) |
||
| 254 | { |
||
| 255 | checkSession(); |
||
| 256 | validateToken('admin-regr'); |
||
| 257 | |||
| 258 | // Set all the options.... |
||
| 259 | updateSettings(array( |
||
| 260 | 'reserveWord' => (isset($_POST['matchword']) ? '1' : '0'), |
||
| 261 | 'reserveCase' => (isset($_POST['matchcase']) ? '1' : '0'), |
||
| 262 | 'reserveUser' => (isset($_POST['matchuser']) ? '1' : '0'), |
||
| 263 | 'reserveName' => (isset($_POST['matchname']) ? '1' : '0'), |
||
| 264 | 'reserveNames' => str_replace("\r", '', $_POST['reserved']) |
||
| 265 | )); |
||
| 266 | $context['saved_successful'] = true; |
||
| 267 | } |
||
| 268 | |||
| 269 | // Get the reserved word options and words. |
||
| 270 | $modSettings['reserveNames'] = str_replace('\n', "\n", $modSettings['reserveNames']); |
||
| 271 | $context['reserved_words'] = explode("\n", $modSettings['reserveNames']); |
||
| 272 | $context['reserved_word_options'] = array(); |
||
| 273 | $context['reserved_word_options']['match_word'] = $modSettings['reserveWord'] == '1'; |
||
| 274 | $context['reserved_word_options']['match_case'] = $modSettings['reserveCase'] == '1'; |
||
| 275 | $context['reserved_word_options']['match_user'] = $modSettings['reserveUser'] == '1'; |
||
| 276 | $context['reserved_word_options']['match_name'] = $modSettings['reserveName'] == '1'; |
||
| 277 | |||
| 278 | // Ready the template...... |
||
| 279 | $context['sub_template'] = 'edit_reserved_words'; |
||
| 280 | $context['page_title'] = $txt['admin_reserved_set']; |
||
| 281 | createToken('admin-regr'); |
||
| 282 | } |
||
| 283 | |||
| 284 | /** |
||
| 285 | * This function handles registration settings, and provides a few pretty stats too while it's at it. |
||
| 286 | * General registration settings and Coppa compliance settings. |
||
| 287 | * Accessed by ?action=admin;area=regcenter;sa=settings. |
||
| 288 | * Requires the admin_forum permission. |
||
| 289 | * |
||
| 290 | * @param bool $return_config Whether or not to return the config_vars array (used for admin search) |
||
| 291 | * @return void|array Returns nothing or returns the $config_vars array if $return_config is true |
||
| 292 | */ |
||
| 293 | function ModifyRegistrationSettings($return_config = false) |
||
| 294 | { |
||
| 295 | global $txt, $context, $scripturl, $modSettings, $sourcedir; |
||
| 296 | |||
| 297 | // This is really quite wanting. |
||
| 298 | require_once($sourcedir . '/ManageServer.php'); |
||
| 299 | |||
| 300 | $config_vars = array( |
||
| 301 | array('select', 'registration_method', array($txt['setting_registration_standard'], $txt['setting_registration_activate'], $txt['setting_registration_approval'], $txt['setting_registration_disabled'])), |
||
| 302 | array('check', 'send_welcomeEmail'), |
||
| 303 | '', |
||
| 304 | array('int', 'coppaAge', 'subtext' => $txt['zero_to_disable'], 'onchange' => 'checkCoppa();', 'onkeyup' => 'checkCoppa();'), |
||
| 305 | array('select', 'coppaType', array($txt['setting_coppaType_reject'], $txt['setting_coppaType_approval']), 'onchange' => 'checkCoppa();'), |
||
| 306 | array('large_text', 'coppaPost', 'subtext' => $txt['setting_coppaPost_desc']), |
||
| 307 | array('text', 'coppaFax'), |
||
| 308 | array('text', 'coppaPhone'), |
||
| 309 | ); |
||
| 310 | |||
| 311 | call_integration_hook('integrate_modify_registration_settings', array(&$config_vars)); |
||
| 312 | |||
| 313 | if ($return_config) |
||
| 314 | return $config_vars; |
||
| 315 | |||
| 316 | // Setup the template |
||
| 317 | $context['sub_template'] = 'show_settings'; |
||
| 318 | $context['page_title'] = $txt['registration_center']; |
||
| 319 | |||
| 320 | if (isset($_GET['save'])) |
||
| 321 | { |
||
| 322 | checkSession(); |
||
| 323 | |||
| 324 | // Are there some contacts missing? |
||
| 325 | if (!empty($_POST['coppaAge']) && !empty($_POST['coppaType']) && empty($_POST['coppaPost']) && empty($_POST['coppaFax'])) |
||
| 326 | fatal_lang_error('admin_setting_coppa_require_contact'); |
||
| 327 | |||
| 328 | // Post needs to take into account line breaks. |
||
| 329 | $_POST['coppaPost'] = str_replace("\n", '<br>', empty($_POST['coppaPost']) ? '' : $_POST['coppaPost']); |
||
| 330 | |||
| 331 | call_integration_hook('integrate_save_registration_settings'); |
||
| 332 | |||
| 333 | saveDBSettings($config_vars); |
||
| 334 | $_SESSION['adm-save'] = true; |
||
| 335 | redirectexit('action=admin;area=regcenter;sa=settings'); |
||
| 336 | } |
||
| 337 | |||
| 338 | $context['post_url'] = $scripturl . '?action=admin;area=regcenter;save;sa=settings'; |
||
| 339 | $context['settings_title'] = $txt['settings']; |
||
| 340 | |||
| 341 | // Define some javascript for COPPA. |
||
| 342 | $context['settings_post_javascript'] = ' |
||
| 343 | function checkCoppa() |
||
| 344 | { |
||
| 345 | var coppaDisabled = document.getElementById(\'coppaAge\').value == 0; |
||
| 346 | document.getElementById(\'coppaType\').disabled = coppaDisabled; |
||
| 347 | |||
| 348 | var disableContacts = coppaDisabled || document.getElementById(\'coppaType\').options[document.getElementById(\'coppaType\').selectedIndex].value != 1; |
||
| 349 | document.getElementById(\'coppaPost\').disabled = disableContacts; |
||
| 350 | document.getElementById(\'coppaFax\').disabled = disableContacts; |
||
| 351 | document.getElementById(\'coppaPhone\').disabled = disableContacts; |
||
| 352 | } |
||
| 353 | checkCoppa();'; |
||
| 354 | |||
| 355 | // Turn the postal address into something suitable for a textbox. |
||
| 356 | $modSettings['coppaPost'] = !empty($modSettings['coppaPost']) ? preg_replace('~<br ?/?' . '>~', "\n", $modSettings['coppaPost']) : ''; |
||
| 357 | |||
| 358 | prepareDBSettingContext($config_vars); |
||
| 359 | } |
||
| 360 | |||
| 361 | ?> |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.