function MaintainPurgeInactiveMembers() { global $sourcedir, $context, $smcFunc, $txt; $_POST['maxdays'] = empty($_POST['maxdays']) ? 0 : (int) $_POST['maxdays']; if (!empty($_POST['groups']) && $_POST['maxdays'] > 0) { checkSession(); $groups = array(); foreach ($_POST['groups'] as $id => $dummy) { $groups[] = (int) $id; } $time_limit = time() - $_POST['maxdays'] * 24 * 3600; $where_vars = array('time_limit' => $time_limit); if ($_POST['del_type'] == 'activated') { $where = 'mem.date_registered < {int:time_limit} AND mem.is_activated = {int:is_activated}'; $where_vars['is_activated'] = 0; } else { $where = 'mem.last_login < {int:time_limit}'; } // Need to get *all* groups then work out which (if any) we avoid. $request = $smcFunc['db_query']('', ' SELECT id_group, group_name, min_posts FROM {db_prefix}membergroups', array()); while ($row = $smcFunc['db_fetch_assoc']($request)) { // Avoid this one? if (!in_array($row['id_group'], $groups)) { // Post group? if ($row['min_posts'] != -1) { $where .= ' AND mem.id_post_group != {int:id_post_group_' . $row['id_group'] . '}'; $where_vars['id_post_group_' . $row['id_group']] = $row['id_group']; } else { $where .= ' AND mem.id_group != {int:id_group_' . $row['id_group'] . '} AND FIND_IN_SET({int:id_group_' . $row['id_group'] . '}, mem.additional_groups) = 0'; $where_vars['id_group_' . $row['id_group']] = $row['id_group']; } } } $smcFunc['db_free_result']($request); // If we have ungrouped unselected we need to avoid those guys. if (!in_array(0, $groups)) { $where .= ' AND (mem.id_group != 0 OR mem.additional_groups != {string:blank_add_groups})'; $where_vars['blank_add_groups'] = ''; } // Select all the members we're about to murder/remove... $request = $smcFunc['db_query']('', ' SELECT mem.id_member, IFNULL(m.id_member, 0) AS is_mod FROM {db_prefix}members AS mem LEFT JOIN {db_prefix}moderators AS m ON (m.id_member = mem.id_member) WHERE ' . $where, $where_vars); $members = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { if (!$row['is_mod'] || !in_array(3, $groups)) { $members[] = $row['id_member']; } } $smcFunc['db_free_result']($request); require_once $sourcedir . '/Subs-Members.php'; deleteMembers($members); } $context['maintenance_finished'] = $txt['maintain_members']; }
/** * Activate an account. * This function is called from the profile account actions area. */ public function action_activateaccount() { global $context, $user_profile, $modSettings; isAllowedTo('moderate_forum'); $memID = currentMemberID(); if (isset($_REQUEST['save']) && isset($user_profile[$memID]['is_activated']) && $user_profile[$memID]['is_activated'] != 1) { require_once SUBSDIR . '/Members.subs.php'; // If we are approving the deletion of an account, we do something special ;) if ($user_profile[$memID]['is_activated'] == 4) { deleteMembers($context['id_member']); redirectexit(); } // Actually update this member now, as it guarantees the unapproved count can't get corrupted. approveMembers(array('members' => array($context['id_member']), 'activated_status' => $user_profile[$memID]['is_activated'])); // Log what we did? logAction('approve_member', array('member' => $memID), 'admin'); // If we are doing approval, update the stats for the member just in case. if (in_array($user_profile[$memID]['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); } // Leave it be... redirectexit('action=profile;u=' . $memID . ';area=summary'); }
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 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 deleteAccount2($profile_vars, $post_errors, $memID) { global $user_info, $sourcedir, $context, $cur_profile, $modSettings, $smcFunc; // Try get more time... @set_time_limit(600); // !!! Add a way to delete pms as well? if (!$context['user']['is_owner']) { isAllowedTo('profile_remove_any'); } elseif (!allowedTo('profile_remove_any')) { isAllowedTo('profile_remove_own'); } checkSession(); $old_profile =& $cur_profile; // Too often, people remove/delete their own only account. if (in_array(1, explode(',', $old_profile['additional_groups'])) || $old_profile['id_group'] == 1) { // Are you allowed to administrate the forum, as they are? isAllowedTo('admin_forum'); $request = $smcFunc['db_query']('', ' SELECT id_member FROM {db_prefix}members WHERE (id_group = {int:admin_group} OR FIND_IN_SET({int:admin_group}, additional_groups) != 0) AND id_member != {int:selected_member} LIMIT 1', array('admin_group' => 1, 'selected_member' => $memID)); list($another) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); if (empty($another)) { fatal_lang_error('at_least_one_admin', 'critical'); } } // This file is needed for the deleteMembers function. require_once $sourcedir . '/Subs-Members.php'; // Do you have permission to delete others profiles, or is that your profile you wanna delete? if ($memID != $user_info['id']) { isAllowedTo('profile_remove_any'); // Now, have you been naughty and need your posts deleting? // !!! Should this check board permissions? if ($_POST['remove_type'] != 'none' && allowedTo('moderate_forum')) { // Include RemoveTopics - essential for this type of work! require_once $sourcedir . '/RemoveTopic.php'; // First off we delete any topics the member has started - if they wanted topics being done. if ($_POST['remove_type'] == 'topics') { // Fetch all topics started by this user within the time period. $request = $smcFunc['db_query']('', ' SELECT t.id_topic FROM {db_prefix}topics AS t WHERE t.id_member_started = {int:selected_member}', array('selected_member' => $memID)); $topicIDs = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $topicIDs[] = $row['id_topic']; } $smcFunc['db_free_result']($request); // Actually remove the topics. // !!! This needs to check permissions, but we'll let it slide for now because of moderate_forum already being had. removeTopics($topicIDs); } // Now delete the remaining messages. $request = $smcFunc['db_query']('', ' SELECT m.id_msg FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic AND t.id_first_msg != m.id_msg) WHERE m.id_member = {int:selected_member}', array('selected_member' => $memID)); // This could take a while... but ya know it's gonna be worth it in the end. while ($row = $smcFunc['db_fetch_assoc']($request)) { if (function_exists('apache_reset_timeout')) { @apache_reset_timeout(); } removeMessage($row['id_msg']); } $smcFunc['db_free_result']($request); } // Only delete this poor members account if they are actually being booted out of camp. if (isset($_POST['deleteAccount'])) { deleteMembers($memID); } } elseif (empty($post_errors) && !empty($modSettings['approveAccountDeletion']) && !allowedTo('moderate_forum')) { // Setup their account for deletion ;) updateMemberData($memID, array('is_activated' => 4)); // Another account needs approval... updateSettings(array('unapprovedMembers' => true), true); } elseif (empty($post_errors)) { deleteMembers($memID); require_once $sourcedir . '/LogInOut.php'; LogOut(true); redirectExit(); } }
function deleteAccount2($profile_vars, $post_errors, $memID) { global $ID_MEMBER, $user_info, $sourcedir, $context, $db_prefix, $user_profile, $modSettings; // !!! Add a way to delete pms as well? if (!$context['user']['is_owner']) { isAllowedTo('profile_remove_any'); } elseif (!allowedTo('profile_remove_any')) { isAllowedTo('profile_remove_own'); } checkSession(); $old_profile =& $user_profile[$memID]; // Too often, people remove/delete their own only account. if (in_array(1, explode(',', $old_profile['additionalGroups'])) || $old_profile['ID_GROUP'] == 1) { // Are you allowed to administrate the forum, as they are? isAllowedTo('admin_forum'); $request = db_query("\n\t\t\tSELECT ID_MEMBER\n\t\t\tFROM {$db_prefix}members\n\t\t\tWHERE (ID_GROUP = 1 OR FIND_IN_SET(1, additionalGroups))\n\t\t\t\tAND ID_MEMBER != {$memID}\n\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'); } } // This file is needed for the deleteMembers function. require_once $sourcedir . '/Subs-Members.php'; // Do you have permission to delete others profiles, or is that your profile you wanna delete? if ($memID != $ID_MEMBER) { isAllowedTo('profile_remove_any'); // Now, have you been naughty and need your posts deleting? // !!! Should this check board permissions? if ($_POST['remove_type'] != 'none' && allowedTo('moderate_forum')) { // Include RemoveTopics - essential for this type of work! require_once $sourcedir . '/RemoveTopic.php'; // First off we delete any topics the member has started - if they wanted topics being done. if ($_POST['remove_type'] == 'topics') { // Fetch all topics started by this user within the time period. $request = db_query("\n\t\t\t\t\tSELECT t.ID_TOPIC\n\t\t\t\t\tFROM {$db_prefix}topics AS t\n\t\t\t\t\tWHERE t.ID_MEMBER_STARTED = {$memID}", __FILE__, __LINE__); $topicIDs = array(); while ($row = mysql_fetch_assoc($request)) { $topicIDs[] = $row['ID_TOPIC']; } mysql_free_result($request); // Actually remove the topics. // !!! This needs to check permissions, but we'll let it slide for now because of moderate_forum already being had. removeTopics($topicIDs); } // Now delete the remaining messages. $request = db_query("\n\t\t\t\tSELECT m.ID_MSG\n\t\t\t\tFROM ({$db_prefix}messages AS m, {$db_prefix}topics AS t)\n\t\t\t\tWHERE m.ID_MEMBER = {$memID}\n\t\t\t\t\tAND m.ID_TOPIC = t.ID_TOPIC\n\t\t\t\t\tAND t.ID_FIRST_MSG != m.ID_MSG", __FILE__, __LINE__); // This could take a while... but ya know it's gonna be worth it in the end. while ($row = mysql_fetch_assoc($request)) { removeMessage($row['ID_MSG']); } mysql_free_result($request); } // Only delete this poor members account if they are actually being booted out of camp. if (isset($_POST['deleteAccount'])) { deleteMembers($memID); } } elseif (empty($post_errors) && !empty($modSettings['approveAccountDeletion']) && !allowedTo('moderate_forum')) { // Setup their account for deletion ;) updateMemberData($memID, array('is_activated' => 4)); // Another account needs approval... updateSettings(array('unapprovedMembers' => true), true); } elseif (empty($post_errors)) { deleteMembers($memID); } }
/** * 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 merge_char_accounts($source, $dest) { global $user_profile, $sourcedir, $smcFunc; if ($source == $dest) { return 'no_same'; } $loaded = loadMemberData(array($source, $dest)); if (!in_array($source, $loaded) || !in_array($dest, $loaded)) { return 'no_exist'; } if ($user_profile[$source]['id_group'] == 1 || in_array('1', explode(',', $user_profile[$source]['additional_groups']))) { return 'no_merge_admin'; } // Work out which the main characters are. $source_main = 0; $dest_main = 0; foreach ($user_profile[$source]['characters'] as $id_char => $char) { if ($char['is_main']) { $source_main = $id_char; break; } } foreach ($user_profile[$dest]['characters'] as $id_char => $char) { if ($char['is_main']) { $dest_main = $id_char; break; } } if (empty($source_main) || empty($dest_main)) { return 'no_main'; } // Move characters $smcFunc['db_query']('', ' UPDATE {db_prefix}characters SET id_member = {int:dest} WHERE id_member = {int:source} AND id_character != {int:source_main}', array('source' => $source, 'source_main' => $source_main, 'dest' => $dest, 'dest_main' => $dest_main)); // Move posts over - main $smcFunc['db_query']('', ' UPDATE {db_prefix}messages SET id_member = {int:dest}, id_character = {int:dest_main} WHERE id_member = {int:source} AND id_character = {int:source_main}', array('source' => $source, 'source_main' => $source_main, 'dest' => $dest, 'dest_main' => $dest_main)); // Move posts over - characters (i.e. whatever's left) $smcFunc['db_query']('', ' UPDATE {db_prefix}messages SET id_member = {int:dest} WHERE id_member = {int:source}', array('source' => $source, 'dest' => $dest)); // Fix post counts of destination accounts $total_posts = 0; foreach ($user_profile[$source]['characters'] as $char) { $total_posts += $char['posts']; } if (!empty($total_posts)) { updateMemberData($dest, array('posts' => 'posts + ' . $total_posts)); } if (!empty($user_profile[$source]['characters'][$source_main]['posts'])) { updateCharacterData($dest_main, array('posts' => 'posts + ' . $user_profile[$source]['characters'][$source_main]['posts'])); } // Reassign topics $smcFunc['db_query']('', ' UPDATE {db_prefix}topics SET id_member_started = {int:dest} WHERE id_member_started = {int:source}', array('source' => $source, 'dest' => $dest)); $smcFunc['db_query']('', ' UPDATE {db_prefix}topics SET id_member_updated = {int:dest} WHERE id_member_updated = {int:source}', array('source' => $source, 'dest' => $dest)); // Move PMs - sent items $smcFunc['db_query']('', ' UPDATE {db_prefix}personal_messages SET id_member_from = {int:dest} WHERE id_member_from = {int:source}', array('source' => $source, 'dest' => $dest)); // Move PMs - received items // First we have to get all the existing recipient rows $rows = []; $request = $smcFunc['db_query']('', ' SELECT id_pm, bcc, is_read, is_new, deleted FROM {db_prefix}pm_recipients WHERE id_member = {int:source}', array('source' => $source)); while ($row = $smcFunc['db_fetch_assoc']($request)) { $rows[] = array('id_pm' => $row['id_pm'], 'id_member' => $dest, 'bcc' => $row['bcc'], 'is_read' => $row['is_read'], 'is_new' => $row['is_new'], 'deleted' => $row['deleted'], 'is_inbox' => 1); } $smcFunc['db_free_result']($request); if (!empty($rows)) { $smcFunc['db_insert']('ignore', '{db_prefix}pm_recipients', array('id_pm' => 'int', 'id_member' => 'int', 'bcc' => 'int', 'is_read' => 'int', 'is_new' => 'int', 'deleted' => 'int', 'is_inbox' => 'int'), $rows, array('id_pm', 'id_member')); } // Delete the source user require_once $sourcedir . '/Subs-Members.php'; deleteMembers($source); return true; }
/** * Removing old and inactive members. */ public function action_purgeinactive_display() { global $context, $txt; checkSession(); validateToken('admin-maint'); require_once SUBSDIR . '/DataValidator.class.php'; // Start with checking and cleaning what was sent $validator = new Data_Validator(); $validator->sanitation_rules(array('maxdays' => 'intval')); $validator->validation_rules(array('maxdays' => 'required', 'groups' => 'isarray', 'del_type' => 'required')); // Validator says, you can pass or not if ($validator->validate($_POST)) { require_once SUBSDIR . '/Maintenance.subs.php'; require_once SUBSDIR . '/Members.subs.php'; $groups = array(); foreach ($validator->groups as $id => $dummy) { $groups[] = (int) $id; } $time_limit = time() - $validator->maxdays * 24 * 3600; $members = purgeMembers($validator->type, $groups, $time_limit); deleteMembers($members); $context['maintenance_finished'] = array('errors' => array(sprintf($txt['maintain_done'], $txt['maintain_members']))); } else { $context['maintenance_finished'] = array('errors' => $validator->validation_errors(), 'type' => 'minor'); } }