ManageRegistration.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. <?php
  2. /**
  3. * Simple Machines Forum (SMF)
  4. *
  5. * @package SMF
  6. * @author Simple Machines http://www.simplemachines.org
  7. * @copyright 2011 Simple Machines
  8. * @license http://www.simplemachines.org/about/smf/license.php BSD
  9. *
  10. * @version 2.0
  11. */
  12. if (!defined('SMF'))
  13. die('Hacking attempt...');
  14. /* This file helps the administrator setting registration settings and policy
  15. as well as allow the administrator to register new members themselves.
  16. void RegCenter()
  17. - entrance point for the registration center.
  18. - accessed by ?action=admin;area=regcenter.
  19. - requires either the moderate_forum or the admin_forum permission.
  20. - loads the Login language file and the Register template.
  21. - calls the right function based on the subaction.
  22. void AdminRegister()
  23. - a function to register a new member from the admin center.
  24. - accessed by ?action=admin;area=regcenter;sa=register
  25. - requires the moderate_forum permission.
  26. - uses the admin_register sub template of the Register template.
  27. - allows assigning a primary group to the member being registered.
  28. void EditAgreement()
  29. - allows the administrator to edit the registration agreement, and
  30. choose whether it should be shown or not.
  31. - accessed by ?action=admin;area=regcenter;sa=agreement.
  32. - uses the Admin template and the edit_agreement sub template.
  33. - requires the admin_forum permission.
  34. - uses the edit_agreement administration area.
  35. - writes and saves the agreement to the agreement.txt file.
  36. void SetReserve()
  37. - set the names under which users are not allowed to register.
  38. - accessed by ?action=admin;area=regcenter;sa=reservednames.
  39. - requires the admin_forum permission.
  40. - uses the reserved_words sub template of the Register template.
  41. void ModifyRegistrationSettings()
  42. - set general registration settings and Coppa compliance settings.
  43. - accessed by ?action=admin;area=regcenter;sa=settings.
  44. - requires the admin_forum permission.
  45. */
  46. // Main handling function for the admin approval center
  47. function RegCenter()
  48. {
  49. global $modSettings, $context, $txt, $scripturl;
  50. // Old templates might still request this.
  51. if (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'browse')
  52. redirectexit('action=admin;area=viewmembers;sa=browse' . (isset($_REQUEST['type']) ? ';type=' . $_REQUEST['type'] : ''));
  53. $subActions = array(
  54. 'register' => array('AdminRegister', 'moderate_forum'),
  55. 'agreement' => array('EditAgreement', 'admin_forum'),
  56. 'reservednames' => array('SetReserve', 'admin_forum'),
  57. 'settings' => array('ModifyRegistrationSettings', 'admin_forum'),
  58. );
  59. // Work out which to call...
  60. $context['sub_action'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : (allowedTo('moderate_forum') ? 'register' : 'settings');
  61. // Must have sufficient permissions.
  62. isAllowedTo($subActions[$context['sub_action']][1]);
  63. // Loading, always loading.
  64. loadLanguage('Login');
  65. loadTemplate('Register');
  66. // Next create the tabs for the template.
  67. $context[$context['admin_menu_name']]['tab_data'] = array(
  68. 'title' => $txt['registration_center'],
  69. 'help' => 'registrations',
  70. 'description' => $txt['admin_settings_desc'],
  71. 'tabs' => array(
  72. 'register' => array(
  73. 'description' => $txt['admin_register_desc'],
  74. ),
  75. 'agreement' => array(
  76. 'description' => $txt['registration_agreement_desc'],
  77. ),
  78. 'reservednames' => array(
  79. 'description' => $txt['admin_reserved_desc'],
  80. ),
  81. 'settings' => array(
  82. 'description' => $txt['admin_settings_desc'],
  83. )
  84. )
  85. );
  86. // Finally, get around to calling the function...
  87. $subActions[$context['sub_action']][0]();
  88. }
  89. // This function allows the admin to register a new member by hand.
  90. function AdminRegister()
  91. {
  92. global $txt, $context, $sourcedir, $scripturl, $smcFunc;
  93. if (!empty($_POST['regSubmit']))
  94. {
  95. checkSession();
  96. foreach ($_POST as $key => $value)
  97. if (!is_array($_POST[$key]))
  98. $_POST[$key] = htmltrim__recursive(str_replace(array("\n", "\r"), '', $_POST[$key]));
  99. $regOptions = array(
  100. 'interface' => 'admin',
  101. 'username' => $_POST['user'],
  102. 'email' => $_POST['email'],
  103. 'password' => $_POST['password'],
  104. 'password_check' => $_POST['password'],
  105. 'check_reserved_name' => true,
  106. 'check_password_strength' => false,
  107. 'check_email_ban' => false,
  108. 'send_welcome_email' => isset($_POST['emailPassword']) || empty($_POST['password']),
  109. 'require' => isset($_POST['emailActivate']) ? 'activation' : 'nothing',
  110. 'memberGroup' => empty($_POST['group']) || !allowedTo('manage_membergroups') ? 0 : (int) $_POST['group'],
  111. );
  112. require_once($sourcedir . '/Subs-Members.php');
  113. $memberID = registerMember($regOptions);
  114. if (!empty($memberID))
  115. {
  116. $context['new_member'] = array(
  117. 'id' => $memberID,
  118. 'name' => $_POST['user'],
  119. 'href' => $scripturl . '?action=profile;u=' . $memberID,
  120. 'link' => '<a href="' . $scripturl . '?action=profile;u=' . $memberID . '">' . $_POST['user'] . '</a>',
  121. );
  122. $context['registration_done'] = sprintf($txt['admin_register_done'], $context['new_member']['link']);
  123. }
  124. }
  125. // Basic stuff.
  126. $context['sub_template'] = 'admin_register';
  127. $context['page_title'] = $txt['registration_center'];
  128. // Load the assignable member groups.
  129. if (allowedTo('manage_membergroups'))
  130. {
  131. $request = $smcFunc['db_query']('', '
  132. SELECT group_name, id_group
  133. FROM {db_prefix}membergroups
  134. WHERE id_group != {int:moderator_group}
  135. AND min_posts = {int:min_posts}' . (allowedTo('admin_forum') ? '' : '
  136. AND id_group != {int:admin_group}
  137. AND group_type != {int:is_protected}') . '
  138. AND hidden != {int:hidden_group}
  139. ORDER BY min_posts, CASE WHEN id_group < {int:newbie_group} THEN id_group ELSE 4 END, group_name',
  140. array(
  141. 'moderator_group' => 3,
  142. 'min_posts' => -1,
  143. 'admin_group' => 1,
  144. 'is_protected' => 1,
  145. 'hidden_group' => 2,
  146. 'newbie_group' => 4,
  147. )
  148. );
  149. $context['member_groups'] = array(0 => $txt['admin_register_group_none']);
  150. while ($row = $smcFunc['db_fetch_assoc']($request))
  151. $context['member_groups'][$row['id_group']] = $row['group_name'];
  152. $smcFunc['db_free_result']($request);
  153. }
  154. else
  155. $context['member_groups'] = array();
  156. }
  157. // I hereby agree not to be a lazy bum.
  158. function EditAgreement()
  159. {
  160. global $txt, $boarddir, $context, $modSettings, $smcFunc, $settings;
  161. // By default we look at agreement.txt.
  162. $context['current_agreement'] = '';
  163. // Is there more than one to edit?
  164. $context['editable_agreements'] = array(
  165. '' => $txt['admin_agreement_default'],
  166. );
  167. // Get our languages.
  168. getLanguages();
  169. // Try to figure out if we have more agreements.
  170. foreach ($context['languages'] as $lang)
  171. {
  172. if (file_exists($boarddir . '/agreement.' . $lang['filename'] . '.txt'))
  173. {
  174. $context['editable_agreements']['.' . $lang['filename']] = $lang['name'];
  175. // Are we editing this?
  176. if (isset($_POST['agree_lang']) && $_POST['agree_lang'] == '.' . $lang['filename'])
  177. $context['current_agreement'] = '.' . $lang['filename'];
  178. }
  179. }
  180. if (isset($_POST['agreement']))
  181. {
  182. checkSession();
  183. // Off it goes to the agreement file.
  184. $fp = fopen($boarddir . '/agreement' . $context['current_agreement'] . '.txt', 'w');
  185. fwrite($fp, str_replace("\r", '', $_POST['agreement']));
  186. fclose($fp);
  187. updateSettings(array('requireAgreement' => !empty($_POST['requireAgreement'])));
  188. }
  189. $context['agreement'] = file_exists($boarddir . '/agreement' . $context['current_agreement'] . '.txt') ? htmlspecialchars(file_get_contents($boarddir . '/agreement' . $context['current_agreement'] . '.txt')) : '';
  190. $context['warning'] = is_writable($boarddir . '/agreement' . $context['current_agreement'] . '.txt') ? '' : $txt['agreement_not_writable'];
  191. $context['require_agreement'] = !empty($modSettings['requireAgreement']);
  192. $context['sub_template'] = 'edit_agreement';
  193. $context['page_title'] = $txt['registration_agreement'];
  194. }
  195. // Set reserved names/words....
  196. function SetReserve()
  197. {
  198. global $txt, $context, $modSettings;
  199. // Submitting new reserved words.
  200. if (!empty($_POST['save_reserved_names']))
  201. {
  202. checkSession();
  203. // Set all the options....
  204. updateSettings(array(
  205. 'reserveWord' => (isset($_POST['matchword']) ? '1' : '0'),
  206. 'reserveCase' => (isset($_POST['matchcase']) ? '1' : '0'),
  207. 'reserveUser' => (isset($_POST['matchuser']) ? '1' : '0'),
  208. 'reserveName' => (isset($_POST['matchname']) ? '1' : '0'),
  209. 'reserveNames' => str_replace("\r", '', $_POST['reserved'])
  210. ));
  211. }
  212. // Get the reserved word options and words.
  213. $modSettings['reserveNames'] = str_replace('\n', "\n", $modSettings['reserveNames']);
  214. $context['reserved_words'] = explode("\n", $modSettings['reserveNames']);
  215. $context['reserved_word_options'] = array();
  216. $context['reserved_word_options']['match_word'] = $modSettings['reserveWord'] == '1';
  217. $context['reserved_word_options']['match_case'] = $modSettings['reserveCase'] == '1';
  218. $context['reserved_word_options']['match_user'] = $modSettings['reserveUser'] == '1';
  219. $context['reserved_word_options']['match_name'] = $modSettings['reserveName'] == '1';
  220. // Ready the template......
  221. $context['sub_template'] = 'edit_reserved_words';
  222. $context['page_title'] = $txt['admin_reserved_set'];
  223. }
  224. // This function handles registration settings, and provides a few pretty stats too while it's at it.
  225. function ModifyRegistrationSettings($return_config = false)
  226. {
  227. global $txt, $context, $scripturl, $modSettings, $sourcedir;
  228. // This is really quite wanting.
  229. require_once($sourcedir . '/ManageServer.php');
  230. $config_vars = array(
  231. array('select', 'registration_method', array($txt['setting_registration_standard'], $txt['setting_registration_activate'], $txt['setting_registration_approval'], $txt['setting_registration_disabled'])),
  232. array('check', 'enableOpenID'),
  233. array('check', 'notify_new_registration'),
  234. array('check', 'send_welcomeEmail'),
  235. '',
  236. array('int', 'coppaAge', 'subtext' => $txt['setting_coppaAge_desc'], 'onchange' => 'checkCoppa();'),
  237. array('select', 'coppaType', array($txt['setting_coppaType_reject'], $txt['setting_coppaType_approval']), 'onchange' => 'checkCoppa();'),
  238. array('large_text', 'coppaPost', 'subtext' => $txt['setting_coppaPost_desc']),
  239. array('text', 'coppaFax'),
  240. array('text', 'coppaPhone'),
  241. );
  242. if ($return_config)
  243. return $config_vars;
  244. // Setup the template
  245. $context['sub_template'] = 'show_settings';
  246. $context['page_title'] = $txt['registration_center'];
  247. if (isset($_GET['save']))
  248. {
  249. checkSession();
  250. // Are there some contacts missing?
  251. if (!empty($_POST['coppaAge']) && !empty($_POST['coppaType']) && empty($_POST['coppaPost']) && empty($_POST['coppaFax']))
  252. fatal_lang_error('admin_setting_coppa_require_contact');
  253. // Post needs to take into account line breaks.
  254. $_POST['coppaPost'] = str_replace("\n", '<br />', empty($_POST['coppaPost']) ? '' : $_POST['coppaPost']);
  255. saveDBSettings($config_vars);
  256. redirectexit('action=admin;area=regcenter;sa=settings');
  257. }
  258. $context['post_url'] = $scripturl . '?action=admin;area=regcenter;save;sa=settings';
  259. $context['settings_title'] = $txt['settings'];
  260. // Define some javascript for COPPA.
  261. $context['settings_post_javascript'] = '
  262. function checkCoppa()
  263. {
  264. var coppaDisabled = document.getElementById(\'coppaAge\').value == 0;
  265. document.getElementById(\'coppaType\').disabled = coppaDisabled;
  266. var disableContacts = coppaDisabled || document.getElementById(\'coppaType\').options[document.getElementById(\'coppaType\').selectedIndex].value != 1;
  267. document.getElementById(\'coppaPost\').disabled = disableContacts;
  268. document.getElementById(\'coppaFax\').disabled = disableContacts;
  269. document.getElementById(\'coppaPhone\').disabled = disableContacts;
  270. }
  271. checkCoppa();';
  272. // Turn the postal address into something suitable for a textbox.
  273. $modSettings['coppaPost'] = !empty($modSettings['coppaPost']) ? preg_replace('~<br ?/?' . '>~', "\n", $modSettings['coppaPost']) : '';
  274. prepareDBSettingContext($config_vars);
  275. }
  276. ?>