function AdminApprove() { global $txt, $context, $scripturl, $modSettings, $sourcedir, $language, $user_info, $smcFunc; // First, check our session. checkSession(); require_once $sourcedir . '/Subs-Post.php'; // We also need to the login languages here - for emails. loadLanguage('Login'); // Sort out where we are going... $browse_type = isset($_REQUEST['type']) ? $_REQUEST['type'] : (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 1 ? 'activate' : 'approve'); $current_filter = (int) $_REQUEST['orig_filter']; // If we are applying a filter do just that - then redirect. if (isset($_REQUEST['filter']) && $_REQUEST['filter'] != $_REQUEST['orig_filter']) { redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $_REQUEST['filter'] . ';start=' . $_REQUEST['start']); } // Nothing to do? if (!isset($_POST['todoAction']) && !isset($_POST['time_passed'])) { redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); } // Are we dealing with members who have been waiting for > set amount of time? if (isset($_POST['time_passed'])) { $timeBefore = time() - 86400 * (int) $_POST['time_passed']; $condition = ' AND date_registered < {int:time_before}'; } else { $members = array(); foreach ($_POST['todoAction'] as $id) { $members[] = (int) $id; } $condition = ' AND id_member IN ({array_int:members})'; } // Get information on each of the members, things that are important to us, like email address... $request = $smcFunc['db_query']('', ' SELECT id_member, member_name, real_name, email_address, validation_code, lngfile FROM {db_prefix}members WHERE is_activated = {int:activated_status}' . $condition . ' ORDER BY lngfile', array('activated_status' => $current_filter, 'time_before' => empty($timeBefore) ? 0 : $timeBefore, 'members' => empty($members) ? array() : $members)); $member_count = $smcFunc['db_num_rows']($request); // If no results then just return! if ($member_count == 0) { redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); } $member_info = array(); $members = array(); // Fill the info array. while ($row = $smcFunc['db_fetch_assoc']($request)) { $members[] = $row['id_member']; $member_info[] = array('id' => $row['id_member'], 'username' => $row['member_name'], 'name' => $row['real_name'], 'email' => $row['email_address'], 'language' => empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile'], 'code' => $row['validation_code']); } $smcFunc['db_free_result']($request); // Are we activating or approving the members? if ($_POST['todo'] == 'ok' || $_POST['todo'] == 'okemail') { // Approve/activate this member. $smcFunc['db_query']('', ' UPDATE {db_prefix}members SET validation_code = {string:blank_string}, is_activated = {int:is_activated} WHERE is_activated = {int:activated_status}' . $condition, array('is_activated' => 1, 'time_before' => empty($timeBefore) ? 0 : $timeBefore, 'members' => empty($members) ? array() : $members, 'activated_status' => $current_filter, 'blank_string' => '')); // Do we have to let the integration code know about the activations? if (!empty($modSettings['integrate_activate'])) { foreach ($member_info as $member) { call_integration_hook('integrate_activate', array($member['username'])); } } // Check for email. if ($_POST['todo'] == 'okemail') { foreach ($member_info as $member) { $replacements = array('NAME' => $member['name'], 'USERNAME' => $member['username'], 'PROFILELINK' => $scripturl . '?action=profile;u=' . $member['id'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder'); $emaildata = loadEmailTemplate('admin_approve_accept', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } } } elseif ($_POST['todo'] == 'require_activation') { require_once $sourcedir . '/Subs-Members.php'; // We have to do this for each member I'm afraid. foreach ($member_info as $member) { // Generate a random activation code. $validation_code = generateValidationCode(); // Set these members for activation - I know this includes two id_member checks but it's safer than bodging $condition ;). $smcFunc['db_query']('', ' UPDATE {db_prefix}members SET validation_code = {string:validation_code}, is_activated = {int:not_activated} WHERE is_activated = {int:activated_status} ' . $condition . ' AND id_member = {int:selected_member}', array('not_activated' => 0, 'activated_status' => $current_filter, 'selected_member' => $member['id'], 'validation_code' => $validation_code, 'time_before' => empty($timeBefore) ? 0 : $timeBefore, 'members' => empty($members) ? array() : $members)); $replacements = array('USERNAME' => $member['name'], 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $member['id'] . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $member['id'], 'ACTIVATIONCODE' => $validation_code); $emaildata = loadEmailTemplate('admin_approve_activation', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } } elseif ($_POST['todo'] == 'reject' || $_POST['todo'] == 'rejectemail') { require_once $sourcedir . '/Subs-Members.php'; deleteMembers($members); // Send email telling them they aren't welcome? if ($_POST['todo'] == 'rejectemail') { foreach ($member_info as $member) { $replacements = array('USERNAME' => $member['name']); $emaildata = loadEmailTemplate('admin_approve_reject', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 1); } } } elseif ($_POST['todo'] == 'delete' || $_POST['todo'] == 'deleteemail') { require_once $sourcedir . '/Subs-Members.php'; deleteMembers($members); // Send email telling them they aren't welcome? if ($_POST['todo'] == 'deleteemail') { foreach ($member_info as $member) { $replacements = array('USERNAME' => $member['name']); $emaildata = loadEmailTemplate('admin_approve_delete', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 1); } } } elseif ($_POST['todo'] == 'remind') { foreach ($member_info as $member) { $replacements = array('USERNAME' => $member['name'], 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $member['id'] . ';code=' . $member['code'], 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $member['id'], 'ACTIVATIONCODE' => $member['code']); $emaildata = loadEmailTemplate('admin_approve_remind', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 1); } } // Back to the user's language! if (isset($current_language) && $current_language != $user_info['language']) { loadLanguage('index'); loadLanguage('ManageMembers'); } // Log what we did? if (!empty($modSettings['modlog_enabled']) && in_array($_POST['todo'], array('ok', 'okemail', 'require_activation', 'remind'))) { $log_action = $_POST['todo'] == 'remind' ? 'remind_member' : 'approve_member'; $log_inserts = array(); foreach ($member_info as $member) { $log_inserts[] = array(time(), 3, $user_info['id'], $user_info['ip'], $log_action, 0, 0, 0, serialize(array('member' => $member['id']))); } $smcFunc['db_insert']('', '{db_prefix}log_actions', array('log_time' => 'int', 'id_log' => 'int', 'id_member' => 'int', 'ip' => 'string-16', 'action' => 'string', 'id_board' => 'int', 'id_topic' => 'int', 'id_msg' => 'int', 'extra' => 'string-65534'), $log_inserts, array('id_action')); } // Although updateStats *may* catch this, best to do it manually just in case (Doesn't always sort out unapprovedMembers). if (in_array($current_filter, array(3, 4))) { updateSettings(array('unapprovedMembers' => $modSettings['unapprovedMembers'] > $member_count ? $modSettings['unapprovedMembers'] - $member_count : 0)); } // Update the member's stats. (but, we know the member didn't change their name.) updateStats('member', false); // If they haven't been deleted, update the post group statistics on them... if (!in_array($_POST['todo'], array('delete', 'deleteemail', 'reject', 'rejectemail', 'remind'))) { updateStats('postgroups', $members); } redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); }
function AdminApprove() { global $txt, $context, $db_prefix, $scripturl, $modSettings, $sourcedir, $language, $user_info; require_once $sourcedir . '/Subs-Post.php'; // We also need to the login languages here - for emails. loadLanguage('Login'); // Sort out where we are going... $browse_type = isset($_REQUEST['type']) ? $_REQUEST['type'] : (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 1 ? 'activate' : 'approve'); $current_filter = (int) $_REQUEST['orig_filter']; // If we are applying a filter do just that - then redirect. if (isset($_REQUEST['filter']) && $_REQUEST['filter'] != $_REQUEST['orig_filter']) { redirectexit('action=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $_REQUEST['filter'] . ';start=' . $_REQUEST['start']); } // Nothing to do? if (!isset($_POST['todoAction']) && !isset($_POST['time_passed'])) { redirectexit('action=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); } // Are we dealing with members who have been waiting for > set amount of time? if (isset($_POST['time_passed'])) { $timeBefore = time() - 86400 * (int) $_POST['time_passed']; $condition = "\n\t\t\tAND dateRegistered < {$timeBefore}"; } else { $members = array(); foreach ($_POST['todoAction'] as $id) { $members[] = (int) $id; } $condition = "\n\t\t\tAND ID_MEMBER IN (" . implode(', ', $members) . ")"; } // Get information on each of the members, things that are important to us, like email address... $request = db_query("\n\t\tSELECT ID_MEMBER, memberName, realName, emailAddress, validation_code, lngfile\n\t\tFROM {$db_prefix}members\n\t\tWHERE is_activated = {$current_filter}{$condition}\n\t\tORDER BY lngfile", __FILE__, __LINE__); $member_count = mysql_num_rows($request); // If no results then just return! if ($member_count == 0) { redirectexit('action=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); } $member_info = array(); $members = array(); // Fill the info array. while ($row = mysql_fetch_assoc($request)) { $members[] = $row['ID_MEMBER']; $member_info[] = array('id' => $row['ID_MEMBER'], 'username' => $row['memberName'], 'name' => $row['realName'], 'email' => $row['emailAddress'], 'language' => empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile'], 'code' => $row['validation_code']); } mysql_free_result($request); // Are we activating or approving the members? if ($_POST['todo'] == 'ok' || $_POST['todo'] == 'okemail') { // Approve/activate this member. db_query("\n\t\t\tUPDATE {$db_prefix}members\n\t\t\tSET validation_code = '', is_activated = 1\n\t\t\tWHERE is_activated = {$current_filter}{$condition}\n\t\t\tLIMIT {$member_count}", __FILE__, __LINE__); // Do we have to let the integration code know about the activations? if (isset($modSettings['integrate_activate']) && function_exists($modSettings['integrate_activate'])) { foreach ($member_info as $member) { call_user_func($modSettings['integrate_activate'], $member['username']); } } // Check for email. if ($_POST['todo'] == 'okemail') { foreach ($member_info as $member) { if (empty($current_language) || $current_language != $member['language']) { $current_language = loadLanguage('index', $member['language'], false); loadLanguage('ManageMembers', $member['language'], false); } sendmail($member['email'], $txt['register_subject'], "{$txt['hello_guest']} {$member['name']}!\n\n" . "{$txt['admin_approve_accept_desc']} {$txt['719']} {$member['username']}\n\n" . "{$txt['701']}\n" . "{$scripturl}?action=profile\n\n" . $txt[130]); } } } elseif ($_POST['todo'] == 'require_activation') { require_once $sourcedir . '/Subs-Members.php'; // We have to do this for each member I'm afraid. foreach ($member_info as $member) { // Generate a random activation code. $validation_code = generateValidationCode(); // Set these members for activation - I know this includes two ID_MEMBER checks but it's safer than bodging $condition ;). db_query("\n\t\t\t\tUPDATE {$db_prefix}members\n\t\t\t\tSET validation_code = '{$validation_code}', is_activated = 0\n\t\t\t\tWHERE is_activated = {$current_filter}\n\t\t\t\t\t{$condition}\n\t\t\t\t\tAND ID_MEMBER = {$member['id']}\n\t\t\t\tLIMIT 1", __FILE__, __LINE__); if (empty($current_language) || $current_language != $member['language']) { $current_language = loadLanguage('index', $member['language'], false); loadLanguage('ManageMembers', $member['language'], false); } // Send out the activation email. sendmail($member['email'], $txt['register_subject'], "{$txt['hello_guest']} {$member['name']}!\n\n" . "{$txt['admin_approve_require_activation']} {$txt['admin_approve_remind_desc2']}\n" . "{$scripturl}?action=activate;u={$member['id']};code={$validation_code}\n\n" . $txt[130]); } } elseif ($_POST['todo'] == 'reject' || $_POST['todo'] == 'rejectemail') { require_once $sourcedir . '/Subs-Members.php'; deleteMembers($members); // Send email telling them they aren't welcome? if ($_POST['todo'] == 'rejectemail') { foreach ($member_info as $member) { if (empty($current_language) || $current_language != $member['language']) { $current_language = loadLanguage('ManageMembers', $member['language'], false); } sendmail($member['email'], $txt['admin_approve_reject'], "{$member['name']},\n\n" . "{$txt['admin_approve_reject_desc']}\n\n" . $txt[130]); } } } elseif ($_POST['todo'] == 'delete' || $_POST['todo'] == 'deleteemail') { require_once $sourcedir . '/Subs-Members.php'; deleteMembers($members); // Send email telling them they aren't welcome? if ($_POST['todo'] == 'deleteemail') { foreach ($member_info as $member) { if (empty($current_language) || $current_language != $member['language']) { $current_language = loadLanguage('ManageMembers', $member['language'], false); } sendmail($member['email'], $txt['admin_approve_delete'], "{$member['name']},\n\n" . "{$txt['admin_approve_delete_desc']}\n\n" . $txt[130]); } } } elseif ($_POST['todo'] == 'remind') { foreach ($member_info as $member) { if (empty($current_language) || $current_language != $member['language']) { $current_language = loadLanguage('ManageMembers', $member['language'], false); } sendmail($member['email'], $txt['admin_approve_remind'], "{$member['name']},\n\n" . "{$txt['admin_approve_remind_desc']} {$context['forum_name']}.\n\n{$txt['admin_approve_remind_desc2']}\n\n" . "{$scripturl}?action=activate;u={$member['id']};code={$member['code']}\n\n" . $txt[130]); } } // Back to the user's language! if (isset($current_language) && $current_language != $user_info['language']) { loadLanguage('index'); loadLanguage('ManageMembers'); } // Although updateStats *may* catch this, best to do it manually just incase (Doesn't always sort out unapprovedMembers). if (in_array($current_filter, array(3, 4))) { updateSettings(array('unapprovedMembers' => $modSettings['unapprovedMembers'] > $member_count ? $modSettings['unapprovedMembers'] - $member_count : 0)); } // Update the member's stats. (but, we know the member didn't change their name.) updateStats('member', false); // If they haven't been deleted, update the post group statistics on them... if (!in_array($_POST['todo'], array('delete', 'deleteemail', 'reject', 'rejectemail', 'remind'))) { updateStats('postgroups', 'ID_MEMBER IN (' . implode(', ', $members) . ')'); } redirectexit('action=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); }
function registerMember(&$regOptions, $return_errors = false) { global $scripturl, $txt, $modSettings, $context, $sourcedir; global $user_info, $options, $settings, $smcFunc; loadLanguage('Login'); // We'll need some external functions. require_once $sourcedir . '/lib/Subs-Auth.php'; require_once $sourcedir . '/lib/Subs-Post.php'; // Put any errors in here. $reg_errors = array(); // Registration from the admin center, let them sweat a little more. if ($regOptions['interface'] == 'admin') { is_not_guest(); isAllowedTo('moderate_forum'); } elseif ($regOptions['interface'] == 'guest') { // You cannot register twice... if (empty($user_info['is_guest'])) { redirectexit(); } // Make sure they didn't just register with this session. if (!empty($_SESSION['just_registered']) && empty($modSettings['disableRegisterCheck'])) { fatal_lang_error('register_only_once', false); } } // What method of authorization are we going to use? if (empty($regOptions['auth_method']) || !in_array($regOptions['auth_method'], array('password', 'openid'))) { if (!empty($regOptions['openid'])) { $regOptions['auth_method'] = 'openid'; } else { $regOptions['auth_method'] = 'password'; } } // No name?! How can you register with no name? if (empty($regOptions['username'])) { $reg_errors[] = array('lang', 'need_username'); } // Spaces and other odd characters are evil... $regOptions['username'] = preg_replace('~[\\t\\n\\r\\x0B\\0' . ($context['server']['complex_preg_chars'] ? '\\x{A0}' : "Â ") . ']+~u', ' ', $regOptions['username']); // Don't use too long a name. if (commonAPI::strlen($regOptions['username']) > 25) { $reg_errors[] = array('lang', 'error_long_name'); } // Only these characters are permitted. if (preg_match('~[<>&"\'=\\\\]~', preg_replace('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', '', $regOptions['username'])) != 0 || $regOptions['username'] == '_' || $regOptions['username'] == '|' || strpos($regOptions['username'], '[code') !== false || strpos($regOptions['username'], '[/code') !== false) { $reg_errors[] = array('lang', 'error_invalid_characters_username'); } if (commonAPI::strtolower($regOptions['username']) === commonAPI::strtolower($txt['guest_title'])) { $reg_errors[] = array('lang', 'username_reserved', 'general', array($txt['guest_title'])); } // !!! Separate the sprintf? if (empty($regOptions['email']) || preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $regOptions['email']) === 0 || strlen($regOptions['email']) > 255) { $reg_errors[] = array('done', sprintf($txt['valid_email_needed'], commonAPI::htmlspecialchars($regOptions['username']))); } if (!empty($regOptions['check_reserved_name']) && isReservedName($regOptions['username'], 0, false)) { if ($regOptions['password'] == 'chocolate cake') { $reg_errors[] = array('done', 'Sorry, I don\'t take bribes... you\'ll need to come up with a different name.'); } $reg_errors[] = array('done', '(' . htmlspecialchars($regOptions['username']) . ') ' . $txt['name_in_use']); } // Generate a validation code if it's supposed to be emailed. $validation_code = ''; if ($regOptions['require'] == 'activation') { $validation_code = generateValidationCode(); } // If you haven't put in a password generate one. if ($regOptions['interface'] == 'admin' && $regOptions['password'] == '' && $regOptions['auth_method'] == 'password') { mt_srand(time() + 1277); $regOptions['password'] = generateValidationCode(); $regOptions['password_check'] = $regOptions['password']; } elseif ($regOptions['password'] != $regOptions['password_check'] && $regOptions['auth_method'] == 'password') { $reg_errors[] = array('lang', 'passwords_dont_match'); } // That's kind of easy to guess... if ($regOptions['password'] == '') { if ($regOptions['auth_method'] == 'password') { $reg_errors[] = array('lang', 'no_password'); } else { $regOptions['password'] = sha1(mt_rand()); } } // Now perform hard password validation as required. if (!empty($regOptions['check_password_strength'])) { $passwordError = validatePassword($regOptions['password'], $regOptions['username'], array($regOptions['email'])); // Password isn't legal? if ($passwordError != null) { $reg_errors[] = array('lang', 'profile_error_password_' . $passwordError); } } // If they are using an OpenID that hasn't been verified yet error out. // !!! Change this so they can register without having to attempt a login first if ($regOptions['auth_method'] == 'openid' && (empty($_SESSION['openid']['verified']) || $_SESSION['openid']['openid_uri'] != $regOptions['openid'])) { $reg_errors[] = array('lang', 'openid_not_verified'); } // You may not be allowed to register this email. if (!empty($regOptions['check_email_ban'])) { isBannedEmail($regOptions['email'], 'cannot_register', $txt['ban_register_prohibited']); } // Check if the email address is in use. $request = smf_db_query(' SELECT id_member FROM {db_prefix}members WHERE email_address = {string:email_address} OR email_address = {string:username} LIMIT 1', array('email_address' => $regOptions['email'], 'username' => $regOptions['username'])); // !!! Separate the sprintf? if (mysql_num_rows($request) != 0) { $reg_errors[] = array('lang', 'email_in_use', false, array(htmlspecialchars($regOptions['email']))); } mysql_free_result($request); // If we found any errors we need to do something about it right away! foreach ($reg_errors as $key => $error) { /* Note for each error: 0 = 'lang' if it's an index, 'done' if it's clear text. 1 = The text/index. 2 = Whether to log. 3 = sprintf data if necessary. */ if ($error[0] == 'lang') { loadLanguage('Errors'); } $message = $error[0] == 'lang' ? empty($error[3]) ? $txt[$error[1]] : vsprintf($txt[$error[1]], $error[3]) : $error[1]; // What to do, what to do, what to do. if ($return_errors) { if (!empty($error[2])) { log_error($message, $error[2]); } $reg_errors[$key] = $message; } else { fatal_error($message, empty($error[2]) ? false : $error[2]); } } // If there's any errors left return them at once! if (!empty($reg_errors)) { return $reg_errors; } $reservedVars = array('actual_theme_url', 'actual_images_url', 'base_theme_dir', 'base_theme_url', 'default_images_url', 'default_theme_dir', 'default_theme_url', 'default_template', 'images_url', 'number_recent_posts', 'smiley_sets_default', 'theme_dir', 'theme_id', 'theme_layers', 'theme_templates', 'theme_url'); // Can't change reserved vars. if (isset($regOptions['theme_vars']) && array_intersect($regOptions['theme_vars'], $reservedVars) != array()) { fatal_lang_error('no_theme'); } // Some of these might be overwritten. (the lower ones that are in the arrays below.) $regOptions['register_vars'] = array('member_name' => $regOptions['username'], 'email_address' => $regOptions['email'], 'passwd' => sha1(strtolower($regOptions['username']) . $regOptions['password']), 'password_salt' => substr(md5(mt_rand()), 0, 4), 'posts' => 0, 'date_registered' => time(), 'member_ip' => $regOptions['interface'] == 'admin' ? '127.0.0.1' : $user_info['ip'], 'member_ip2' => $regOptions['interface'] == 'admin' ? '127.0.0.1' : $_SERVER['BAN_CHECK_IP'], 'validation_code' => $validation_code, 'real_name' => $regOptions['username'], 'personal_text' => $modSettings['default_personal_text'], 'pm_email_notify' => 1, 'id_theme' => 0, 'id_post_group' => 4, 'lngfile' => '', 'buddy_list' => '', 'pm_ignore_list' => '', 'message_labels' => '', 'location' => '', 'time_format' => '', 'signature' => '', 'avatar' => '', 'usertitle' => '', 'secret_question' => '', 'secret_answer' => '', 'additional_groups' => '', 'ignore_boards' => '', 'smiley_set' => '', 'openid_uri' => !empty($regOptions['openid']) ? $regOptions['openid'] : ''); // Setup the activation status on this new account so it is correct - firstly is it an under age account? if ($regOptions['require'] == 'coppa') { $regOptions['register_vars']['is_activated'] = 5; // !!! This should be changed. To what should be it be changed?? $regOptions['register_vars']['validation_code'] = ''; } elseif ($regOptions['require'] == 'nothing') { $regOptions['register_vars']['is_activated'] = 1; } elseif ($regOptions['require'] == 'activation') { $regOptions['register_vars']['is_activated'] = 0; } else { $regOptions['register_vars']['is_activated'] = 3; } if (isset($regOptions['memberGroup'])) { // Make sure the id_group will be valid, if this is an administator. $regOptions['register_vars']['id_group'] = $regOptions['memberGroup'] == 1 && !allowedTo('admin_forum') ? 0 : $regOptions['memberGroup']; // Check if this group is assignable. $unassignableGroups = array(-1, 3); $request = smf_db_query(' SELECT id_group FROM {db_prefix}membergroups WHERE min_posts != {int:min_posts}' . (allowedTo('admin_forum') ? '' : ' OR group_type = {int:is_protected}'), array('min_posts' => -1, 'is_protected' => 1)); while ($row = mysql_fetch_assoc($request)) { $unassignableGroups[] = $row['id_group']; } mysql_free_result($request); if (in_array($regOptions['register_vars']['id_group'], $unassignableGroups)) { $regOptions['register_vars']['id_group'] = 0; } } // Integrate optional member settings to be set. if (!empty($regOptions['extra_register_vars'])) { foreach ($regOptions['extra_register_vars'] as $var => $value) { $regOptions['register_vars'][$var] = $value; } } // Integrate optional user theme options to be set. $theme_vars = array(); if (!empty($regOptions['theme_vars'])) { foreach ($regOptions['theme_vars'] as $var => $value) { $theme_vars[$var] = $value; } } // Call an optional function to validate the users' input. HookAPI::callHook('integrate_register', array(&$regOptions, &$theme_vars)); // Right, now let's prepare for insertion. $knownInts = array('date_registered', 'posts', 'id_group', 'last_login', 'instant_messages', 'unread_messages', 'new_pm', 'pm_prefs', 'gender', 'hide_email', 'show_online', 'pm_email_notify', 'karma_good', 'karma_bad', 'notify_announcements', 'notify_send_body', 'notify_regularity', 'notify_types', 'id_theme', 'is_activated', 'id_msg_last_visit', 'id_post_group', 'total_time_logged_in', 'warning'); $knownFloats = array('time_offset'); $column_names = array(); $values = array(); foreach ($regOptions['register_vars'] as $var => $val) { $type = 'string'; if (in_array($var, $knownInts)) { $type = 'int'; } elseif (in_array($var, $knownFloats)) { $type = 'float'; } elseif ($var == 'birthdate') { $type = 'date'; } $column_names[$var] = $type; $values[$var] = $val; } // Register them into the database. smf_db_insert('', '{db_prefix}members', $column_names, $values, array('id_member')); $memberID = smf_db_insert_id('{db_prefix}members', 'id_member'); // Update the number of members and latest member's info - and pass the name, but remove the 's. if ($regOptions['register_vars']['is_activated'] == 1) { updateStats('member', $memberID, $regOptions['register_vars']['real_name']); } else { updateStats('member'); } // Theme variables too? if (!empty($theme_vars)) { $inserts = array(); foreach ($theme_vars as $var => $val) { $inserts[] = array($memberID, $var, $val); } smf_db_insert('insert', '{db_prefix}themes', array('id_member' => 'int', 'variable' => 'string-255', 'value' => 'string-65534'), $inserts, array('id_member', 'variable')); } // If it's enabled, increase the registrations for today. trackStats(array('registers' => '+')); // Administrative registrations are a bit different... if ($regOptions['interface'] == 'admin') { if ($regOptions['require'] == 'activation') { $email_message = 'admin_register_activate'; } elseif (!empty($regOptions['send_welcome_email'])) { $email_message = 'admin_register_immediate'; } if (isset($email_message)) { $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $memberID, 'ACTIVATIONCODE' => $validation_code); $emaildata = loadEmailTemplate($email_message, $replacements); sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } // All admins are finished here. return $memberID; } // Can post straight away - welcome them to your fantastic community... if ($regOptions['require'] == 'nothing') { if (!empty($regOptions['send_welcome_email'])) { $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : ''); $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . 'immediate', $replacements); sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } // Send admin their notification. adminNotify('standard', $memberID, $regOptions['username']); } elseif ($regOptions['require'] == 'activation' || $regOptions['require'] == 'coppa') { $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : ''); if ($regOptions['require'] == 'activation') { $replacements += array('ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $memberID, 'ACTIVATIONCODE' => $validation_code); } else { $replacements += array('COPPALINK' => $scripturl . '?action=coppa;u=' . $memberID); } $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . ($regOptions['require'] == 'activation' ? 'activate' : 'coppa'), $replacements); sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } else { $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : ''); $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . 'pending', $replacements); sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); // Admin gets informed here... adminNotify('approval', $memberID, $regOptions['username']); } // Okay, they're for sure registered... make sure the session is aware of this for security. (Just married :P!) $_SESSION['just_registered'] = 1; return $memberID; }
function saveProfileChanges(&$profile_vars, &$post_errors, $memID) { global $db_prefix, $user_info, $txt, $modSettings, $user_profile; global $newpassemail, $validationCode, $context, $settings, $sourcedir; global $func; // These make life easier.... $old_profile =& $user_profile[$memID]; // Permissions... if ($context['user']['is_owner']) { $changeIdentity = allowedTo(array('profile_identity_any', 'profile_identity_own')); $changeOther = allowedTo(array('profile_extra_any', 'profile_extra_own')); } else { $changeIdentity = allowedTo('profile_identity_any'); $changeOther = allowedTo('profile_extra_any'); } // Arrays of all the changes - makes things easier. $profile_bools = array('notifyAnnouncements', 'notifyOnce', 'notifySendBody'); $profile_ints = array('pm_email_notify', 'notifyTypes', 'ICQ', 'gender', 'ID_THEME'); $profile_floats = array('timeOffset'); $profile_strings = array('websiteUrl', 'websiteTitle', 'AIM', 'YIM', 'location', 'birthdate', 'timeFormat', 'buddy_list', 'pm_ignore_list', 'smileySet', 'signature', 'personalText', 'avatar'); // Fix the spaces in messenger screennames... $fix_spaces = array('MSN', 'AIM', 'YIM'); foreach ($fix_spaces as $var) { // !!! Why? if (isset($_POST[$var])) { $_POST[$var] = strtr($_POST[$var], ' ', '+'); } } // Make sure the MSN one is an email address, not something like 'none' :P. if (isset($_POST['MSN']) && ($_POST['MSN'] == '' || preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', $_POST['MSN']) != 0)) { $profile_strings[] = 'MSN'; } // Validate the title... if (!empty($modSettings['titlesEnable']) && (allowedTo('profile_title_any') || allowedTo('profile_title_own') && $context['user']['is_owner'])) { $profile_strings[] = 'usertitle'; } // Validate the timeOffset... if (isset($_POST['timeOffset'])) { $_POST['timeOffset'] = strtr($_POST['timeOffset'], ',', '.'); if ($_POST['timeOffset'] < -23.5 || $_POST['timeOffset'] > 23.5) { $post_errors[] = 'bad_offset'; } } // Fix the URL... if (isset($_POST['websiteUrl'])) { if (strlen(trim($_POST['websiteUrl'])) > 0 && strpos($_POST['websiteUrl'], '://') === false) { $_POST['websiteUrl'] = 'http://' . $_POST['websiteUrl']; } if (strlen($_POST['websiteUrl']) < 8) { $_POST['websiteUrl'] = ''; } } // !!! Should we check for this year and tell them they made a mistake :P? (based on coppa at least?) if (isset($_POST['birthdate'])) { if (preg_match('/(\\d{4})[\\-\\., ](\\d{2})[\\-\\., ](\\d{2})/', $_POST['birthdate'], $dates) === 1) { $_POST['birthdate'] = checkdate($dates[2], $dates[3], $dates[1] < 4 ? 4 : $dates[1]) ? sprintf('%04d-%02d-%02d', $dates[1] < 4 ? 4 : $dates[1], $dates[2], $dates[3]) : '0001-01-01'; } else { unset($_POST['birthdate']); } } elseif (isset($_POST['bday1'], $_POST['bday2'], $_POST['bday3']) && $_POST['bday1'] > 0 && $_POST['bday2'] > 0) { $_POST['birthdate'] = checkdate($_POST['bday1'], $_POST['bday2'], $_POST['bday3'] < 4 ? 4 : $_POST['bday3']) ? sprintf('%04d-%02d-%02d', $_POST['bday3'] < 4 ? 4 : $_POST['bday3'], $_POST['bday1'], $_POST['bday2']) : '0001-01-01'; } elseif (isset($_POST['bday1']) || isset($_POST['bday2']) || isset($_POST['bday3'])) { $_POST['birthdate'] = '0001-01-01'; } if (isset($_POST['im_email_notify'])) { $_POST['pm_email_notify'] = $_POST['im_email_notify']; } // Validate and set the ignorelist... if (isset($_POST['pm_ignore_list']) || isset($_POST['im_ignore_list'])) { if (!isset($_POST['pm_ignore_list'])) { $_POST['pm_ignore_list'] = $_POST['im_ignore_list']; } $_POST['pm_ignore_list'] = strtr($func['htmltrim']($_POST['pm_ignore_list']), array('\\\'' => ''', "\n" => "', '", "\r" => '', '"' => '')); if (preg_match('~(\\A|,)\\*(\\Z|,)~s', $_POST['pm_ignore_list']) == 0) { $result = db_query("\n\t\t\t\tSELECT ID_MEMBER\n\t\t\t\tFROM {$db_prefix}members\n\t\t\t\tWHERE memberName IN ('{$_POST['pm_ignore_list']}') OR realName IN ('{$_POST['pm_ignore_list']}')\n\t\t\t\tLIMIT " . (substr_count($_POST['pm_ignore_list'], '\', \'') + 1), __FILE__, __LINE__); $_POST['pm_ignore_list'] = ''; while ($row = mysql_fetch_assoc($result)) { $_POST['pm_ignore_list'] .= $row['ID_MEMBER'] . ','; } mysql_free_result($result); // !!! Did we find all the members? $_POST['pm_ignore_list'] = substr($_POST['pm_ignore_list'], 0, -1); } else { $_POST['pm_ignore_list'] = '*'; } } // Similarly, do the same for the buddy list if (isset($_POST['buddy_list'])) { $_POST['buddy_list'] = strtr(trim($_POST['buddy_list']), array('\\\'' => ''', "\n" => "', '", "\r" => '', '"' => '')); if (trim($_POST['buddy_list']) != '') { $result = db_query("\n\t\t\t\tSELECT ID_MEMBER\n\t\t\t\tFROM {$db_prefix}members\n\t\t\t\tWHERE memberName IN ('{$_POST['buddy_list']}') OR realName IN ('{$_POST['buddy_list']}')\n\t\t\t\tLIMIT " . (substr_count($_POST['buddy_list'], '\', \'') + 1), __FILE__, __LINE__); $_POST['buddy_list'] = ''; while ($row = mysql_fetch_assoc($result)) { $_POST['buddy_list'] .= $row['ID_MEMBER'] . ','; } mysql_free_result($result); // !!! Did we find all the members? $_POST['buddy_list'] = substr($_POST['buddy_list'], 0, -1); } } // Validate the smiley set. if (isset($_POST['smileySet'])) { $smiley_sets = explode(',', $modSettings['smiley_sets_known']); if (!in_array($_POST['smileySet'], $smiley_sets) && $_POST['smileySet'] != 'none') { $_POST['smileySet'] = ''; } } // Make sure the signature isn't too long. if (isset($_POST['signature'])) { require_once $sourcedir . '/Subs-Post.php'; if (!empty($modSettings['max_signatureLength']) && $func['strlen']($_POST['signature']) > $modSettings['max_signatureLength']) { $_POST['signature'] = addslashes($func['substr'](stripslashes($_POST['signature']), 0, $modSettings['max_signatureLength'])); } if (strlen($_POST['signature']) > 65534) { $_POST['signature'] = addslashes($func['truncate'](stripslashes($_POST['signature']), 65534)); } $_POST['signature'] = strtr($_POST['signature'], array('"' => '\\"', ''' => '\\'', ''' => '\\'')); preparsecode($_POST['signature']); } // Identity-only changes... if ($changeIdentity) { // This block is only concerned with display name validation. if (isset($_POST['realName']) && (!empty($modSettings['allow_editDisplayName']) || allowedTo('moderate_forum')) && trim($_POST['realName']) != $old_profile['realName']) { $_POST['realName'] = trim(preg_replace('~[\\s]~' . ($context['utf8'] ? 'u' : ''), ' ', $_POST['realName'])); if (trim($_POST['realName']) == '') { $post_errors[] = 'no_name'; } elseif ($func['strlen']($_POST['realName']) > 60) { $post_errors[] = 'name_too_long'; } else { require_once $sourcedir . '/Subs-Members.php'; if (isReservedName($_POST['realName'], $memID)) { $post_errors[] = 'name_taken'; } } if (isset($_POST['realName'])) { $profile_vars['realName'] = '\'' . $_POST['realName'] . '\''; } } // Change the registration date. if (!empty($_POST['dateRegistered']) && allowedTo('admin_forum')) { // Bad date! Go try again - please? if (($_POST['dateRegistered'] = strtotime($_POST['dateRegistered'])) === -1) { fatal_error($txt['smf233'] . ' ' . strftime('%d %b %Y ' . (strpos($user_info['time_format'], '%H') !== false ? '%I:%M:%S %p' : '%H:%M:%S'), forum_time(false)), false); } elseif ($_POST['dateRegistered'] != $txt[470] && $_POST['dateRegistered'] != strtotime(strftime('%Y-%m-%d', $user_profile[$memID]['dateRegistered'] + ($user_info['time_offset'] + $modSettings['time_offset']) * 3600))) { $profile_vars['dateRegistered'] = $_POST['dateRegistered'] - ($user_info['time_offset'] + $modSettings['time_offset']) * 3600; } } // Change the number of posts. if (isset($_POST['posts']) && allowedTo('moderate_forum')) { $profile_vars['posts'] = $_POST['posts'] != '' ? (int) strtr($_POST['posts'], array(',' => '', '.' => '', ' ' => '')) : '\'\''; } // This block is only concerned with email address validation.. if (isset($_POST['emailAddress']) && strtolower($_POST['emailAddress']) != strtolower($old_profile['emailAddress'])) { $_POST['emailAddress'] = strtr($_POST['emailAddress'], array(''' => '\\\'')); // Prepare the new password, or check if they want to change their own. if (!empty($modSettings['send_validation_onChange']) && !allowedTo('moderate_forum')) { require_once $sourcedir . '/Subs-Members.php'; $validationCode = generateValidationCode(); $profile_vars['validation_code'] = '\'' . $validationCode . '\''; $profile_vars['is_activated'] = '2'; $newpassemail = true; } // Check the name and email for validity. if (trim($_POST['emailAddress']) == '') { $post_errors[] = 'no_email'; } if (preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', stripslashes($_POST['emailAddress'])) == 0) { $post_errors[] = 'bad_email'; } // Email addresses should be and stay unique. $request = db_query("\n\t\t\t\tSELECT ID_MEMBER\n\t\t\t\tFROM {$db_prefix}members\n\t\t\t\tWHERE ID_MEMBER != {$memID}\n\t\t\t\t\tAND emailAddress = '{$_POST['emailAddress']}'\n\t\t\t\tLIMIT 1", __FILE__, __LINE__); if (mysql_num_rows($request) > 0) { $post_errors[] = 'email_taken'; } mysql_free_result($request); $profile_vars['emailAddress'] = '\'' . $_POST['emailAddress'] . '\''; } // Hide email address? if (isset($_POST['hideEmail']) && (!empty($modSettings['allow_hideEmail']) || allowedTo('moderate_forum'))) { $profile_vars['hideEmail'] = empty($_POST['hideEmail']) ? '0' : '1'; } // Are they allowed to change their hide status? if (isset($_POST['showOnline']) && (!empty($modSettings['allow_hideOnline']) || allowedTo('moderate_forum'))) { $profile_vars['showOnline'] = empty($_POST['showOnline']) ? '0' : '1'; } // If they're trying to change the password, let's check they pick a sensible one. if (isset($_POST['passwrd1']) && $_POST['passwrd1'] != '') { // Do the two entries for the password even match? if ($_POST['passwrd1'] != $_POST['passwrd2']) { $post_errors[] = 'bad_new_password'; } // Let's get the validation function into play... require_once $sourcedir . '/Subs-Auth.php'; $passwordErrors = validatePassword($_POST['passwrd1'], $user_info['username'], array($user_info['name'], $user_info['email'])); // Were there errors? if ($passwordErrors != null) { $post_errors[] = 'password_' . $passwordErrors; } // Set up the new password variable... ready for storage. $profile_vars['passwd'] = '\'' . sha1(strtolower($old_profile['memberName']) . un_htmlspecialchars(stripslashes($_POST['passwrd1']))) . '\''; } if (isset($_POST['secretQuestion'])) { $profile_vars['secretQuestion'] = '\'' . $_POST['secretQuestion'] . '\''; } // Do you have a *secret* password? if (isset($_POST['secretAnswer']) && $_POST['secretAnswer'] != '') { $profile_vars['secretAnswer'] = '\'' . md5($_POST['secretAnswer']) . '\''; } } // Things they can do if they are a forum moderator. if (allowedTo('moderate_forum')) { if (($_REQUEST['sa'] == 'activateAccount' || !empty($_POST['is_activated'])) && isset($old_profile['is_activated']) && $old_profile['is_activated'] != 1) { // If we are approving the deletion of an account, we do something special ;) if ($old_profile['is_activated'] == 4) { require_once $sourcedir . '/Subs-Members.php'; deleteMembers($memID); redirectexit(); } if (isset($modSettings['integrate_activate']) && function_exists($modSettings['integrate_activate'])) { call_user_func($modSettings['integrate_activate'], $old_profile['memberName']); } // Actually update this member now, as it guarantees the unapproved count can't get corrupted. updateMemberData($memID, array('is_activated' => $old_profile['is_activated'] >= 10 ? '11' : '1', 'validation_code' => '\'\'')); // If we are doing approval, update the stats for the member just incase. if (in_array($old_profile['is_activated'], array(3, 4, 13, 14))) { updateSettings(array('unapprovedMembers' => $modSettings['unapprovedMembers'] > 1 ? $modSettings['unapprovedMembers'] - 1 : 0)); } // Make sure we update the stats too. updateStats('member', false); } if (isset($_POST['karmaGood'])) { $profile_vars['karmaGood'] = $_POST['karmaGood'] != '' ? (int) $_POST['karmaGood'] : '\'\''; } if (isset($_POST['karmaBad'])) { $profile_vars['karmaBad'] = $_POST['karmaBad'] != '' ? (int) $_POST['karmaBad'] : '\'\''; } } // Assigning membergroups (you need admin_forum permissions to change an admins' membergroups). if (allowedTo('manage_membergroups')) { // The account page allows the change of your ID_GROUP - but not to admin!. if (isset($_POST['ID_GROUP']) && (allowedTo('admin_forum') || (int) $_POST['ID_GROUP'] != 1 && $old_profile['ID_GROUP'] != 1)) { $profile_vars['ID_GROUP'] = (int) $_POST['ID_GROUP']; } // Find the additional membergroups (if any) if (isset($_POST['additionalGroups']) && is_array($_POST['additionalGroups'])) { foreach ($_POST['additionalGroups'] as $i => $group_id) { if ((int) $group_id == 0 || !allowedTo('admin_forum') && (int) $group_id == 1) { unset($_POST['additionalGroups'][$i], $_POST['additionalGroups'][$i]); } else { $_POST['additionalGroups'][$i] = (int) $group_id; } } // Put admin back in there if you don't have permission to take it away. if (!allowedTo('admin_forum') && in_array(1, explode(',', $old_profile['additionalGroups']))) { $_POST['additionalGroups'][] = 1; } $profile_vars['additionalGroups'] = '\'' . implode(',', $_POST['additionalGroups']) . '\''; } // Too often, people remove delete their own account, or something. if (in_array(1, explode(',', $old_profile['additionalGroups'])) || $old_profile['ID_GROUP'] == 1) { $stillAdmin = !isset($profile_vars['ID_GROUP']) || $profile_vars['ID_GROUP'] == 1 || isset($_POST['additionalGroups']) && in_array(1, $_POST['additionalGroups']); // If they would no longer be an admin, look for any other... if (!$stillAdmin) { $request = db_query("\n\t\t\t\t\tSELECT ID_MEMBER\n\t\t\t\t\tFROM {$db_prefix}members\n\t\t\t\t\tWHERE (ID_GROUP = 1 OR FIND_IN_SET(1, additionalGroups))\n\t\t\t\t\t\tAND ID_MEMBER != {$memID}\n\t\t\t\t\tLIMIT 1", __FILE__, __LINE__); list($another) = mysql_fetch_row($request); mysql_free_result($request); if (empty($another)) { fatal_lang_error('at_least_one_admin'); } } } } // Validate the language file... if (($changeIdentity || $changeOther) && isset($_POST['lngfile']) && !empty($modSettings['userLanguage'])) { $language_directories = array($settings['default_theme_dir'] . '/languages', $settings['actual_theme_dir'] . '/languages'); if (!empty($settings['base_theme_dir'])) { $language_directories[] = $settings['base_theme_dir'] . '/languages'; } $language_directories = array_unique($language_directories); foreach ($language_directories as $language_dir) { if (!file_exists($language_dir)) { continue; } $dir = dir($language_dir); while ($entry = $dir->read()) { if (preg_match('~^index\\.(.+)\\.php$~', $entry, $matches) && $matches[1] == $_POST['lngfile']) { $profile_vars['lngfile'] = "'{$_POST['lngfile']}'"; // If they are the owner, make this persist even after they log out. if ($context['user']['is_owner']) { $_SESSION['language'] = $_POST['lngfile']; } } } $dir->close(); } } // Here's where we sort out all the 'other' values... if ($changeOther) { makeThemeChanges($memID, isset($_POST['ID_THEME']) ? (int) $_POST['ID_THEME'] : $old_profile['ID_THEME']); makeAvatarChanges($memID, $post_errors); makeNotificationChanges($memID); foreach ($profile_bools as $var) { if (isset($_POST[$var])) { $profile_vars[$var] = empty($_POST[$var]) ? '0' : '1'; } } foreach ($profile_ints as $var) { if (isset($_POST[$var])) { $profile_vars[$var] = $_POST[$var] != '' ? (int) $_POST[$var] : '\'\''; } } foreach ($profile_floats as $var) { if (isset($_POST[$var])) { $profile_vars[$var] = (double) $_POST[$var]; } } foreach ($profile_strings as $var) { if (isset($_POST[$var])) { $profile_vars[$var] = '\'' . $_POST[$var] . '\''; } } } if (isset($profile_vars['ICQ']) && $profile_vars['ICQ'] == '0') { $profile_vars['ICQ'] = '\'\''; } }
function RemindMail() { global $db_prefix, $context, $txt, $scripturl, $sourcedir, $user_info, $webmaster_email; checkSession(); // You must enter a username/email address. if (!isset($_POST['user']) || $_POST['user'] == '') { fatal_lang_error(40, false); } // Find the user! $request = db_query("\n\t\tSELECT ID_MEMBER, realName, memberName, emailAddress, is_activated, validation_code\n\t\tFROM {$db_prefix}members\n\t\tWHERE memberName = '{$_POST['user']}'\n\t\tLIMIT 1", __FILE__, __LINE__); if (mysql_num_rows($request) == 0) { mysql_free_result($request); $request = db_query("\n\t\t\tSELECT ID_MEMBER, realName, memberName, emailAddress, is_activated, validation_code\n\t\t\tFROM {$db_prefix}members\n\t\t\tWHERE emailAddress = '{$_POST['user']}'\n\t\t\tLIMIT 1", __FILE__, __LINE__); if (mysql_num_rows($request) == 0) { fatal_lang_error(40, false); } } $row = mysql_fetch_assoc($request); mysql_free_result($request); // If the user isn't activated/approved, give them some feedback on what to do next. if ($row['is_activated'] != 1) { // Awaiting approval... if (trim($row['validation_code']) == '') { fatal_error($txt['registration_not_approved'] . ' <a href="' . $scripturl . '?action=activate;user='******'user'] . '">' . $txt[662] . '</a>.', false); } else { fatal_error($txt['registration_not_activated'] . ' <a href="' . $scripturl . '?action=activate;user='******'user'] . '">' . $txt[662] . '</a>.', false); } } // You can't get emailed if you have no email address. $row['emailAddress'] = trim($row['emailAddress']); if ($row['emailAddress'] == '') { fatal_error('<b>' . $txt[394] . '<br />' . $txt[395] . ' <a href="mailto:' . $webmaster_email . '">webmaster</a> ' . $txt[396] . '.'); } // Randomly generate a new password, with only alpha numeric characters that is a max length of 10 chars. require_once $sourcedir . '/Subs-Members.php'; $password = generateValidationCode(); // Set the password in the database. updateMemberData($row['ID_MEMBER'], array('validation_code' => "'" . substr(md5($password), 0, 10) . "'")); require_once $sourcedir . '/Subs-Post.php'; sendmail($row['emailAddress'], $txt['reminder_subject'], sprintf($txt['sendtopic_dear'], $row['realName']) . "\n\n" . "{$txt['reminder_mail']}:\n\n" . "{$scripturl}?action=reminder;sa=setpassword;u={$row['ID_MEMBER']};code={$password}\n\n" . "{$txt['512']}: {$user_info['ip']}\n\n" . "{$txt['35']}: {$row['memberName']}\n\n" . $txt[130]); // Set up the template. $context += array('page_title' => &$txt[194], 'sub_template' => 'sent', 'description' => &$txt['reminder_sent']); }
/** * This function handles the approval, rejection, activation or deletion of members. * * What it does: * - Called by ?action=admin;area=viewmembers;sa=approve. * - Requires the moderate_forum permission. * - Redirects to ?action=admin;area=viewmembers;sa=browse * with the same parameters as the calling page. */ public function action_approve() { global $scripturl, $modSettings; // First, check our session. checkSession(); require_once SUBSDIR . '/Mail.subs.php'; require_once SUBSDIR . '/Members.subs.php'; // We also need to the login languages here - for emails. loadLanguage('Login'); // Start off clean $conditions = array(); // Sort out where we are going... $current_filter = $conditions['activated_status'] = (int) $_REQUEST['orig_filter']; // If we are applying a filter do just that - then redirect. if (isset($_REQUEST['filter']) && $_REQUEST['filter'] != $_REQUEST['orig_filter']) { redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $_REQUEST['filter'] . ';start=' . $_REQUEST['start']); } // Nothing to do? if (!isset($_POST['todoAction']) && !isset($_POST['time_passed'])) { redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); } // Are we dealing with members who have been waiting for > set amount of time? if (isset($_POST['time_passed'])) { $conditions['time_before'] = time() - 86400 * (int) $_POST['time_passed']; } else { $conditions['members'] = array(); foreach ($_POST['todoAction'] as $id) { $conditions['members'][] = (int) $id; } } $data = retrieveMemberData($conditions); if ($data['member_count'] == 0) { redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); } $member_info = $data['member_info']; $conditions['members'] = $data['members']; // Are we activating or approving the members? if ($_POST['todo'] == 'ok' || $_POST['todo'] == 'okemail') { // Approve / activate this member. approveMembers($conditions); // Check for email. if ($_POST['todo'] == 'okemail') { foreach ($member_info as $member) { $replacements = array('NAME' => $member['name'], 'USERNAME' => $member['username'], 'PROFILELINK' => $scripturl . '?action=profile;u=' . $member['id'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder'); $emaildata = loadEmailTemplate('admin_approve_accept', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } } // Update the menu action cache so its forced to refresh cache_put_data('num_menu_errors', null, 900); } elseif ($_POST['todo'] == 'require_activation') { require_once SUBSDIR . '/Auth.subs.php'; // We have to do this for each member I'm afraid. foreach ($member_info as $member) { $conditions['selected_member'] = $member['id']; // Generate a random activation code. $conditions['validation_code'] = generateValidationCode(); // Set these members for activation - I know this includes two id_member checks but it's safer than bodging $condition ;). enforceReactivation($conditions); $replacements = array('USERNAME' => $member['name'], 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $member['id'] . ';code=' . $conditions['validation_code'], 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $member['id'], 'ACTIVATIONCODE' => $conditions['validation_code']); $emaildata = loadEmailTemplate('admin_approve_activation', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } } elseif ($_POST['todo'] == 'reject' || $_POST['todo'] == 'rejectemail') { deleteMembers($conditions['members']); // Send email telling them they aren't welcome? if ($_POST['todo'] == 'rejectemail') { foreach ($member_info as $member) { $replacements = array('USERNAME' => $member['name']); $emaildata = loadEmailTemplate('admin_approve_reject', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 1); } } } elseif ($_POST['todo'] == 'delete' || $_POST['todo'] == 'deleteemail') { deleteMembers($conditions['members']); // Send email telling them they aren't welcome? if ($_POST['todo'] == 'deleteemail') { foreach ($member_info as $member) { $replacements = array('USERNAME' => $member['name']); $emaildata = loadEmailTemplate('admin_approve_delete', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 1); } } } elseif ($_POST['todo'] == 'remind') { foreach ($member_info as $member) { $replacements = array('USERNAME' => $member['name'], 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $member['id'] . ';code=' . $member['code'], 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $member['id'], 'ACTIVATIONCODE' => $member['code']); $emaildata = loadEmailTemplate('admin_approve_remind', $replacements, $member['language']); sendmail($member['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 1); } } // Log what we did? if (!empty($modSettings['modlog_enabled']) && in_array($_POST['todo'], array('ok', 'okemail', 'require_activation', 'remind'))) { $log_action = $_POST['todo'] == 'remind' ? 'remind_member' : 'approve_member'; foreach ($member_info as $member) { logAction($log_action, array('member' => $member['id']), 'admin'); } } // Although updateStats *may* catch this, best to do it manually just in case (Doesn't always sort out unapprovedMembers). if (in_array($current_filter, array(3, 4))) { updateSettings(array('unapprovedMembers' => $modSettings['unapprovedMembers'] > $data['member_count'] ? $modSettings['unapprovedMembers'] - $data['member_count'] : 0)); } // Update the member's stats. (but, we know the member didn't change their name.) updateStats('member', false); // If they haven't been deleted, update the post group statistics on them... if (!in_array($_POST['todo'], array('delete', 'deleteemail', 'reject', 'rejectemail', 'remind'))) { updateStats('postgroups', $conditions['members']); } redirectexit('action=admin;area=viewmembers;sa=browse;type=' . $_REQUEST['type'] . ';sort=' . $_REQUEST['sort'] . ';filter=' . $current_filter . ';start=' . $_REQUEST['start']); }
function GenerateSecureLoginHash($memberID) { global $smcFunc, $modSettings, $sourcedir; SetupLoginSecurityTable($memberID); require_once $sourcedir . '/Subs-Members.php'; $newHash = generateValidationCode(); $newHash_sha1 = sha1($newHash); // Setup the next experiation $nextexpire = time() + $modSettings['ls_securehash_expire_minutes'] * 60; $smcFunc['db_query']('', "\n\tUPDATE {db_prefix}login_security \n\tSET secureloginhash = '{$newHash_sha1}', secureloginhashexpiretime = {$nextexpire}\n\tWHERE ID_MEMBER = " . $memberID); return $newHash_sha1; }
function RemindPick() { global $context, $txt, $scripturl, $sourcedir, $user_info, $webmaster_email, $smcFunc, $language, $modSettings; checkSession(); // Coming with a known ID? if (!empty($_REQUEST['uid'])) { $where = 'id_member = {int:id_member}'; $where_params['id_member'] = (int) $_REQUEST['uid']; } elseif (isset($_POST['user']) && $_POST['user'] != '') { $where = 'member_name = {string:member_name}'; $where_params['member_name'] = $_POST['user']; $where_params['email_address'] = $_POST['user']; } // You must enter a username/email address. if (empty($where)) { fatal_lang_error('username_no_exist', false); } // Find the user! $request = $smcFunc['db_query']('', ' SELECT id_member, real_name, member_name, email_address, is_activated, validation_code, lngfile, openid_uri, secret_question FROM {db_prefix}members WHERE ' . $where . ' LIMIT 1', array_merge($where_params, array())); // Maybe email? if ($smcFunc['db_num_rows']($request) == 0 && empty($_REQUEST['uid'])) { $smcFunc['db_free_result']($request); $request = $smcFunc['db_query']('', ' SELECT id_member, real_name, member_name, email_address, is_activated, validation_code, lngfile, openid_uri, secret_question FROM {db_prefix}members WHERE email_address = {string:email_address} LIMIT 1', array_merge($where_params, array())); if ($smcFunc['db_num_rows']($request) == 0) { fatal_lang_error('no_user_with_email', false); } } $row = $smcFunc['db_fetch_assoc']($request); $smcFunc['db_free_result']($request); $context['account_type'] = !empty($row['openid_uri']) ? 'openid' : 'password'; // If the user isn't activated/approved, give them some feedback on what to do next. if ($row['is_activated'] != 1) { // Awaiting approval... if (trim($row['validation_code']) == '') { fatal_error($txt['registration_not_approved'] . ' <a href="' . $scripturl . '?action=activate;user='******'user'] . '">' . $txt['here'] . '</a>.', false); } else { fatal_error($txt['registration_not_activated'] . ' <a href="' . $scripturl . '?action=activate;user='******'user'] . '">' . $txt['here'] . '</a>.', false); } } // You can't get emailed if you have no email address. $row['email_address'] = trim($row['email_address']); if ($row['email_address'] == '') { fatal_error($txt['no_reminder_email'] . '<br />' . $txt['send_email'] . ' <a href="mailto:' . $webmaster_email . '">webmaster</a> ' . $txt['to_ask_password'] . '.'); } // If they have no secret question then they can only get emailed the item, or they are requesting the email, send them an email. if (empty($row['secret_question']) || isset($_POST['reminder_type']) && $_POST['reminder_type'] == 'email') { // Randomly generate a new password, with only alpha numeric characters that is a max length of 10 chars. require_once $sourcedir . '/Subs-Members.php'; $password = generateValidationCode(); require_once $sourcedir . '/Subs-Post.php'; $replacements = array('REALNAME' => $row['real_name'], 'REMINDLINK' => $scripturl . '?action=reminder;sa=setpassword;u=' . $row['id_member'] . ';code=' . $password, 'IP' => $user_info['ip'], 'MEMBERNAME' => $row['member_name'], 'OPENID' => $row['openid_uri']); $emaildata = loadEmailTemplate('forgot_' . $context['account_type'], $replacements, empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile']); $context['description'] = $txt['reminder_' . (!empty($row['openid_uri']) ? 'openid_' : '') . 'sent']; // If they were using OpenID simply email them their OpenID identity. sendmail($row['email_address'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); if (empty($row['openid_uri'])) { // Set the password in the database. updateMemberData($row['id_member'], array('validation_code' => substr(md5($password), 0, 10))); } // Set up the template. $context['sub_template'] = 'sent'; // Dont really. return; } elseif (isset($_POST['reminder_type']) && $_POST['reminder_type'] == 'secret') { return SecretAnswerInput(); } // No we're here setup the context for template number 2! $context['sub_template'] = 'reminder_pick'; $context['current_member'] = array('id' => $row['id_member'], 'name' => $row['member_name']); }
function resetPassword($memID, $username = null) { global $db_prefix, $scripturl, $context, $txt, $sourcedir, $modSettings; // Language... and a required file. loadLanguage('Login'); require_once $sourcedir . '/Subs-Post.php'; // Get some important details. $request = db_query("\n\t\tSELECT memberName, emailAddress\n\t\tFROM {$db_prefix}members\n\t\tWHERE ID_MEMBER = {$memID}", __FILE__, __LINE__); list($user, $email) = mysql_fetch_row($request); mysql_free_result($request); if ($username !== null) { $old_user = $user; $user = trim($username); } // Generate a random password. require_once $sourcedir . '/Subs-Members.php'; $newPassword = generateValidationCode(); $newPassword_sha1 = sha1(strtolower($user) . $newPassword); // Do some checks on the username if needed. if ($username !== null) { // No name?! How can you register with no name? if ($user == '') { fatal_lang_error(37, false); } // Only these characters are permitted. if (in_array($user, array('_', '|')) || preg_match('~[<>&"\'=\\\\]~', $user) != 0 || strpos($user, '[code') !== false || strpos($user, '[/code') !== false) { fatal_lang_error(240, false); } if (stristr($user, $txt[28]) !== false) { fatal_lang_error(244, true, array($txt[28])); } require_once $sourcedir . '/Subs-Members.php'; if (isReservedName($user, $memID, false)) { fatal_error('(' . htmlspecialchars($user) . ') ' . $txt[473], false); } // Update the database... updateMemberData($memID, array('memberName' => '\'' . $user . '\'', 'passwd' => '\'' . $newPassword_sha1 . '\'')); } else { updateMemberData($memID, array('passwd' => '\'' . $newPassword_sha1 . '\'')); } if (isset($modSettings['integrate_reset_pass']) && function_exists($modSettings['integrate_reset_pass'])) { call_user_func($modSettings['integrate_reset_pass'], $old_user, $user, $newPassword); } // Send them the email informing them of the change - then we're done! sendmail($email, $txt['change_password'], "{$txt['hello_member']} {$user}!\n\n" . "{$txt['change_password_1']} {$context['forum_name']} {$txt['change_password_2']}\n\n" . "{$txt['719']}{$user}, {$txt['492']} {$newPassword}\n\n" . "{$txt['701']}\n" . "{$scripturl}?action=profile\n\n" . $txt[130]); }
function registerMember(&$regOptions) { global $scripturl, $txt, $modSettings, $db_prefix, $context, $sourcedir; global $user_info, $options, $settings, $func; loadLanguage('Login'); // We'll need some external functions. require_once $sourcedir . '/Subs-Auth.php'; require_once $sourcedir . '/Subs-Post.php'; // Registration from the admin center, let them sweat a little more. if ($regOptions['interface'] == 'admin') { is_not_guest(); isAllowedTo('moderate_forum'); } elseif ($regOptions['interface'] == 'guest') { spamProtection('register'); // You cannot register twice... if (empty($user_info['is_guest'])) { redirectexit(); } // Make sure they didn't just register with this session. if (!empty($_SESSION['just_registered']) && empty($modSettings['disableRegisterCheck'])) { fatal_lang_error('register_only_once', false); } } // No name?! How can you register with no name? if (empty($regOptions['username'])) { fatal_lang_error(37, false); } // Spaces and other odd characters are evil... $regOptions['username'] = preg_replace('~[\\t\\n\\r\\x0B\\0' . ($context['utf8'] ? $context['server']['complex_preg_chars'] ? '\\x{A0}' : pack('C*', 0xc2, 0xa0) : '\\xA0') . ']+~' . ($context['utf8'] ? 'u' : ''), ' ', $regOptions['username']); // Don't use too long a name. if ($func['strlen']($regOptions['username']) > 25) { $regOptions['username'] = $func['htmltrim']($func['substr']($regOptions['username'], 0, 25)); } // Only these characters are permitted. if (preg_match('~[<>&"\'=\\\\]~', $regOptions['username']) != 0 || $regOptions['username'] == '_' || $regOptions['username'] == '|' || strpos($regOptions['username'], '[code') !== false || strpos($regOptions['username'], '[/code') !== false) { fatal_lang_error(240, false); } if (stristr($regOptions['username'], $txt[28]) !== false) { fatal_lang_error(244, true, array($txt[28])); } // !!! Separate the sprintf? if (empty($regOptions['email']) || preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', stripslashes($regOptions['email'])) === 0 || strlen(stripslashes($regOptions['email'])) > 255) { fatal_error(sprintf($txt[500], $regOptions['username']), false); } if (!empty($regOptions['check_reserved_name']) && isReservedName($regOptions['username'], 0, false)) { if ($regOptions['password'] == 'chocolate cake') { fatal_error('Sorry, I don\'t take bribes... you\'ll need to come up with a different name.', false); } fatal_error('(' . htmlspecialchars($regOptions['username']) . ') ' . $txt[473], false); } // Generate a validation code if it's supposed to be emailed. $validation_code = ''; if ($regOptions['require'] == 'activation') { $validation_code = generateValidationCode(); } // If you haven't put in a password generated one. if ($regOptions['interface'] == 'admin' && $regOptions['password'] == '') { mt_srand(time() + 1277); $regOptions['password'] = generateValidationCode(); $regOptions['password_check'] = $regOptions['password']; } elseif ($regOptions['password'] != $regOptions['password_check']) { fatal_lang_error(213, false); } // That's kind of easy to guess... if ($regOptions['password'] == '') { fatal_lang_error(91, false); } // Now perform hard password validation as required. if (!empty($regOptions['check_password_strength'])) { $passwordError = validatePassword($regOptions['password'], $regOptions['username'], array($regOptions['email'])); // Password isn't legal? if ($passwordError != null) { fatal_lang_error('profile_error_password_' . $passwordError, false); } } // You may not be allowed to register this email. if (!empty($regOptions['check_email_ban'])) { isBannedEmail($regOptions['email'], 'cannot_register', $txt['ban_register_prohibited']); } // Check if the email address is in use. $request = db_query("\n\t\tSELECT ID_MEMBER\n\t\tFROM {$db_prefix}members\n\t\tWHERE emailAddress = '{$regOptions['email']}'\n\t\t\tOR emailAddress = '{$regOptions['username']}'\n\t\tLIMIT 1", __FILE__, __LINE__); // !!! Separate the sprintf? if (mysql_num_rows($request) != 0) { fatal_error(sprintf($txt[730], htmlspecialchars($regOptions['email'])), false); } mysql_free_result($request); // Some of these might be overwritten. (the lower ones that are in the arrays below.) $regOptions['register_vars'] = array('memberName' => "'{$regOptions['username']}'", 'emailAddress' => "'{$regOptions['email']}'", 'passwd' => '\'' . sha1(strtolower($regOptions['username']) . $regOptions['password']) . '\'', 'passwordSalt' => '\'' . substr(md5(mt_rand()), 0, 4) . '\'', 'posts' => 0, 'dateRegistered' => time(), 'memberIP' => "'{$user_info['ip']}'", 'memberIP2' => "'{$_SERVER['BAN_CHECK_IP']}'", 'validation_code' => "'{$validation_code}'", 'realName' => "'{$regOptions['username']}'", 'personalText' => '\'' . addslashes($modSettings['default_personalText']) . '\'', 'pm_email_notify' => 1, 'ID_THEME' => 0, 'ID_POST_GROUP' => 4, 'lngfile' => "''", 'buddy_list' => "''", 'pm_ignore_list' => "''", 'messageLabels' => "''", 'personalText' => "''", 'websiteTitle' => "''", 'websiteUrl' => "''", 'location' => "''", 'ICQ' => "''", 'AIM' => "''", 'YIM' => "''", 'MSN' => "''", 'timeFormat' => "''", 'signature' => "''", 'avatar' => "''", 'usertitle' => "''", 'secretQuestion' => "''", 'secretAnswer' => "''", 'additionalGroups' => "''", 'smileySet' => "''"); // Setup the activation status on this new account so it is correct - firstly is it an under age account? if ($regOptions['require'] == 'coppa') { $regOptions['register_vars']['is_activated'] = 5; // !!! This should be changed. To what should be it be changed?? $regOptions['register_vars']['validation_code'] = "''"; } elseif ($regOptions['require'] == 'nothing') { $regOptions['register_vars']['is_activated'] = 1; } elseif ($regOptions['require'] == 'activation') { $regOptions['register_vars']['is_activated'] = 0; } else { $regOptions['register_vars']['is_activated'] = 3; } if (isset($regOptions['memberGroup'])) { // Make sure the ID_GROUP will be valid, if this is an administator. $regOptions['register_vars']['ID_GROUP'] = $regOptions['memberGroup'] == 1 && !allowedTo('admin_forum') ? 0 : $regOptions['memberGroup']; // Check if this group is assignable. $unassignableGroups = array(-1, 3); $request = db_query("\n\t\t\tSELECT ID_GROUP\n\t\t\tFROM {$db_prefix}membergroups\n\t\t\tWHERE minPosts != -1", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($request)) { $unassignableGroups[] = $row['ID_GROUP']; } mysql_free_result($request); if (in_array($regOptions['register_vars']['ID_GROUP'], $unassignableGroups)) { $regOptions['register_vars']['ID_GROUP'] = 0; } } // Integrate optional member settings to be set. if (!empty($regOptions['extra_register_vars'])) { foreach ($regOptions['extra_register_vars'] as $var => $value) { $regOptions['register_vars'][$var] = $value; } } // Integrate optional user theme options to be set. $theme_vars = array(); if (!empty($regOptions['theme_vars'])) { foreach ($regOptions['theme_vars'] as $var => $value) { $theme_vars[$var] = $value; } } // Call an optional function to validate the users' input. if (isset($modSettings['integrate_register']) && function_exists($modSettings['integrate_register'])) { $modSettings['integrate_register']($regOptions, $theme_vars); } // Register them into the database. db_query("\n\t\tINSERT INTO {$db_prefix}members\n\t\t\t(" . implode(', ', array_keys($regOptions['register_vars'])) . ")\n\t\tVALUES (" . implode(', ', $regOptions['register_vars']) . ')', __FILE__, __LINE__); $memberID = db_insert_id(); // Grab their real name and send emails using it. $realName = substr($regOptions['register_vars']['realName'], 1, -1); // Update the number of members and latest member's info - and pass the name, but remove the 's. updateStats('member', $memberID, $realName); // Theme variables too? if (!empty($theme_vars)) { $setString = ''; foreach ($theme_vars as $var => $val) { $setString .= "\n\t\t\t\t({$memberID}, SUBSTRING('{$var}', 1, 255), SUBSTRING('{$val}', 1, 65534)),"; } db_query("\n\t\t\tINSERT INTO {$db_prefix}themes\n\t\t\t\t(ID_MEMBER, variable, value)\n\t\t\tVALUES " . substr($setString, 0, -1), __FILE__, __LINE__); } // If it's enabled, increase the registrations for today. trackStats(array('registers' => '+')); // Administrative registrations are a bit different... if ($regOptions['interface'] == 'admin') { if ($regOptions['require'] == 'activation') { $email_message = 'register_activate_message'; } elseif (!empty($regOptions['send_welcome_email'])) { $email_message = 'register_immediate_message'; } if (isset($email_message)) { sendmail($regOptions['email'], $txt['register_subject'], sprintf($txt[$email_message], $realName, $regOptions['username'], $regOptions['password'], $validation_code, $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code)); } // All admins are finished here. return $memberID; } // Can post straight away - welcome them to your fantastic community... if ($regOptions['require'] == 'nothing') { if (!empty($regOptions['send_welcome_email'])) { sendmail($regOptions['email'], $txt['register_subject'], sprintf($txt['register_immediate_message'], $realName, $regOptions['username'], $regOptions['password'])); } // Send admin their notification. adminNotify('standard', $memberID, $regOptions['username']); } elseif ($regOptions['require'] == 'activation' || $regOptions['require'] == 'coppa') { sendmail($regOptions['email'], $txt['register_subject'], sprintf($txt['register_activate_message'], $realName, $regOptions['username'], $regOptions['password'], $validation_code, $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code)); } else { sendmail($regOptions['email'], $txt['register_subject'], sprintf($txt['register_pending_message'], $realName, $regOptions['username'], $regOptions['password'])); // Admin gets informed here... adminNotify('approval', $memberID, $regOptions['username']); } // Okay, they're for sure registered... make sure the session is aware of this for security. (Just married :P!) $_SESSION['just_registered'] = 1; return $memberID; }
/** * Pick a reminder type. * Accessed by sa=picktype */ public function action_picktype() { global $context, $txt, $scripturl, $user_info, $webmaster_email, $language, $modSettings; checkSession(); validateToken('remind'); createToken('remind'); require_once SUBSDIR . '/Auth.subs.php'; // No where params just yet $where_params = array(); // Coming with a known ID? if (!empty($_REQUEST['uid'])) { $where = 'id_member = {int:id_member}'; $where_params['id_member'] = (int) $_REQUEST['uid']; } elseif (isset($_POST['user']) && $_POST['user'] != '') { $where = 'member_name = {string:member_name}'; $where_params['member_name'] = $_POST['user']; $where_params['email_address'] = $_POST['user']; } // You must enter a username/email address. if (empty($where)) { fatal_lang_error('username_no_exist', false); } // Make sure we are not being slammed // Don't call this if you're coming from the "Choose a reminder type" page - otherwise you'll likely get an error if (!isset($_POST['reminder_type']) || !in_array($_POST['reminder_type'], array('email', 'secret'))) { spamProtection('remind'); } $member = findUser($where, $where_params); $context['account_type'] = !empty($member['openid_uri']) ? 'openid' : 'password'; // If the user isn't activated/approved, give them some feedback on what to do next. if ($member['is_activated'] != 1) { // Awaiting approval... if (trim($member['validation_code']) == '') { fatal_error($txt['registration_not_approved'] . ' <a href="' . $scripturl . '?action=activate;user='******'user'] . '">' . $txt['here'] . '</a>.', false); } else { fatal_error($txt['registration_not_activated'] . ' <a href="' . $scripturl . '?action=activate;user='******'user'] . '">' . $txt['here'] . '</a>.', false); } } // You can't get emailed if you have no email address. $member['email_address'] = trim($member['email_address']); if ($member['email_address'] == '') { fatal_error($txt['no_reminder_email'] . '<br />' . $txt['send_email'] . ' <a href="mailto:' . $webmaster_email . '">webmaster</a> ' . $txt['to_ask_password'] . '.'); } // If they have no secret question then they can only get emailed the item, or they are requesting the email, send them an email. if (empty($member['secret_question']) || isset($_POST['reminder_type']) && $_POST['reminder_type'] == 'email') { // Randomly generate a new password, with only alpha numeric characters that is a max length of 10 chars. $password = generateValidationCode(); require_once SUBSDIR . '/Mail.subs.php'; $replacements = array('REALNAME' => $member['real_name'], 'REMINDLINK' => $scripturl . '?action=reminder;sa=setpassword;u=' . $member['id_member'] . ';code=' . $password, 'IP' => $user_info['ip'], 'MEMBERNAME' => $member['member_name'], 'OPENID' => $member['openid_uri']); $emaildata = loadEmailTemplate('forgot_' . $context['account_type'], $replacements, empty($member['lngfile']) || empty($modSettings['userLanguage']) ? $language : $member['lngfile']); $context['description'] = $txt['reminder_' . (!empty($member['openid_uri']) ? 'openid_' : '') . 'sent']; // If they were using OpenID simply email them their OpenID identity. sendmail($member['email_address'], $emaildata['subject'], $emaildata['body'], null, null, false, 1); if (empty($member['openid_uri'])) { // Set the password in the database. updateMemberData($member['id_member'], array('validation_code' => substr(md5($password), 0, 10))); } // Set up the template. $context['sub_template'] = 'sent'; // Dont really. return; } elseif (isset($_POST['reminder_type']) && $_POST['reminder_type'] == 'secret') { return secretAnswerInput(); } // No we're here setup the context for template number 2! $context['sub_template'] = 'reminder_pick'; $context['current_member'] = array('id' => $member['id_member'], 'name' => $member['member_name']); }
function mob_update_email($rpcmsg) { global $txt, $modSettings; global $cookiename, $context; global $sourcedir, $scripturl, $db_prefix; global $ID_MEMBER, $user_info; global $newpassemail, $user_profile, $validationCode; loadLanguage('Profile'); // Start with no updates and no errors. $profile_vars = array(); $post_errors = array(); $_POST['oldpasswrd'] = $rpcmsg->getParam(0) ? $rpcmsg->getScalarValParam(0) : ''; $_POST['emailAddress'] = $rpcmsg->getParam(1) ? $rpcmsg->getScalarValParam(1) : ''; // Clean up the POST variables. $_POST = htmltrim__recursive($_POST); $_POST = stripslashes__recursive($_POST); $_POST = htmlspecialchars__recursive($_POST); $_POST = addslashes__recursive($_POST); $memberResult = loadMemberData($ID_MEMBER, false, 'profile'); if (!is_array($memberResult)) { fatal_lang_error(453, false); } $memID = $ID_MEMBER; $newpassemail = false; $context['user']['is_owner'] = true; isAllowedTo(array('manage_membergroups', 'profile_identity_any', 'profile_identity_own')); // You didn't even enter a password! if (trim($_POST['oldpasswrd']) == '') { fatal_error($txt['profile_error_no_password']); } // This block is only concerned with email address validation.. if (strtolower($_POST['emailAddress']) != strtolower($user_profile[$memID]['emailAddress'])) { $_POST['emailAddress'] = strtr($_POST['emailAddress'], array(''' => '\\\'')); // Prepare the new password, or check if they want to change their own. if (!empty($modSettings['send_validation_onChange']) && !allowedTo('moderate_forum')) { require_once $sourcedir . '/Subs-Members.php'; $validationCode = generateValidationCode(); $profile_vars['validation_code'] = '\'' . $validationCode . '\''; $profile_vars['is_activated'] = '2'; $newpassemail = true; } // Check the name and email for validity. if (trim($_POST['emailAddress']) == '') { fatal_error($txt['profile_error_no_email']); } if (preg_match('~^[0-9A-Za-z=_+\\-/][0-9A-Za-z=_\'+\\-/\\.]*@[\\w\\-]+(\\.[\\w\\-]+)*(\\.[\\w]{2,6})$~', stripslashes($_POST['emailAddress'])) == 0) { fatal_error($txt['profile_error_bad_email']); } // Email addresses should be and stay unique. $request = db_query("\n SELECT ID_MEMBER\n FROM {$db_prefix}members\n WHERE ID_MEMBER != {$memID}\n AND emailAddress = '{$_POST['emailAddress']}'\n LIMIT 1", __FILE__, __LINE__); if (mysql_num_rows($request) > 0) { fatal_error($txt['profile_error_email_taken']); } mysql_free_result($request); $profile_vars['emailAddress'] = '\'' . $_POST['emailAddress'] . '\''; } if (!empty($profile_vars)) { updateMemberData($memID, $profile_vars); } // Send an email? if ($newpassemail) { require_once $sourcedir . '/Subs-Post.php'; // Send off the email. sendmail($_POST['emailAddress'], $txt['activate_reactivate_title'] . ' ' . $context['forum_name'], "{$txt['activate_reactivate_mail']}\n\n" . "{$scripturl}?action=activate;u={$memID};code={$validationCode}\n\n" . "{$txt['activate_code']}: {$validationCode}\n\n" . $txt[130]); // Log the user out. db_query("\n DELETE FROM {$db_prefix}log_online\n WHERE ID_MEMBER = {$memID}", __FILE__, __LINE__); $_SESSION['log_time'] = 0; $_SESSION['login_' . $cookiename] = serialize(array(0, '', 0)); } $response = array('result' => new xmlrpcval(true, 'boolean'), 'result_text' => new xmlrpcval('', 'base64')); return new xmlrpcresp(new xmlrpcval($response, 'struct')); }
function loadProfileFields($force_reload = false) { global $context, $profile_fields, $txt, $scripturl, $modSettings, $user_info, $old_profile, $smcFunc, $cur_profile, $language; // Don't load this twice! if (!empty($profile_fields) && !$force_reload) { return; } /* This horrific array defines all the profile fields in the whole world! In general each "field" has one array - the key of which is the database column name associated with said field. Each item can have the following attributes: string $type: The type of field this is - valid types are: - callback: This is a field which has its own callback mechanism for templating. - check: A simple checkbox. - hidden: This doesn't have any visual aspects but may have some validity. - password: A password box. - select: A select box. - text: A string of some description. string $label: The label for this item - default will be $txt[$key] if this isn't set. string $subtext: The subtext (Small label) for this item. int $size: Optional size for a text area. array $input_attr: An array of text strings to be added to the input box for this item. string $value: The value of the item. If not set $cur_profile[$key] is assumed. string $permission: Permission required for this item (Excluded _any/_own subfix which is applied automatically). function $input_validate: A runtime function which validates the element before going to the database. It is passed the relevant $_POST element if it exists and should be treated like a reference. Return types: - true: Element can be stored. - false: Skip this element. - a text string: An error occured - this is the error message. function $preload: A function that is used to load data required for this element to be displayed. Must return true to be displayed at all. string $cast_type: If set casts the element to a certain type. Valid types (bool, int, float). string $save_key: If the index of this element isn't the database column name it can be overriden with this string. bool $is_dummy: If set then nothing is acted upon for this element. bool $enabled: A test to determine whether this is even available - if not is unset. string $link_with: Key which links this field to an overall set. Note that all elements that have a custom input_validate must ensure they set the value of $cur_profile correct to enable the changes to be displayed correctly on submit of the form. */ $profile_fields = array('avatar_choice' => array('type' => 'callback_template', 'callback_name' => 'profile/avatar_select', 'preload' => 'profileLoadAvatarData', 'input_validate' => 'profileSaveAvatarData', 'save_key' => 'avatar'), 'bday1' => array('type' => 'callback_template', 'callback_name' => 'profile/birthdate_select', 'permission' => 'profile_extra', 'preload' => function () { global $cur_profile, $context; // Split up the birthdate.... list($uyear, $umonth, $uday) = explode('-', empty($cur_profile['birthdate']) || $cur_profile['birthdate'] == '0001-01-01' ? '0000-00-00' : $cur_profile['birthdate']); $context['member']['birth_date'] = array('year' => $uyear == '0004' ? '0000' : $uyear, 'month' => $umonth, 'day' => $uday); return true; }, 'input_validate' => function (&$value) { global $profile_vars, $cur_profile; if (isset($_POST['bday2'], $_POST['bday3']) && $value > 0 && $_POST['bday2'] > 0) { // Set to blank? if ((int) $_POST['bday3'] == 1 && (int) $_POST['bday2'] == 1 && (int) $value == 1) { $value = '0001-01-01'; } else { $value = checkdate($value, $_POST['bday2'], $_POST['bday3'] < 4 ? 4 : $_POST['bday3']) ? sprintf('%04d-%02d-%02d', $_POST['bday3'] < 4 ? 4 : $_POST['bday3'], $_POST['bday1'], $_POST['bday2']) : '0001-01-01'; } } else { $value = '0001-01-01'; } $profile_vars['birthdate'] = $value; $cur_profile['birthdate'] = $value; return false; }), 'birthdate' => array('type' => 'hidden', 'permission' => 'profile_extra', 'input_validate' => function (&$value) { global $cur_profile; // !!! Should we check for this year and tell them they made a mistake :P? (based on coppa at least?) if (preg_match('/(\\d{4})[\\-\\., ](\\d{2})[\\-\\., ](\\d{2})/', $value, $dates) === 1) { $value = checkdate($dates[2], $dates[3], $dates[1] < 4 ? 4 : $dates[1]) ? sprintf('%04d-%02d-%02d', $dates[1] < 4 ? 4 : $dates[1], $dates[2], $dates[3]) : '0001-01-01'; return true; } else { $value = empty($cur_profile['birthdate']) ? '0001-01-01' : $cur_profile['birthdate']; return false; } }), 'date_registered' => array('type' => 'text', 'value' => empty($cur_profile['date_registered']) ? $txt['not_applicable'] : strftime('%Y-%m-%d', $cur_profile['date_registered'] + ($user_info['time_offset'] + $modSettings['time_offset']) * 3600), 'label' => $txt['date_registered'], 'log_change' => true, 'permission' => 'moderate_forum', 'input_validate' => function (&$value) { global $txt, $user_info, $modSettings, $cur_profile, $context; // Bad date! Go try again - please? if (($value = strtotime($value)) === -1) { $value = $cur_profile['date_registered']; return $txt['invalid_registration'] . ' ' . strftime('%d %b %Y ' . (strpos($user_info['time_format'], '%H') !== false ? '%I:%M:%S %p' : '%H:%M:%S'), forum_time(false)); } elseif ($value != $txt['not_applicable'] && $value != strtotime(strftime('%Y-%m-%d', $cur_profile['date_registered'] + ($user_info['time_offset'] + $modSettings['time_offset']) * 3600))) { $value = $value - ($user_info['time_offset'] + $modSettings['time_offset']) * 3600; } else { $value = $cur_profile['date_registered']; } return true; }), 'email_address' => array('type' => 'text', 'label' => $txt['email'], 'subtext' => $txt['valid_email'], 'log_change' => true, 'permission' => 'profile_identity', 'input_validate' => function (&$value) { global $context, $old_profile, $context, $profile_vars, $sourcedir, $modSettings; if (strtolower($value) == strtolower($old_profile['email_address'])) { return false; } $isValid = profileValidateEmail($value, $context['id_member']); // Do they need to revalidate? If so schedule the function! if ($isValid === true && !empty($modSettings['send_validation_onChange']) && !allowedTo('moderate_forum')) { require_once $sourcedir . '/lib/Subs-Members.php'; $profile_vars['validation_code'] = generateValidationCode(); $profile_vars['is_activated'] = 2; $context['profile_execute_on_save'][] = 'profileSendActivation'; unset($context['profile_execute_on_save']['reload_user']); } return $isValid; }), 'gender' => array('type' => 'select', 'cast_type' => 'int', 'options' => 'return array(0 => \'\', 1 => $txt[\'male\'], 2 => $txt[\'female\']);', 'label' => $txt['gender'], 'permission' => 'profile_extra'), 'hide_email' => array('type' => 'check', 'value' => empty($cur_profile['hide_email']) ? true : false, 'label' => $txt['allow_user_email'], 'permission' => 'profile_identity', 'input_validate' => function (&$value) { $value = $value == 0 ? 1 : 0; return true; }), 'id_group' => array('type' => 'callback_template', 'callback_name' => 'profile/group_manage', 'permission' => 'manage_membergroups', 'preload' => 'profileLoadGroups', 'log_change' => true, 'input_validate' => 'profileSaveGroups'), 'id_theme' => array('type' => 'callback_template', 'callback_name' => 'profile/theme_pick', 'permission' => 'profile_extra', 'enabled' => $modSettings['theme_allow'] || allowedTo('admin_forum'), 'preload' => function () { global $context, $cur_profile, $txt; $request = smf_db_query('SELECT value FROM {db_prefix}themes WHERE id_theme = {int:id_theme} AND variable = {string:variable} LIMIT 1', array('id_theme' => $cur_profile['id_theme'], 'variable' => 'name')); list($name) = mysql_fetch_row($request); mysql_free_result($request); $context['member']['theme'] = array('id' => $cur_profile['id_theme'], 'name' => empty($cur_profile['id_theme']) ? $txt['theme_forum_default'] : $name); return true; }, 'input_validate' => function (&$value) { $value = (int) $value; return true; }), 'karma_good' => array('type' => 'callback_template', 'callback_name' => 'profile/reputation_display', 'permission' => 'admin_forum', 'input_validate' => function (&$value) { global $profile_vars, $cur_profile; $value = (int) $value; if (isset($_POST['karma_bad'])) { $profile_vars['karma_bad'] = $_POST['karma_bad'] != '' ? (int) $_POST['karma_bad'] : 0; $cur_profile['karma_bad'] = $_POST['karma_bad'] != '' ? (int) $_POST['karma_bad'] : 0; } return true; }, 'preload' => function () { global $context, $cur_profile; //$context['member']['karma']['good'] = $cur_profile['karma_good']; //$context['member']['karma']['bad'] = $cur_profile['karma_bad']; return true; }, 'enabled' => !empty($modSettings['karmaMode'])), 'lngfile' => array('type' => 'select', 'options' => 'return $context[\'profile_languages\'];', 'label' => $txt['preferred_language'], 'permission' => 'profile_identity', 'preload' => 'profileLoadLanguages', 'enabled' => !empty($modSettings['userLanguage']), 'value' => empty($cur_profile['lngfile']) ? $language : $cur_profile['lngfile'], 'input_validate' => function (&$value) { global $context, $cur_profile; // Load the languages. profileLoadLanguages(); if (isset($context['profile_languages'][$value])) { if ($context['user']['is_owner']) { $_SESSION['language'] = $value; } return true; } else { $value = $cur_profile['lngfile']; return false; } }), 'location' => array('type' => 'text', 'label' => $txt['location'], 'log_change' => true, 'size' => 50, 'permission' => 'profile_extra'), 'member_name' => array('type' => allowedTo('admin_forum') && isset($_GET['changeusername']) ? 'text' : 'label', 'label' => $txt['username'], 'subtext' => allowedTo('admin_forum') && !isset($_GET['changeusername']) ? '(<a href="' . $scripturl . '?action=profile;u=' . $context['id_member'] . ';area=account;changeusername" style="font-style: italic;">' . $txt['username_change'] . '</a>)' : '', 'log_change' => true, 'permission' => 'profile_identity', 'prehtml' => allowedTo('admin_forum') && isset($_GET['changeusername']) ? '<div class="alert">' . $txt['username_warning'] . '</div>' : '', 'input_validate' => function (&$value) { global $sourcedir, $context, $user_info, $cur_profile; if (allowedTo('admin_forum')) { // We\'ll need this... require_once $sourcedir . '/lib/Subs-Auth.php'; // Maybe they are trying to change their password as well? $resetPassword = true; if (isset($_POST['passwrd1']) && $_POST['passwrd1'] != '' && isset($_POST['passwrd2']) && $_POST['passwrd1'] == $_POST['passwrd2'] && validatePassword($_POST['passwrd1'], $value, array($cur_profile['real_name'], $user_info['username'], $user_info['name'], $user_info['email'])) == null) { $resetPassword = false; } // Do the reset... this will send them an email too. if ($resetPassword) { resetPassword($context['id_member'], $value); } elseif ($value !== null) { validateUsername($context['id_member'], $value); updateMemberData($context['id_member'], array('member_name' => $value)); } } return false; }), 'passwrd1' => array('type' => 'password', 'label' => $txt['choose_pass'], 'subtext' => $txt['password_strength'], 'size' => 20, 'value' => '', 'enabled' => empty($cur_profile['openid_uri']), 'permission' => 'profile_identity', 'save_key' => 'passwd', 'input_validate' => function (&$value) { global $sourcedir, $user_info, $smcFunc, $cur_profile; // If we didn\'t try it then ignore it! if ($value == '') { return false; } // Do the two entries for the password even match? if (!isset($_POST['passwrd2']) || $value != $_POST['passwrd2']) { return 'bad_new_password'; } // Let\'s get the validation function into play... require_once $sourcedir . '/lib/Subs-Auth.php'; $passwordErrors = validatePassword($value, $cur_profile['member_name'], array($cur_profile['real_name'], $user_info['username'], $user_info['name'], $user_info['email'])); // Were there errors? if ($passwordErrors != null) { return 'password_' . $passwordErrors; } // Set up the new password variable... ready for storage. $value = sha1(strtolower($cur_profile['member_name']) . un_htmlspecialchars($value)); return true; }), 'passwrd2' => array('type' => 'password', 'label' => $txt['verify_pass'], 'enabled' => empty($cur_profile['openid_uri']), 'size' => 20, 'value' => '', 'permission' => 'profile_identity', 'is_dummy' => true), 'personal_text' => array('type' => 'text', 'label' => $txt['personal_text'], 'log_change' => true, 'input_attr' => array('maxlength="50"'), 'size' => 50, 'permission' => 'profile_extra'), 'pm_prefs' => array('type' => 'callback_template', 'callback_name' => 'pm/settings', 'permission' => 'pm_read', 'preload' => function () { global $context, $cur_profile; $context['display_mode'] = $cur_profile['pm_prefs'] & 3; $context['send_email'] = $cur_profile['pm_email_notify']; $context['receive_from'] = !empty($cur_profile['pm_receive_from']) ? $cur_profile['pm_receive_from'] : 0; return true; }, 'input_validate' => function (&$value) { global $cur_profile, $profile_vars; // Simple validate and apply the two "sub settings" $value = max(min($value, 2), 0); $cur_profile['pm_email_notify'] = $profile_vars['pm_email_notify'] = max(min((int) $_POST['pm_email_notify'], 2), 0); $cur_profile['pm_receive_from'] = $profile_vars['pm_receive_from'] = max(min((int) $_POST['pm_receive_from'], 4), 0); return true; }), 'posts' => array('type' => 'int', 'label' => $txt['profile_posts'], 'log_change' => true, 'size' => 7, 'permission' => 'moderate_forum', 'input_validate' => function (&$value) { $value = $value != '' ? strtr($value, array(',' => '', '.' => '', ' ' => '')) : 0; return true; }), 'real_name' => array('type' => !empty($modSettings['allow_editDisplayName']) || allowedTo('moderate_forum') ? 'text' : 'label', 'label' => $txt['name'], 'subtext' => $txt['display_name_desc'], 'log_change' => true, 'input_attr' => array('maxlength="60"'), 'permission' => 'profile_identity', 'enabled' => !empty($modSettings['allow_editDisplayName']) || allowedTo('moderate_forum'), 'input_validate' => function (&$value) { global $context, $smcFunc, $sourcedir, $cur_profile; $value = trim(preg_replace('~[\\s]~' . ($context['utf8'] ? 'u' : ''), ' ', $value)); if (trim($value) == '') { return 'no_name'; } elseif (CommonAPI::strlen($value) > 60) { return 'name_too_long'; } elseif ($cur_profile['real_name'] != $value) { require_once $sourcedir . '/lib/Subs-Members.php'; if (isReservedName($value, $context['id_member'])) { return 'name_taken'; } } return true; }), 'secret_question' => array('type' => 'text', 'label' => $txt['secret_question'], 'subtext' => $txt['secret_desc'], 'size' => 50, 'permission' => 'profile_identity'), 'secret_answer' => array('type' => 'text', 'label' => $txt['secret_answer'], 'subtext' => $txt['secret_desc2'], 'size' => 20, 'postinput' => '<span class="smalltext" style="margin-left: 4ex;"><a href="' . $scripturl . '?action=helpadmin;help=secret_why_blank" onclick="return reqWin(this.href);">' . $txt['secret_why_blank'] . '</a></span>', 'value' => '', 'permission' => 'profile_identity', 'input_validate' => function (&$value) { $value = $value != '' ? md5($value) : ''; return true; }), 'signature' => array('type' => 'callback_template', 'callback_name' => allowedTo('profile_signature') ? 'profile/signature_modify' : 'profile/signature_cannot_modify', 'permission' => 'profile_extra', 'enabled' => substr($modSettings['signature_settings'], 0, 1) == 1, 'preload' => 'profileLoadSignatureData', 'input_validate' => 'profileValidateSignature'), 'show_online' => array('type' => 'check', 'label' => $txt['show_online'], 'permission' => 'profile_identity', 'enabled' => !empty($modSettings['allow_hideOnline']) || allowedTo('moderate_forum')), 'smiley_set' => array('type' => 'callback_template', 'callback_name' => 'profile/smiley_pick', 'enabled' => !empty($modSettings['smiley_sets_enable']), 'permission' => 'profile_extra', 'preload' => function () { global $modSettings, $context, $txt, $cur_profile; $context['member']['smiley_set']['id'] = empty($cur_profile['smiley_set']) ? '' : $cur_profile['smiley_set']; $context['smiley_sets'] = explode(',', 'none,,' . $modSettings['smiley_sets_known']); $set_names = explode("\n", $txt['smileys_none'] . "\n" . $txt['smileys_forum_board_default'] . "\n" . $modSettings['smiley_sets_names']); foreach ($context['smiley_sets'] as $i => $set) { $context['smiley_sets'][$i] = array('id' => htmlspecialchars($set), 'name' => htmlspecialchars($set_names[$i]), 'selected' => $set == $context['member']['smiley_set']['id']); if ($context['smiley_sets'][$i]['selected']) { $context['member']['smiley_set']['name'] = $set_names[$i]; } } return true; }, 'input_validate' => function (&$value) { global $modSettings; $smiley_sets = explode(',', $modSettings['smiley_sets_known']); if (!in_array($value, $smiley_sets) && $value != 'none') { $value = ''; } return true; }), 'theme_settings' => array('type' => 'callback_template', 'callback_name' => 'profile/theme_settings', 'permission' => 'profile_extra', 'is_dummy' => true, 'preload' => function () { loadLanguage('Settings'); return true; }), 'time_format' => array('type' => 'callback_template', 'callback_name' => 'profile/timeformat_modify', 'permission' => 'profile_extra', 'preload' => function () { global $context, $user_info, $txt, $cur_profile, $modSettings; $context['easy_timeformats'] = array(array('format' => '', 'title' => $txt['timeformat_default']), array('format' => '%B %d, %Y, %I:%M:%S %p', 'title' => $txt['timeformat_easy1']), array('format' => '%B %d, %Y, %H:%M:%S', 'title' => $txt['timeformat_easy2']), array('format' => '%Y-%m-%d, %H:%M:%S', 'title' => $txt['timeformat_easy3']), array('format' => '%d %B %Y, %H:%M:%S', 'title' => $txt['timeformat_easy4']), array('format' => '%d-%m-%Y, %H:%M:%S', 'title' => $txt['timeformat_easy5'])); $context['member']['time_format'] = $cur_profile['time_format']; $context['current_forum_time'] = strftime($modSettings['time_format'], forum_time(false)) . ' ' . date_default_timezone_get(); $context['current_forum_time_js'] = strftime('%Y,' . ((int) strftime('%m', time() + $modSettings['time_offset'] * 3600) - 1) . ',%d,%H,%M,%S', time() + $modSettings['time_offset'] * 3600); $context['current_forum_time_hour'] = (int) strftime('%H', forum_time(false)); return true; }), 'time_offset' => array('type' => 'callback_template', 'callback_name' => 'profile/timeoffset_modify', 'permission' => 'profile_extra', 'preload' => function () { global $context, $cur_profile; $context['member']['time_offset'] = $cur_profile['time_offset']; return true; }, 'input_validate' => function (&$value) { // Validate the time_offset... $value = (double) strtr($value, ',', '.'); if ($value < -23.5 || $value > 23.5) { return 'bad_offset'; } return true; }), 'usertitle' => array('type' => 'text', 'label' => $txt['custom_title'], 'log_change' => true, 'size' => 50, 'permission' => 'profile_title', 'input_attr' => array('maxlength="50"'), 'enabled' => !empty($modSettings['titlesEnable']))); $disabled_fields = !empty($modSettings['disabled_profile_fields']) ? explode(',', $modSettings['disabled_profile_fields']) : array(); // For each of the above let's take out the bits which don't apply - to save memory and security! foreach ($profile_fields as $key => $field) { // Do we have permission to do this? if (isset($field['permission']) && !allowedTo($context['user']['is_owner'] ? array($field['permission'] . '_own', $field['permission'] . '_any') : $field['permission'] . '_any') && !allowedTo($field['permission'])) { unset($profile_fields[$key]); } // Is it enabled? if (isset($field['enabled']) && !$field['enabled']) { unset($profile_fields[$key]); } // Is it specifically disabled? if (in_array($key, $disabled_fields) || isset($field['link_with']) && in_array($field['link_with'], $disabled_fields)) { unset($profile_fields[$key]); } } }
$password = $_POST['password']; $names = $_POST['names']; $emails = $_POST['emails']; $msg = $_POST['msg']; $gateway = new ValidationCodeGateway(); if ($password != 'Evgeny') { die('Invalid Password'); } echo "Validation codes are sent to following addresses: <br/>"; $i = -1; foreach ($emails as $email) { $i++; if (empty($email)) { continue; } $validationCode = generateValidationCode(15); $gateway->insertValidationCode($email, $validationCode); $vars = array("@@name@@", "@@email@@", "@@validationCode@@"); $vals = array($names[$i], $email, $validationCode); $newMsg = str_replace($vars, $vals, $msg); sendValidationCode($email, $validationCode, $newMsg); echo "{$email} <br/>"; } function generateValidationCode($length) { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, strlen($characters) - 1)]; } return $randomString;
/** * Registers a member to the forum. * * What it does: * - Allows two types of interface: 'guest' and 'admin'. The first * - includes hammering protection, the latter can perform the registration silently. * - The strings used in the options array are assumed to be escaped. * - Allows to perform several checks on the input, e.g. reserved names. * - The function will adjust member statistics. * - If an error is detected will fatal error on all errors unless return_errors is true. * * @package Members * @uses Auth.subs.php * @uses Mail.subs.php * @param mixed[] $regOptions * @param string $error_context * @return integer the ID of the newly created member */ function registerMember(&$regOptions, $error_context = 'register') { global $scripturl, $txt, $modSettings, $user_info; $db = database(); loadLanguage('Login'); // We'll need some external functions. require_once SUBSDIR . '/Auth.subs.php'; require_once SUBSDIR . '/Mail.subs.php'; // Put any errors in here. $reg_errors = Error_Context::context($error_context, 0); // Registration from the admin center, let them sweat a little more. if ($regOptions['interface'] == 'admin') { is_not_guest(); isAllowedTo('moderate_forum'); } elseif ($regOptions['interface'] == 'guest') { // You cannot register twice... if (empty($user_info['is_guest'])) { redirectexit(); } // Make sure they didn't just register with this session. if (!empty($_SESSION['just_registered']) && empty($modSettings['disableRegisterCheck'])) { fatal_lang_error('register_only_once', false); } } // What method of authorization are we going to use? if (empty($regOptions['auth_method']) || !in_array($regOptions['auth_method'], array('password', 'openid'))) { if (!empty($regOptions['openid'])) { $regOptions['auth_method'] = 'openid'; } else { $regOptions['auth_method'] = 'password'; } } // Spaces and other odd characters are evil... $regOptions['username'] = trim(preg_replace('~[\\t\\n\\r \\x0B\\0\\x{A0}\\x{AD}\\x{2000}-\\x{200F}\\x{201F}\\x{202F}\\x{3000}\\x{FEFF}]+~u', ' ', $regOptions['username'])); // Valid emails only require_once SUBSDIR . '/DataValidator.class.php'; if (!Data_Validator::is_valid($regOptions, array('email' => 'valid_email|required|max_length[255]'), array('email' => 'trim'))) { $reg_errors->addError('bad_email'); } validateUsername(0, $regOptions['username'], $error_context, !empty($regOptions['check_reserved_name'])); // Generate a validation code if it's supposed to be emailed. $validation_code = ''; if ($regOptions['require'] == 'activation') { $validation_code = generateValidationCode(); } // If you haven't put in a password generate one. if ($regOptions['interface'] == 'admin' && $regOptions['password'] == '' && $regOptions['auth_method'] == 'password') { mt_srand(time() + 1277); $regOptions['password'] = generateValidationCode(); $regOptions['password_check'] = $regOptions['password']; } elseif ($regOptions['password'] != $regOptions['password_check'] && $regOptions['auth_method'] == 'password') { $reg_errors->addError('passwords_dont_match'); } // That's kind of easy to guess... if ($regOptions['password'] == '') { if ($regOptions['auth_method'] == 'password') { $reg_errors->addError('no_password'); } else { $regOptions['password'] = sha1(mt_rand()); } } // Now perform hard password validation as required. if (!empty($regOptions['check_password_strength']) && $regOptions['password'] != '') { $passwordError = validatePassword($regOptions['password'], $regOptions['username'], array($regOptions['email'])); // Password isn't legal? if ($passwordError != null) { $reg_errors->addError('profile_error_password_' . $passwordError); } } // You may not be allowed to register this email. if (!empty($regOptions['check_email_ban'])) { isBannedEmail($regOptions['email'], 'cannot_register', $txt['ban_register_prohibited']); } // Check if the email address is in use. $request = $db->query('', ' SELECT id_member FROM {db_prefix}members WHERE email_address = {string:email_address} OR email_address = {string:username} LIMIT 1', array('email_address' => $regOptions['email'], 'username' => $regOptions['username'])); if ($db->num_rows($request) != 0) { $reg_errors->addError(array('email_in_use', array(htmlspecialchars($regOptions['email'], ENT_COMPAT, 'UTF-8')))); } $db->free_result($request); // Perhaps someone else wants to check this user call_integration_hook('integrate_register_check', array(&$regOptions, &$reg_errors)); // If there's any errors left return them at once! if ($reg_errors->hasErrors()) { return false; } $reservedVars = array('actual_theme_url', 'actual_images_url', 'base_theme_dir', 'base_theme_url', 'default_images_url', 'default_theme_dir', 'default_theme_url', 'default_template', 'images_url', 'number_recent_posts', 'smiley_sets_default', 'theme_dir', 'theme_id', 'theme_layers', 'theme_templates', 'theme_url'); // Can't change reserved vars. if (isset($regOptions['theme_vars']) && count(array_intersect(array_keys($regOptions['theme_vars']), $reservedVars)) != 0) { fatal_lang_error('no_theme'); } // New password hash require_once SUBSDIR . '/Auth.subs.php'; // Some of these might be overwritten. (the lower ones that are in the arrays below.) $regOptions['register_vars'] = array('member_name' => $regOptions['username'], 'email_address' => $regOptions['email'], 'passwd' => validateLoginPassword($regOptions['password'], '', $regOptions['username'], true), 'password_salt' => substr(md5(mt_rand()), 0, 4), 'posts' => 0, 'date_registered' => !empty($regOptions['time']) ? $regOptions['time'] : time(), 'member_ip' => $regOptions['interface'] == 'admin' ? '127.0.0.1' : $regOptions['ip'], 'member_ip2' => $regOptions['interface'] == 'admin' ? '127.0.0.1' : $regOptions['ip2'], 'validation_code' => $validation_code, 'real_name' => $regOptions['username'], 'personal_text' => $modSettings['default_personal_text'], 'pm_email_notify' => 1, 'id_theme' => 0, 'id_post_group' => 4, 'lngfile' => '', 'buddy_list' => '', 'pm_ignore_list' => '', 'message_labels' => '', 'website_title' => '', 'website_url' => '', 'location' => '', 'time_format' => '', 'signature' => '', 'avatar' => '', 'usertitle' => '', 'secret_question' => '', 'secret_answer' => '', 'additional_groups' => '', 'ignore_boards' => '', 'smiley_set' => '', 'openid_uri' => !empty($regOptions['openid']) ? $regOptions['openid'] : ''); // Setup the activation status on this new account so it is correct - firstly is it an under age account? if ($regOptions['require'] == 'coppa') { $regOptions['register_vars']['is_activated'] = 5; // @todo This should be changed. To what should be it be changed?? $regOptions['register_vars']['validation_code'] = ''; } elseif ($regOptions['require'] == 'nothing') { $regOptions['register_vars']['is_activated'] = 1; } elseif ($regOptions['require'] == 'activation') { $regOptions['register_vars']['is_activated'] = 0; } else { $regOptions['register_vars']['is_activated'] = 3; } if (isset($regOptions['memberGroup'])) { // Make sure the id_group will be valid, if this is an administator. $regOptions['register_vars']['id_group'] = $regOptions['memberGroup'] == 1 && !allowedTo('admin_forum') ? 0 : $regOptions['memberGroup']; // Check if this group is assignable. $unassignableGroups = array(-1, 3); $request = $db->query('', ' SELECT id_group FROM {db_prefix}membergroups WHERE min_posts != {int:min_posts}' . (allowedTo('admin_forum') ? '' : ' OR group_type = {int:is_protected}'), array('min_posts' => -1, 'is_protected' => 1)); while ($row = $db->fetch_assoc($request)) { $unassignableGroups[] = $row['id_group']; } $db->free_result($request); if (in_array($regOptions['register_vars']['id_group'], $unassignableGroups)) { $regOptions['register_vars']['id_group'] = 0; } } // Integrate optional member settings to be set. if (!empty($regOptions['extra_register_vars'])) { foreach ($regOptions['extra_register_vars'] as $var => $value) { $regOptions['register_vars'][$var] = $value; } } // Integrate optional user theme options to be set. $theme_vars = array(); if (!empty($regOptions['theme_vars'])) { foreach ($regOptions['theme_vars'] as $var => $value) { $theme_vars[$var] = $value; } } // Right, now let's prepare for insertion. $knownInts = array('date_registered', 'posts', 'id_group', 'last_login', 'personal_messages', 'unread_messages', 'notifications', 'new_pm', 'pm_prefs', 'gender', 'hide_email', 'show_online', 'pm_email_notify', 'karma_good', 'karma_bad', 'notify_announcements', 'notify_send_body', 'notify_regularity', 'notify_types', 'id_theme', 'is_activated', 'id_msg_last_visit', 'id_post_group', 'total_time_logged_in', 'warning'); $knownFloats = array('time_offset'); // Call an optional function to validate the users' input. call_integration_hook('integrate_register', array(&$regOptions, &$theme_vars, &$knownInts, &$knownFloats)); $column_names = array(); $values = array(); foreach ($regOptions['register_vars'] as $var => $val) { $type = 'string'; if (in_array($var, $knownInts)) { $type = 'int'; } elseif (in_array($var, $knownFloats)) { $type = 'float'; } elseif ($var == 'birthdate') { $type = 'date'; } $column_names[$var] = $type; $values[$var] = $val; } // Register them into the database. $db->insert('', '{db_prefix}members', $column_names, $values, array('id_member')); $memberID = $db->insert_id('{db_prefix}members', 'id_member'); // Update the number of members and latest member's info - and pass the name, but remove the 's. if ($regOptions['register_vars']['is_activated'] == 1) { updateMemberStats($memberID, $regOptions['register_vars']['real_name']); } else { updateMemberStats(); } // Theme variables too? if (!empty($theme_vars)) { $inserts = array(); foreach ($theme_vars as $var => $val) { $inserts[] = array($memberID, $var, $val); } $db->insert('insert', '{db_prefix}themes', array('id_member' => 'int', 'variable' => 'string-255', 'value' => 'string-65534'), $inserts, array('id_member', 'variable')); } // If it's enabled, increase the registrations for today. trackStats(array('registers' => '+')); // Administrative registrations are a bit different... if ($regOptions['interface'] == 'admin') { if ($regOptions['require'] == 'activation') { $email_message = 'admin_register_activate'; } elseif (!empty($regOptions['send_welcome_email'])) { $email_message = 'admin_register_immediate'; } if (isset($email_message)) { $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $memberID, 'ACTIVATIONCODE' => $validation_code); $emaildata = loadEmailTemplate($email_message, $replacements); sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } } else { // Can post straight away - welcome them to your fantastic community... if ($regOptions['require'] == 'nothing') { if (!empty($regOptions['send_welcome_email'])) { $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : ''); $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . 'immediate', $replacements); sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } // Send admin their notification. require_once SUBSDIR . '/Notification.subs.php'; sendAdminNotifications('standard', $memberID, $regOptions['username']); } elseif ($regOptions['require'] == 'activation' || $regOptions['require'] == 'coppa') { $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : ''); if ($regOptions['require'] == 'activation') { $replacements += array('ACTIVATIONLINK' => $scripturl . '?action=activate;u=' . $memberID . ';code=' . $validation_code, 'ACTIVATIONLINKWITHOUTCODE' => $scripturl . '?action=activate;u=' . $memberID, 'ACTIVATIONCODE' => $validation_code); } else { $replacements += array('COPPALINK' => $scripturl . '?action=coppa;u=' . $memberID); } $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . ($regOptions['require'] == 'activation' ? 'activate' : 'coppa'), $replacements); sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); } else { $replacements = array('REALNAME' => $regOptions['register_vars']['real_name'], 'USERNAME' => $regOptions['username'], 'PASSWORD' => $regOptions['password'], 'FORGOTPASSWORDLINK' => $scripturl . '?action=reminder', 'OPENID' => !empty($regOptions['openid']) ? $regOptions['openid'] : ''); $emaildata = loadEmailTemplate('register_' . ($regOptions['auth_method'] == 'openid' ? 'openid_' : '') . 'pending', $replacements); sendmail($regOptions['email'], $emaildata['subject'], $emaildata['body'], null, null, false, 0); // Admin gets informed here... require_once SUBSDIR . '/Notification.subs.php'; sendAdminNotifications('approval', $memberID, $regOptions['username']); } // Okay, they're for sure registered... make sure the session is aware of this for security. (Just married :P!) $_SESSION['just_registered'] = 1; } // If they are for sure registered, let other people to know about it call_integration_hook('integrate_register_after', array($regOptions, $memberID)); return $memberID; }
public function action_register2() { global $txt, $modSettings, $context, $user_info; // Start collecting together any errors. $reg_errors = Error_Context::context('register', 0); // Check they are who they should be checkSession(); if (!validateToken('register', 'post', true, false)) { $reg_errors->addError('token_verification'); } // You can't register if it's disabled. if (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 3) { fatal_lang_error('registration_disabled', false); } // Well, if you don't agree, you can't register. if (!empty($modSettings['requireAgreement']) && !isset($_POST['checkbox_agreement'])) { $reg_errors->addError('agreement_unchecked'); } // Make sure they came from *somewhere*, have a session. if (!isset($_SESSION['old_url'])) { redirectexit('action=register'); } // Check their provider deatils match up correctly in case they're pulling something funny if ($_POST['provider'] != $_SESSION['extauth_info']['provider']) { redirectexit('action=register'); } // Clean up foreach ($_POST as $key => $value) { if (!is_array($_POST[$key])) { $_POST[$key] = htmltrim__recursive(str_replace(array("\n", "\r"), '', $_POST[$key])); } } // Needed for isReservedName() and registerMember() require_once SUBSDIR . '/Members.subs.php'; // Needed for generateValidationCode() require_once SUBSDIR . '/Auth.subs.php'; // Set the options needed for registration. $regOptions = array('interface' => 'guest', 'username' => !empty($_POST['user']) ? $_POST['user'] : '', 'email' => !empty($_POST['email']) ? $_POST['email'] : '', 'check_reserved_name' => true, 'check_password_strength' => true, 'check_email_ban' => true, 'send_welcome_email' => !empty($modSettings['send_welcomeEmail']), 'require' => empty($modSettings['registration_method']) ? 'nothing' : ($modSettings['registration_method'] == 1 ? 'activation' : 'approval')); // Lets check for other errors before trying to register the member. if ($reg_errors->hasErrors()) { return $this->action_register(); } mt_srand(time() + 1277); $regOptions['password'] = generateValidationCode(); $regOptions['password_check'] = $regOptions['password']; // Registration needs to know your IP $req = request(); $regOptions['ip'] = $user_info['ip']; $regOptions['ip2'] = $req->ban_ip(); $memberID = registerMember($regOptions, 'register'); // If there are "important" errors and you are not an admin: log the first error // Otherwise grab all of them and don't log anything if ($reg_errors->hasErrors(1) && !$user_info['is_admin']) { foreach ($reg_errors->prepareErrors(1) as $error) { fatal_error($error, 'general'); } } // One last error check if ($reg_errors->hasErrors()) { return $this->action_register(); } // Do our spam protection now. spamProtection('register'); // Since all is well, we'll go ahead and associate the member's external account addAuth($memberID, $_SESSION['extauth_info']['provider'], $_SESSION['extauth_info']['uid'], $_SESSION['extauth_info']['name']); // Basic template variable setup. if (!empty($modSettings['registration_method'])) { loadTemplate('Register'); $context += array('page_title' => $txt['register'], 'title' => $txt['registration_successful'], 'sub_template' => 'after', 'description' => $modSettings['registration_method'] == 2 ? $txt['approval_after_registration'] : $txt['activate_after_registration']); } else { call_integration_hook('integrate_activate', array($regOptions['username'])); setLoginCookie(60 * $modSettings['cookieTime'], $memberID, hash('sha256', Util::strtolower($regOptions['username']) . $regOptions['password'] . $regOptions['register_vars']['password_salt'])); redirectexit('action=auth;sa=check;member=' . $memberID, $context['server']['needs_login_fix']); } }