'AddMembergroup', 'delete' => 'DeleteMembergroup', 'edit' => 'EditMembergroup', 'members' => 'MembergroupMembers' ); if (isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']])) { $sa = $subActions[$_REQUEST['sa']]; unset($subActions); $sa(); } else MembergroupIndex(); } function MembergroupIndex() { global $db_prefix, $txt, $scripturl, $context, $settings; $context['page_title'] = $txt['membergroups_title']; $query = db_query(" SELECT mg.ID_GROUP, mg.groupName, mg.minPosts, mg.onlineColor, mg.stars, COUNT(mem.ID_MEMBER) AS num_members FROM {$db_prefix}membergroups AS mg LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_GROUP = mg.ID_GROUP OR FIND_IN_SET(mg.ID_GROUP, mem.additionalGroups) OR mg.ID_GROUP = mem.ID_POST_GROUP) GROUP BY mg.ID_GROUP ORDER BY mg.minPosts, IF(mg.ID_GROUP < 4, mg.ID_GROUP, 4), mg.groupName", __FILE__, __LINE__); $context['groups'] = array( 'regular' => array(), 'post' => array() ); while ($row = mysql_fetch_assoc($query)) { $row['stars'] = explode('#', $row['stars']); $context['groups'][$row['minPosts'] == -1 ? 'regular' : 'post'][$row['ID_GROUP']] = array( 'id' => $row['ID_GROUP'], 'name' => $row['groupName'], 'num_members' => $row['ID_GROUP'] != 3 ? $row['num_members'] : $txt['membergroups_guests_na'], 'allow_delete' => $row['ID_GROUP'] > 4, 'can_search' => $row['ID_GROUP'] != 3, 'href' => $scripturl . '?action=membergroups;sa=members;id=' . $row['ID_GROUP'], 'link' => '' . $row['num_members'] . '', 'is_post_group' => $row['minPosts'] != -1, 'min_posts' => $row['minPosts'] == -1 ? '-' : $row['minPosts'], 'color' => empty($row['onlineColor']) ? '' : $row['onlineColor'], 'stars' => !empty($row['stars'][0]) && !empty($row['stars'][1]) ? str_repeat('*', $row['stars'][0]) : '', 'last_group' => false ); } mysql_free_result($query); $request = db_query(" SELECT COUNT(ID_MEMBER) FROM {$db_prefix}members WHERE ID_GROUP = 0", __FILE__, __LINE__); list ($num_members) = mysql_fetch_row($request); mysql_free_result($request); $context['groups'][count($context['groups']) - 1]['last_group'] = true; } function AddMembergroup() { global $db_prefix, $context, $txt, $sourcedir; if (empty($_POST['group_name'])) { $context['page_title'] = $txt['membergroups_new_group']; $context['sub_template'] = 'new_group'; $context['postgroup'] = !empty($_POST['postgroup']); $result = db_query(" SELECT ID_GROUP, groupName FROM {$db_prefix}membergroups WHERE ID_GROUP > 3 OR ID_GROUP = 2 ORDER BY minPosts, ID_GROUP != 2, groupName", __FILE__, __LINE__); $context['groups'] = array(); while ($row = mysql_fetch_assoc($result)) $context['groups'][] = array( 'id' => $row['ID_GROUP'], 'name' => $row['groupName'] ); mysql_free_result($result); $result = db_query(" SELECT ID_BOARD, name, childLevel FROM {$db_prefix}boards ORDER BY boardOrder", __FILE__, __LINE__); $context['boards'] = array(); while ($row = mysql_fetch_assoc($result)) $context['boards'][] = array( 'id' => $row['ID_BOARD'], 'name' => $row['name'], 'child_level' => $row['childLevel'], 'selected' => false ); mysql_free_result($result); return; } checkSession(); $request = db_query(" SELECT groupName FROM {$db_prefix}membergroups WHERE groupName = '$_POST[group_name]' LIMIT 1", __FILE__, __LINE__); if (mysql_num_rows($request) != 0) redirectexit('action=membergroups;'); mysql_free_result($request); $request = db_query(" SELECT MAX(ID_GROUP) FROM {$db_prefix}membergroups", __FILE__, __LINE__); list ($ID_GROUP) = mysql_fetch_row($request); mysql_free_result($request); $ID_GROUP++; db_query(" INSERT INTO {$db_prefix}membergroups (ID_GROUP, groupName, minPosts, stars) VALUES ($ID_GROUP, '$_POST[group_name]', " . (isset($_POST['min_posts']) ? (int) $_POST['min_posts'] : '-1') . ", '1#star.gif')", __FILE__, __LINE__); // Update the post groups now, if this is a post group! if (isset($_POST['min_posts'])) updateStats('postgroups'); if (!isset($_POST['copyperm']) || $_POST['copyperm'] == 1) { // Set default permission level. require_once($sourcedir . '/ManagePermissions.php'); setPermissionLevel($_POST['level'], $ID_GROUP, 'null'); } // Copy the permissions! else { $_POST['copyperm'] = (int) $_POST['copyperm']; $request = db_query(" SELECT permission, addDeny FROM {$db_prefix}permissions WHERE ID_GROUP = $_POST[copyperm]", __FILE__, __LINE__); $setString = ''; while ($row = mysql_fetch_assoc($request)) $setString .= " ($ID_GROUP, '$row[permission]', $row[addDeny]),"; mysql_free_result($request); if (!empty($setString)) db_query(" INSERT INTO {$db_prefix}permissions (ID_GROUP, permission, addDeny) VALUES" . substr($setString, 0, -1), __FILE__, __LINE__); $request = db_query(" SELECT ID_BOARD, permission, addDeny FROM {$db_prefix}board_permissions WHERE ID_GROUP = $_POST[copyperm]", __FILE__, __LINE__); $setString = ''; while ($row = mysql_fetch_assoc($request)) $setString .= " ($ID_GROUP, $row[ID_BOARD], '$row[permission]', $row[addDeny]),"; mysql_free_result($request); if (!empty($setString)) db_query(" INSERT INTO {$db_prefix}board_permissions (ID_GROUP, ID_BOARD, permission, addDeny) VALUES" . substr($setString, 0, -1), __FILE__, __LINE__); // Also get some membergroup information if we're not copying from guests... if ($_POST['copyperm'] > 0) { $request = db_query(" SELECT onlineColor, maxMessages, stars FROM {$db_prefix}membergroups WHERE ID_GROUP = $_POST[copyperm] LIMIT 1", __FILE__, __LINE__); $group_info = mysql_fetch_assoc($request); mysql_free_result($request); // ...and update the new membergroup with it. db_query(" UPDATE {$db_prefix}membergroups SET onlineColor = '$group_info[onlineColor]', maxMessages = $group_info[maxMessages], stars = '$group_info[stars]' WHERE ID_GROUP = $ID_GROUP LIMIT 1", __FILE__, __LINE__); } } if (empty($_POST['boardaccess'])) $_POST['boardaccess'] = array(); $boards = array(); foreach ($_POST['boardaccess'] as $id => $dummy) $boards[] = (int) $id; // If they have no special access requirements then skip the rest of this. if (count($boards) == 0) redirectexit('action=membergroups;'); // Now it's the time to sort out which boards this new group has access to. $result = db_query(" SELECT ID_BOARD, memberGroups FROM {$db_prefix}boards WHERE ID_BOARD IN (" . implode(', ', $boards) . ") LIMIT " . count($boards), __FILE__, __LINE__); while ($row = mysql_fetch_assoc($result)) { // They should have access... but there is a list of VIPs. $memberGroups = explode(',', $row['memberGroups']); $memberGroups[] = $ID_GROUP; db_query(" UPDATE {$db_prefix}boards SET memberGroups = '" . implode(',', $memberGroups) . "' WHERE ID_BOARD = $row[ID_BOARD] LIMIT 1", __FILE__, __LINE__); } mysql_free_result($result); redirectexit('action=membergroups;'); } function DeleteMembergroup() { global $db_prefix; checkSession('request'); $_REQUEST['id'] = (int) $_REQUEST['id']; if ($_REQUEST['id'] <= 4) redirectexit('action=membergroups;'); db_query(" DELETE FROM {$db_prefix}membergroups WHERE ID_GROUP = $_REQUEST[id] LIMIT 1", __FILE__, __LINE__); db_query(" DELETE FROM {$db_prefix}permissions WHERE ID_GROUP = $_REQUEST[id]", __FILE__, __LINE__); db_query(" DELETE FROM {$db_prefix}board_permissions WHERE ID_GROUP = $_REQUEST[id]", __FILE__, __LINE__); db_query(" UPDATE {$db_prefix}members SET ID_GROUP = 0 WHERE ID_GROUP = $_REQUEST[id]", __FILE__, __LINE__); $request = db_query(" SELECT ID_MEMBER, additionalGroups FROM {$db_prefix}members WHERE FIND_IN_SET($_REQUEST[id], additionalGroups)", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($request)) { $row['additionalGroups'] = array_flip(explode(',', $row['additionalGroups'])); unset($row['additionalGroups'][$_REQUEST['id']]); $row['additionalGroups'] = implode(',', array_keys($row['additionalGroups'])); updateMemberData($row['ID_MEMBER'], array('additionalGroups' => '\'' . $row['additionalGroups'] . '\'')); } mysql_free_result($request); $request = db_query(" SELECT ID_BOARD, memberGroups FROM {$db_prefix}boards WHERE FIND_IN_SET($_REQUEST[id], memberGroups)", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($request)) { $row['memberGroups'] = array_flip(explode(',', $row['memberGroups'])); unset($row['memberGroups'][$_REQUEST['id']]); $row['memberGroups'] = implode(',', array_keys($row['memberGroups'])); db_query(" UPDATE {$db_prefix}boards SET memberGroups = '$row[memberGroups]' WHERE ID_BOARD = $row[ID_BOARD] LIMIT 1", __FILE__, __LINE__); } // Recalculate the post groups, as they likely changed. updateStats('postgroups'); redirectexit('action=membergroups;'); } function EditMembergroup() { global $db_prefix, $context, $txt; $_GET['id'] = empty($_GET['id']) || $_GET['id'] < 0 ? 1 : (int) $_GET['id']; if (isset($_POST['delete'])) DeleteMembergroup(); elseif (isset($_POST['submit'])) { checkSession(); $_POST['max_messages'] = (int) $_POST['max_messages']; $_POST['min_posts'] = isset($_POST['min_posts']) && $_POST['post_group'] == '1' && $_GET['id'] > 3 ? abs($_POST['min_posts']) : ($_GET['id'] == 4 ? 0 : -1); $_POST['stars'] = (empty($_POST['star_count']) || $_POST['star_count'] < 0) ? '' : min((int) $_POST['star_count'], 99) . '#' . $_POST['star_image']; db_query(" UPDATE {$db_prefix}membergroups SET groupName = '$_POST[group_name]', onlineColor = '$_POST[online_color]', maxMessages = $_POST[max_messages], minPosts = $_POST[min_posts], stars = '$_POST[stars]' WHERE ID_GROUP = $_GET[id] LIMIT 1", __FILE__, __LINE__); // There might have been some post group changes. updateStats('postgroups'); redirectexit('action=membergroups;'); } $result = db_query(" SELECT groupName, minPosts, onlineColor, maxMessages, stars FROM {$db_prefix}membergroups WHERE ID_GROUP = $_GET[id] LIMIT 1", __FILE__, __LINE__); $row = mysql_fetch_assoc($result); mysql_free_result($result); $row['stars'] = explode('#', $row['stars']); $context['group'] = array( 'id' => $_GET['id'], 'name' => $row['groupName'], 'editable_name' => htmlspecialchars($row['groupName']), 'color' => $row['onlineColor'], 'min_posts' => $row['minPosts'], 'max_messages' => $row['maxMessages'], 'star_count' => (int) $row['stars'][0], 'star_image' => isset($row['stars'][1]) ? $row['stars'][1] : '', 'is_post_group' => $row['minPosts'] != -1, 'allow_post_group' => $_GET['id'] > 4, 'allow_delete' => $_GET['id'] > 4 ); $context['sub_template'] = 'edit_group'; $context['page_title'] = $txt['membergroups_edit_group']; } // Display members of a group, and allow adding of members to a group. Silly function name though ;) function MembergroupMembers() { global $txt, $scripturl, $db_prefix, $context, $modSettings; $_REQUEST['id'] = (int) $_REQUEST['id']; // Start! $context['start'] = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0; // Load up the group details - and ensure this ISN'T a post group ;) $request = db_query(" SELECT ID_GROUP AS id, groupName AS name, minPosts = -1 AS assignable FROM {$db_prefix}membergroups WHERE ID_GROUP = $_REQUEST[id] LIMIT 1", __FILE__, __LINE__); // Not really possible... if (mysql_num_rows($request) == 0) fatal_lang_error(1); $context['group'] = mysql_fetch_assoc($request); mysql_free_result($request); if ($context['group']['id'] == 1 && !allowedTo('admin_forum')) $context['group']['assignable'] = 0; // Changing members in this group? if (isset($_POST['sc']) && $context['group']['assignable'] && $_REQUEST['id'] != 3) { checkSession(); // Removing member from group? if (isset($_POST['remove']) && isset($_REQUEST['rem'])) { $members = array(); foreach ($_REQUEST['rem'] AS $remove => $dummy) $members[] = (int) $remove; // First, reset those who have this as their primary group - this is the easy one. db_query(" UPDATE {$db_prefix}members SET ID_GROUP = 0 WHERE ID_GROUP = $_REQUEST[id] AND ID_MEMBER IN (" . implode(', ', $members) . ") LIMIT " . count($members), __FILE__, __LINE__); // Those who have it as part of their additional group must be updated the long way... sadly. $request = db_query(" SELECT ID_MEMBER, additionalGroups FROM {$db_prefix}members WHERE FIND_IN_SET($_REQUEST[id], additionalGroups) AND ID_MEMBER IN (" . implode(', ', $members) . ") LIMIT " . count($members), __FILE__, __LINE__); while ($row = mysql_fetch_assoc($request)) { $tempGroup = array_flip(explode(',', $row['additionalGroups'])); unset($tempGroup[$_REQUEST['id']]); $tempGroup = implode(',', array_flip($tempGroup)); // Do the update for this member - this may be slow for lots of people... but how many you really do at once? db_query(" UPDATE {$db_prefix}members SET additionalGroups = '$tempGroup' WHERE ID_MEMBER = $row[ID_MEMBER] LIMIT 1", __FILE__, __LINE__); } mysql_free_result($request); } // Must be adding... elseif (isset($_REQUEST['add']) && !empty($_REQUEST['toAdd'])) { // Get all the members to be added... taking into account names can be quoted ;) $_REQUEST['toAdd'] = strtr(un_htmlspecialchars($_REQUEST['toAdd']), array('\\"' => '"')); preg_match_all('~"([^"]+)"~', $_REQUEST['toAdd'], $matches); $memberQuery = array_unique(array_merge($matches[1], explode(',', preg_replace('~"([^"]+)"~', '', $_REQUEST['toAdd'])))); foreach ($memberQuery as $index => $member) { if (strlen(trim($member)) > 0) $memberQuery[$index] = strtolower(trim($member)); else unset($memberQuery[$index]); } $request = db_query(" SELECT ID_MEMBER, ID_GROUP, additionalGroups FROM {$db_prefix}members WHERE memberName IN ('" . implode("', '", $memberQuery) . "')", __FILE__, __LINE__); // Reset the query array and we'll use it to update the members. $memberQuery = array( 'main_group' => array(), 'additional' => array() ); while ($row = mysql_fetch_assoc($request)) { // Verify that they are not already a member - and add them to our array. if ($row['ID_GROUP'] != $_REQUEST['id'] && !in_array($_REQUEST['id'], explode(',', $row['additionalGroups']))) $memberQuery[$row['ID_GROUP'] == 0 ? 'main_group' : 'additional'][] = $row['ID_MEMBER']; } mysql_free_result($request); // Do the updates... if (!empty($memberQuery['main_group'])) db_query(" UPDATE {$db_prefix}members SET ID_GROUP = $_REQUEST[id] WHERE ID_MEMBER IN (" . implode(', ', $memberQuery['main_group']) . ") LIMIT " . count($memberQuery['main_group']), __FILE__, __LINE__); // This one is more complicated! if (!empty($memberQuery['additional'])) { db_query(" UPDATE {$db_prefix}members SET additionalGroups = IF(additionalGroups = '', '$_REQUEST[id]', CONCAT(additionalGroups, ',$_REQUEST[id]')) WHERE ID_MEMBER IN (" . implode(', ', $memberQuery['additional']) . ") LIMIT " . count($memberQuery['additional']), __FILE__, __LINE__); } } } // Sort out the sorting! $sort_methods = array( 'name' => 'realName', 'email' => 'emailAddress', 'active' => 'lastLogin', 'registered' => 'dateRegistered', 'posts' => 'posts', ); // They didn't pick one, default to by name.. if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) { $context['sort_by'] = 'name'; $querySort = 'realName'; } // Otherwise default to ascending. else { $context['sort_by'] = $_REQUEST['sort']; $querySort = $sort_methods[$_REQUEST['sort']]; } $context['sort_direction'] = isset($_REQUEST['desc']) ? 'down' : 'up'; // Count members of the group. $request = db_query(" SELECT COUNT(ID_MEMBER) FROM {$db_prefix}members WHERE " . ($context['group']['assignable'] ? "ID_GROUP = $_REQUEST[id] OR FIND_IN_SET($_REQUEST[id], additionalGroups)" : "ID_POST_GROUP = $_REQUEST[id]"), __FILE__, __LINE__); list ($context['total_members']) = mysql_fetch_row($request); mysql_free_result($request); // Create the page index. $context['page_index'] = constructPageIndex($scripturl . '?action=membergroups;sa=members;id=' . $_REQUEST['id'] . ';sort=' . $context['sort_by'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $context['start'], $context['total_members'], $modSettings['defaultMaxMembers']); // Load up all members of this group. $request = db_query(" SELECT ID_MEMBER, realName, memberName, emailAddress, memberIP, dateRegistered, lastLogin, posts FROM {$db_prefix}members WHERE " . ($context['group']['assignable'] ? "ID_GROUP = $_REQUEST[id] OR FIND_IN_SET($_REQUEST[id], additionalGroups)" : "ID_POST_GROUP = $_REQUEST[id]") . " ORDER BY $querySort " . ($context['sort_direction'] == 'down' ? 'DESC' : 'ASC') . " LIMIT $context[start], $modSettings[defaultMaxMembers]", __FILE__, __LINE__); $context['members'] = array(); while ($row = mysql_fetch_assoc($request)) $context['members'][] = array( 'id' => $row['ID_MEMBER'], 'name' => '' . $row['realName'] . '', 'email' => '' . $row['emailAddress'] . '', 'ip' => '' . $row['memberIP'] . '', 'registered' => timeformat($row['dateRegistered']), 'last_online' => empty($row['lastLogin']) ? $txt['never'] : timeformat($row['lastLogin']), 'posts' => $row['posts'], ); mysql_free_result($request); // Select the template. $context['sub_template'] = 'group_members'; $context['page_title'] = $txt['membergroups_members_title'] . ': ' . $context['group']['name']; } // View all members. function ViewMembers() { global $txt, $scripturl, $db_prefix, $context, $modSettings; isAllowedTo('moderate_forum'); // Administration bar, I choose you! adminIndex('view_members'); loadTemplate('ManageMembers'); loadLanguage('ManageMembers'); $allowed_sub_actions = array('all', 'search', 'query', 'delete'); // Set default sub action. $context['sub_action'] = empty($_REQUEST['sa']) || !in_array($_REQUEST['sa'], $allowed_sub_actions) ? 'all' : $_REQUEST['sa']; if ($context['sub_action'] == 'delete' && allowedTo('profile_remove_any')) { checkSession(); // Delete all the selected members. deleteMembers(array_keys($_POST['delete'])); // Update the latest member... updateStats('member'); // Switch to 'view all members'. $context['sub_action'] = 'all'; } // Retrieve the membergroups and postgroups. if (in_array($context['sub_action'], array('search', 'query'))) { $context['membergroups'] = array( array( 'id' => 0, 'name' => $txt['membergroups_members'], 'can_be_additional' => false ) ); $context['postgroups'] = array(); $request = db_query(" SELECT ID_GROUP, groupName, minPosts FROM {$db_prefix}membergroups WHERE ID_GROUP != 3 ORDER BY minPosts, IF(ID_GROUP < 4, ID_GROUP, 4), groupName", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($request)) { if ($row['minPosts'] == -1) $context['membergroups'][] = array( 'id' => $row['ID_GROUP'], 'name' => $row['groupName'], 'can_be_additional' => true ); else $context['postgroups'][] = array( 'id' => $row['ID_GROUP'], 'name' => $row['groupName'] ); } } // Check input after a member search has been submitted. if ($context['sub_action'] == 'query' && empty($_REQUEST['params'])) { // Some data about the form fields and how they are linked to the database. $params = array( 'mem_id' => array( 'db_fields' => array('ID_MEMBER'), 'type' => 'int', 'range' => true ), 'age' => array( 'db_fields' => array('birthdate'), 'type' => 'age', 'range' => true ), 'posts' => array( 'db_fields' => array('posts'), 'type' => 'int', 'range' => true ), 'reg_date' => array( 'db_fields' => array('dateRegistered'), 'type' => 'date', 'range' => true ), 'last_online' => array( 'db_fields' => array('lastLogin'), 'type' => 'date', 'range' => true ), 'gender' => array( 'db_fields' => array('gender'), 'type' => 'checkbox', 'values' => array('0', '1', '2'), ), 'activated' => array( 'db_fields' => array('is_activated'), 'type' => 'checkbox', 'values' => array('0', '1'), ), 'membername' => array( 'db_fields' => array('memberName', 'realName'), 'type' => 'string' ), 'email' => array( 'db_fields' => array('emailAddress'), 'type' => 'string' ), 'website' => array( 'db_fields' => array('websiteTitle', 'websiteUrl'), 'type' => 'string' ), 'location' => array( 'db_fields' => array('location'), 'type' => 'string' ), 'ip' => array( 'db_fields' => array('memberIP'), 'type' => 'string' ), 'messenger' => array( 'db_fields' => array('ICQ', 'AIM', 'YIM', 'MSN'), 'type' => 'string' ) ); $range_trans = array( '--' => '<', '-' => '<=', '=' => '=', '+' => '>=', '++' => '>' ); // Loop through every field of the form. $query_parts = array(); foreach ($params as $param_name => $param_info) { // Not filled in? if (!isset($_POST[$param_name]) || $_POST[$param_name] == '') continue; // Make sure numeric values are really numeric. if (in_array($param_info['type'], array('int', 'age'))) $_POST[$param_name] = (int) $_POST[$param_name]; // Date values have to match the specified format. elseif ($param_info['type'] == 'date') { // Check if this date format is valid. if (!preg_match('/^\d{4}-\d{1,2}-\d{1,2}$/', $_POST[$param_name])) continue; // Add quotes for the database. $_POST[$param_name] = strtotime($_POST[$param_name]); } // Those values that are in some kind of range (<, <=, =, >=, >). if (!empty($param_info['range'])) { // Default to '=', just in case... if (empty($range_trans[$_POST['types'][$param_name]])) $_POST['types'][$param_name] = '='; // Handle special case 'age'. if ($param_info['type'] == 'age') { // All people that were born between $lowerlimit and $upperlimit are currently the specified age. $datearray = getdate(forum_time()); $upperlimit = str_pad($datearray['year'] - $_POST[$param_name], 4, '0') . '-' . str_pad($datearray['mon'], 2, '0', STR_PAD_LEFT) . '-' . str_pad($datearray['mday'], 2, '0', STR_PAD_LEFT); $lowerlimit = str_pad($datearray['year'] - $_POST[$param_name] - 1, 4, '0') . '-' . str_pad($datearray['mon'], 2, '0', STR_PAD_LEFT) . '-' . str_pad($datearray['mday'], 2, '0', STR_PAD_LEFT); if (in_array($_POST['types'][$param_name], array('-', '--', '='))) $query_parts[] = "{$param_info['db_fields'][0]} > '" . ($_POST['types'][$param_name] == '--' ? $upperlimit : $lowerlimit) . "'"; if (in_array($_POST['types'][$param_name], array('+', '++', '='))) { $query_parts[] = "{$param_info['db_fields'][0]} <= '" . ($_POST['types'][$param_name] == '++' ? $lowerlimit : $upperlimit) . "'"; // Make sure that members that didn't set their birth year are not queried. $query_parts[] = "{$param_info['db_fields'][0]} > '0000-12-31'"; } } else $query_parts[] = $param_info['db_fields'][0] . ' ' . $range_trans[$_POST['types'][$param_name]] . ' ' . $_POST[$param_name]; } // Checkboxes. elseif ($param_info['type'] == 'checkbox') { // Each checkbox or no checkbox at all is checked -> ignore. if (!is_array($_POST[$param_name]) || count($_POST[$param_name]) == 0 || count($_POST[$param_name]) == count($param_info['values'])) continue; $query_parts[] = "{$param_info['db_fields'][0]} IN ('" . implode("', '", $_POST[$param_name]) . "')"; } else { // Replace the wildcard characters ('*' and '?') into MySQL ones. $_POST[$param_name] = strtolower(addslashes(strtr($_POST[$param_name], array('%' => '\%', '_' => '\_', '*' => '%', '?' => '_')))); $query_parts[] = '(' . implode(" LIKE '%{$_POST[$param_name]}%' OR ", $param_info['db_fields']) . " LIKE '%{$_POST[$param_name]}%')"; } } // Set up the membergroup query part. $mg_query_parts = array(); // Primary membergroups, but only if at least was was not selected. if (!empty($_POST['membergroups'][1]) && count($context['membergroups']) != count($_POST['membergroups'][1])) $mg_query_parts[] = "ID_GROUP IN (" . implode(", ", $_POST['membergroups'][1]) . ")"; // Additional membergroups (these are only relevant if not all primary groups where selected!). if (!empty($_POST['membergroups'][2]) && (empty($_POST['membergroups'][1]) || count($context['membergroups']) != count($_POST['membergroups'][1]))) foreach ($_POST['membergroups'][2] as $mg) $mg_query_parts[] = "FIND_IN_SET(" . (int) $mg . ", additionalGroups)"; // Combine the one or two membergroup parts into one query part linked with an OR. if (!empty($mg_query_parts)) $query_parts[] = '(' . implode(' OR ', $mg_query_parts) . ')'; // Get all selected post count related membergroups. if (!empty($_POST['postgroups']) && count($_POST['postgroups']) != count($context['postgroups'])) $query_parts[] = "ID_POST_GROUP IN (" . implode(", ", $_POST['postgroups']) . ")"; // Construct the where part of the query. $where = empty($query_parts) ? '1' : implode(' AND ', $query_parts); } // If the query information was already packed in the URL, decode it. elseif ($context['sub_action'] == 'query') $where = base64_decode($_REQUEST['params']); // Construct the additional URL part with the query info in it. $context['params_url'] = $context['sub_action'] == 'query' ? ';sa=query;params=' . base64_encode($where) : ''; // Get the title and sub template ready.. $context['page_title'] = $txt[9]; $context['sub_template'] = 'view_members'; // Determine whether to show the 'delete members' checkboxes. $context['can_delete_members'] = allowedTo('profile_remove_any'); // All the columns they have to pick from... $context['columns'] = array( 'ID_MEMBER' => array('label' => $txt['member_id']), 'memberName' => array('label' => $txt[35]), 'realName' => array('label' => $txt['display_name']), 'emailAddress' => array('label' => $txt['email_address']), 'memberIP' => array('label' => $txt['ip_address']), 'lastLogin' => array('label' => $txt['viewmembers_online']), 'posts' => array('label' => $txt[26]) ); // Default sort column to 'memberName' if the current one is unknown or not set. if (!isset($_REQUEST['sort']) || !array_key_exists($_REQUEST['sort'], $context['columns'])) $_REQUEST['sort'] = 'memberName'; // Provide extra information about each column - the link, whether it's selected, etc. foreach ($context['columns'] as $col => $dummy) { $context['columns'][$col]['href'] = $scripturl . '?action=viewmembers' . $context['params_url'] . ';sort=' . $col . ';start=0'; if (!isset($_REQUEST['desc']) && $col == $_REQUEST['sort']) $context['columns'][$col]['href'] .= ';desc'; $context['columns'][$col]['link'] = '' . $context['columns'][$col]['label'] . ''; $context['columns'][$col]['selected'] = $_REQUEST['sort'] == $col; } $context['sort_by'] = $_REQUEST['sort']; $context['sort_direction'] = !isset($_REQUEST['desc']) ? 'down' : 'up'; // Calculate the number of results. if (empty($where) or $where == '1') $num_members = $modSettings['memberCount']; else { $request = db_query(" SELECT COUNT(ID_MEMBER) FROM {$db_prefix}members WHERE $where", __FILE__, __LINE__); list ($num_members) = mysql_fetch_row($request); } // Construct the page links. $context['page_index'] = constructPageIndex($scripturl . '?action=viewmembers' . $context['params_url'] . ';sort=' . $_REQUEST['sort'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $num_members, $modSettings['defaultMaxMembers']); $context['start'] = $_REQUEST['start']; $request = db_query(" SELECT ID_MEMBER, memberName, realName, emailAddress, memberIP, IFNULL(lastLogin, 0) AS lastLogin, posts FROM {$db_prefix}members" . ($context['sub_action'] == 'query' && !empty($where) ? " WHERE $where" : '') . " ORDER BY $_REQUEST[sort]" . (!isset($_REQUEST['desc']) ? '' : ' DESC') . " LIMIT $_REQUEST[start], $modSettings[defaultMaxMembers]", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($request)) { // Calculate number of days since last online. if (empty($row['lastLogin'])) $difference = $txt['never']; else { // Today or some time ago? $difference = jeffsdatediff($row['lastLogin']); if (empty($difference)) $difference = $txt['viewmembers_today']; elseif ($difference == 1) $difference .= ' ' . $txt['viewmembers_day_ago']; else $difference .= ' ' . $txt['viewmembers_days_ago']; } $context['members'][] = array( 'id' => $row['ID_MEMBER'], 'username' => $row['memberName'], 'name' => $row['realName'], 'email' => $row['emailAddress'], 'ip' => $row['memberIP'], 'last_active' => $difference, 'posts' => $row['posts'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_MEMBER'], 'link' => '' . $row['realName'] . '' ); } mysql_free_result($request); } function jeffsdatediff($old) { // Get the current time as the user would see it. $forumTime = forum_time(); // Calculate the seconds that have passed since midnight. $sinceMidnight = date('H', $forumTime) * 60 * 60 + date('i', $forumTime) * 60 + date('s', $forumTime); // Take the difference between the two times. $dis = time() - $old; // Before midnight? if ($dis < $sinceMidnight) return 0; else $dis -= $sinceMidnight; // Divide out the seconds in a day to get the number of days. return ceil($dis / (24 * 60 * 60)); } function submitSpammer($users) { global $db_prefix, $sourcedir, $modSettings, $ID_MEMBER; // If it's not an array, make it so! if (!is_array($users)) $users = array($users); else $users = array_unique($users); if (empty($users)) { return; } elseif (count($users) == 1) { list ($user) = $users; $condition = '= ' . $user; } else { $condition = 'IN (' . implode(',', $users) . ')'; } $res = db_query( "SELECT memberName, emailAddress, memberIP FROM {$db_prefix}members WHERE ID_MEMBER $condition", __FILE__, __LINE__); if ($res === FALSE) { return; } while ($user = mysql_fetch_assoc($res)) { if ($user === FALSE) continue; actuallySubmitSpammer( $user['memberName'], $user['emailAddress'], $user['memberIP']); } } function actuallySubmitSpammer($_username, $_email, $_ipaddr) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://www.stopforumspam.com/add"); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, array( 'username' => $_username, 'email' => $_email, 'ip_addr' => $_ipaddr, 'api_key' => 'jk192x8p4GAmbY')); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_exec($ch); curl_close($ch); } // Delete a group of/single member. function deleteMembers($users) { global $db_prefix, $sourcedir, $modSettings, $ID_MEMBER; // If it's not an array, make it so! if (!is_array($users)) $users = array($users); else $users = array_unique($users); // How many are they deleting? if (empty($users)) return; elseif (count($users) == 1) { list ($user) = $users; $condition = '= ' . $user; if ($user == $ID_MEMBER) isAllowedTo('profile_remove_own'); else isAllowedTo('profile_remove_any'); } else { $condition = 'IN (' . implode(',', $users) . ')'; // Deleting more than one? You can't have more than once account... isAllowedTo('profile_remove_any'); // Log the action while we are here. foreach ($users as $user) logAction('delete_member', array('member' => $user)); } // Make these peoples' posts guest posts. db_query(" UPDATE {$db_prefix}messages SET ID_MEMBER = 0" . (!empty($modSettings['allow_hideEmail']) ? ", posterEmail = ''" : '') . " WHERE ID_MEMBER $condition", __FILE__, __LINE__); // Delete the member. db_query(" DELETE FROM {$db_prefix}members WHERE ID_MEMBER $condition LIMIT " . count($users), __FILE__, __LINE__); // Delete the logs... db_query(" DELETE FROM {$db_prefix}log_topics WHERE ID_MEMBER $condition", __FILE__, __LINE__); db_query(" DELETE FROM {$db_prefix}log_boards WHERE ID_MEMBER $condition", __FILE__, __LINE__); db_query(" DELETE FROM {$db_prefix}log_mark_read WHERE ID_MEMBER $condition", __FILE__, __LINE__); db_query(" DELETE FROM {$db_prefix}log_notify WHERE ID_MEMBER $condition", __FILE__, __LINE__); db_query(" DELETE FROM {$db_prefix}log_online WHERE ID_MEMBER $condition", __FILE__, __LINE__); db_query(" DELETE FROM {$db_prefix}collapsed_categories WHERE ID_MEMBER $condition", __FILE__, __LINE__); db_query(" DELETE FROM {$db_prefix}themes WHERE ID_MEMBER $condition", __FILE__, __LINE__); // Delete personal messages. require_once($sourcedir . '/InstantMessage.php'); deleteMessages(null, null, $users); db_query(" UPDATE {$db_prefix}instant_messages SET ID_MEMBER_FROM = 0 WHERE ID_MEMBER_FROM $condition", __FILE__, __LINE__); // Delete the moderator positions. db_query(" DELETE FROM {$db_prefix}moderators WHERE ID_MEMBER $condition", __FILE__, __LINE__); // Make sure no member's birthday is still sticking in the calendar... updateStats('calendar'); updateStats('member'); } // Email your members... function MailingList() { global $txt, $db_prefix, $sourcedir, $context; global $scripturl, $modSettings, $user_info; isAllowedTo('send_mail'); // Load the admin bar, select 'Email Your Members'.. adminIndex('email_members'); // Just came here.... if (!isset($_REQUEST['sa'])) { loadTemplate('ManageMembers'); $context['page_title'] = $txt[6]; $context['sub_template'] = 'email_members'; $context['groups'] = array(); // Get all the extra groups as well as Administrator and Global Moderator. $request = db_query(" SELECT mg.ID_GROUP, mg.groupName, COUNT(mem.ID_MEMBER) AS num_members FROM {$db_prefix}membergroups AS mg LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_GROUP = mg.ID_GROUP OR FIND_IN_SET(mg.ID_GROUP, mem.additionalGroups) OR mg.ID_GROUP = mem.ID_POST_GROUP) GROUP BY mg.ID_GROUP ORDER BY mg.minPosts, IF(mg.ID_GROUP < 4, mg.ID_GROUP, 4), mg.groupName", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($request)) { $context['groups'][$row['ID_GROUP']] = array( 'id' => $row['ID_GROUP'], 'name' => $row['groupName'], 'member_count' => $row['num_members'], ); } mysql_free_result($request); // Any moderators? $request = db_query(" SELECT COUNT(DISTINCT ID_MEMBER) AS num_distinct_mods FROM {$db_prefix}moderators LIMIT 1", __FILE__, __LINE__); list ($context['groups'][3]['member_count']) = mysql_fetch_row($request); mysql_free_result($request); $context['can_send_pm'] = allowedTo('pm_send'); return; } // Sending! elseif ($_REQUEST['sa'] == 'send2') { checkSession(); require_once($sourcedir . '/Subs-Post.php'); // Get all the receivers. $addressed = explode(';', $_POST['emails']); $cleanlist = array(); foreach ($addressed as $curmem) { $curmem = trim($curmem); if ($curmem != '') $cleanlist[$curmem] = $curmem; } // Prepare the message for HTML. if (isset($_POST['send_html']) && isset($_POST['parse_html'])) $_POST['message'] = str_replace(array("\n", ' '), array("
\n", '  '), stripslashes($_POST['message'])); elseif (!isset($_POST['send_html'])) $_POST['message'] = stripslashes($_POST['message']); // Use the default time format. $user_info['time_format'] = $modSettings['time_format']; $variables = array( '{$board_url}', '{$current_time}', '{$latest_member.link}', '{$latest_member.id}', '{$latest_member.name}' ); // Replace in all the standard things. $_POST['message'] = str_replace($variables, array( isset($_POST['send_html']) ? '' . $scripturl . '' : $scripturl, timeformat(forum_time(), false), isset($_POST['send_html']) ? '' . $modSettings['latestRealName'] . '' : $modSettings['latestRealName'], $modSettings['latestMember'], $modSettings['latestRealName'] ), $_POST['message']); $_POST['subject'] = str_replace($variables, array( $scripturl, timeformat(forum_time(), false), $modSettings['latestRealName'], $modSettings['latestMember'], $modSettings['latestRealName'] ), stripslashes($_POST['subject'])); $from_member = array( '{$member.email}', '{$member.link}', '{$member.id}', '{$member.name}' ); // This is here to prevent spam filters from tagging this as spam. if (isset($_POST['send_html']) && preg_match('~\' . $_POST['message'] . ''; else $_POST['message'] = '' . $_POST['message'] . ''; } $result = db_query(" SELECT realName, memberName, ID_MEMBER, emailAddress FROM {$db_prefix}members WHERE emailAddress IN ('" . implode("', '", $cleanlist) . "')", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($result)) { unset($cleanlist[$row['emailAddress']]); $to_member = array( $row['emailAddress'], isset($_POST['send_html']) ? '' . $row['realName'] . '' : $scripturl . '?action=profile;u=' . $row['ID_MEMBER'], $row['ID_MEMBER'], $row['realName'] ); // Send the actual email off, replacing the member dependent variables. sendmail($row['emailAddress'], str_replace($from_member, $to_member, $_POST['subject']), str_replace($from_member, $to_member, $_POST['message']), null, isset($_POST['send_html'])); } mysql_free_result($result); // Send the emails to people who weren't members.... if (!empty($cleanlist)) foreach ($cleanlist as $email) { $to_member = array( $email, !empty($_POST['send_html']) ? '' . $email . '' : $email, '??', $email ); sendmail($email, str_replace($from_member, $to_member, $_POST['subject']), str_replace($from_member, $to_member, $_POST['message']), null, !empty($_POST['send_html'])); } redirectexit('action=admin'); } checkSession(); $list = array(); $do_pm = !empty($_POST['sendPM']); // Opt-out? $condition = isset($_POST['email_force']) ? '' : ' AND mem.notifyAnnouncements = 1'; // Did they select moderators too? if (!empty($_POST['who']) && in_array(3, $_POST['who'])) { $request = db_query(" SELECT DISTINCT " . ($do_pm ? 'mem.memberName' : 'mem.emailAddress') . " AS identifier FROM {$db_prefix}members AS mem, {$db_prefix}moderators AS mods WHERE mem.ID_MEMBER = mods.ID_MEMBER$condition", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($request)) $list[] = $row['identifier']; mysql_free_result($request); unset($_POST['who'][3]); } // Load all the other groups. if (!empty($_POST['who'])) { $request = db_query(" SELECT " . ($do_pm ? 'mem.memberName' : 'mem.emailAddress') . " AS identifier FROM {$db_prefix}members AS mem, {$db_prefix}membergroups AS mg WHERE (mg.ID_GROUP = mem.ID_GROUP OR FIND_IN_SET(mg.ID_GROUP, mem.additionalGroups) OR mg.ID_GROUP = mem.ID_POST_GROUP) AND mg.ID_GROUP IN (" . implode(',', $_POST['who']) . ")$condition", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($request)) $list[] = $row['identifier']; mysql_free_result($request); } // Tear out duplicates.... $list = array_unique($list); // Sending as a personal message? if ($do_pm) { require_once($sourcedir . '/InstantMessage.php'); require_once($sourcedir . '/Subs-Post.php'); $_REQUEST['bcc'] = implode(',', $list); MessagePost(); } else { loadTemplate('ManageMembers'); $context['page_title'] = $txt[6]; // Just send the to list to the template. $context['addresses'] = implode('; ', $list); $context['default_subject'] = $context['forum_name'] . ': ' . $txt[70]; $context['default_message'] = $txt[72] . "\n\n" . $txt[130] . "\n\n{\$board_url}"; $context['sub_template'] = 'email_members_compose'; } } // Ban center. function Ban() { global $context, $txt; isAllowedTo('manage_bans'); // Boldify "Ban Members" on the admin bar. adminIndex('ban_members'); loadTemplate('ManageMembers'); $subActions = array( 'add' => 'BanEdit', 'edit' => 'BanEdit', 'list' => 'BanList', 'log' => 'BanLog', 'save' => 'BanSave', ); // Default the sub-action to 'view ban list'. $_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'list'; $context['page_title'] = &$txt['ban_title']; $context['sub_action'] = $_REQUEST['sa']; // Call the right function for this sub-acton. $subActions[$_REQUEST['sa']](); } // Ban list function BanList() { global $txt, $db_prefix, $context, $ban_request, $scripturl; // Delete expired bans, the're useless! db_query(" DELETE FROM {$db_prefix}banned WHERE expire_time < " . time(), __FILE__, __LINE__); // User pressed the 'remove selection button'. if (!empty($_POST['removeBans']) && !empty($_POST['remove']) && is_array($_POST['remove'])) { checkSession(); // Make sure every entry is a proper integer. foreach ($_POST['remove'] as $index => $ban_id) $_POST['remove'][(int) $index] = (int) $ban_id; $_POST['remove'] = array_unique($_POST['remove']); db_query(" DELETE FROM {$db_prefix}banned WHERE ID_BAN IN (" . implode(', ', $_POST['remove']) . ') LIMIT ' . count($_POST['remove']), __FILE__, __LINE__); } $sort_methods = array( 'type' => array( 'down' => 'ban.ban_type ASC, ban.hostname ASC, ban.email_address ASC, mem.realName ASC, ban.ip_low1 ASC, ban.ip_low2 ASC, ban.ip_low3 ASC, ban.ip_low4 ASC', 'up' => 'ban.ban_type DESC, ban.hostname DESC, ban.email_address DESC, mem.realName DESC, ban.ip_low1 DESC, ban.ip_low2 DESC, ban.ip_low3 DESC, ban.ip_low4 DESC' ), 'reason' => array( 'down' => 'LENGTH(ban.reason) > 0 DESC, ban.reason ASC', 'up' => 'LENGTH(ban.reason) > 0 ASC, ban.reason DESC' ), 'notes' => array( 'down' => 'LENGTH(ban.notes) > 0 DESC, ban.notes ASC', 'up' => 'LENGTH(ban.notes) > 0 ASC, ban.notes DESC' ), 'restriction' => array( 'down' => 'ban.restriction_type ASC', 'up' => 'ban.restriction_type DESC' ), 'expires' => array( 'down' => 'ISNULL(ban.expire_time) DESC, ban.expire_time DESC', 'up' => 'ISNULL(ban.expire_time) ASC, ban.expire_time ASC' ) ); $context['columns'] = array( 'type' => array( 'width' => '10%', 'label' => &$txt['ban_type'], 'sortable' => true ), 'reason' => array( 'width' => '25%', 'label' => &$txt['ban_reason'], 'sortable' => true ), 'notes' => array( 'width' => '25%', 'label' => &$txt['ban_notes'], 'sortable' => true ), 'restriction' => array( 'label' => &$txt['ban_restriction'], 'sortable' => true ), 'expires' => array( 'label' => &$txt['ban_expires'], 'sortable' => true ), 'actions' => array( 'label' => &$txt['ban_actions'], 'sortable' => false ) ); if (!isset($_REQUEST['sort']) || !array_key_exists($_REQUEST['sort'], $sort_methods)) $_REQUEST['sort'] = 'type'; foreach ($context['columns'] as $col => $dummy) { $context['columns'][$col]['selected'] = $col == $_REQUEST['sort']; $context['columns'][$col]['href'] = $scripturl . '?action=ban;sort=' . $col; if (!isset($_REQUEST['desc']) && $col == $_REQUEST['sort']) $context['columns'][$col]['href'] .= ';desc'; $context['columns'][$col]['link'] = '' . $context['columns'][$col]['label'] . ''; } $context['sort_by'] = $_REQUEST['sort']; $context['sort_direction'] = !isset($_REQUEST['desc']) ? 'down' : 'up'; // Get the total amount of entries. $request = db_query(" SELECT COUNT(ID_BAN) FROM {$db_prefix}banned", __FILE__, __LINE__); list ($totalBans) = mysql_fetch_row($request); mysql_free_result($request); // Create the page index. $context['start'] = $_REQUEST['start']; $context['page_index'] = constructPageIndex($scripturl . '?action=ban;sort=' . $_REQUEST['sort'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $context['start'], $totalBans, 20); // Get the banned values. $ban_request = db_query(" SELECT ban.ID_BAN, ban.ban_type, ban.ip_low1, ban.ip_high1, ban.ip_low2, ban.ip_high2, ban.ip_low3, ban.ip_high3, ban.ip_low4, ban.ip_high4, ban.hostname, ban.email_address, ban.ID_MEMBER, ban.ban_time, ban.expire_time, ban.restriction_type, ban.reason, ban.notes, IFNULL(mem.memberName, ban.ID_MEMBER) AS memberName, IFNULL(mem.realName, ban.ID_MEMBER) AS realName FROM {$db_prefix}banned AS ban LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = ban.ID_MEMBER) ORDER BY " . $sort_methods[$_REQUEST['sort']][$context['sort_direction']] . " LIMIT $context[start], 20", __FILE__, __LINE__); // Set the correct sub-template. $context['sub_template'] = 'ban_list'; // Set the value of the callback function. $context['get_ban'] = 'getBanEntry'; } // Call-back function for the template to retrieve a row of ban data. function getBanEntry($reset = false) { global $scripturl, $ban_request, $txt, $context; if ($ban_request == false) return false; if (!($row = mysql_fetch_assoc($ban_request))) return false; $output = array( 'id' => $row['ID_BAN'], 'type' => $row['ban_type'], 'reason' => $row['reason'], 'notes' => $row['notes'], 'restriction' => $txt['ban_' . $row['restriction_type']], 'expires' => $row['expire_time'] === null ? $txt['never'] : ceil(($row['expire_time'] - time()) / (60 * 60 * 24)) . ' ' . $txt['ban_days'], ); if ($row['ban_type'] == 'ip_ban') { $low_ip = array($row['ip_low1'], $row['ip_low2'], $row['ip_low3'], $row['ip_low4']); $high_ip = array($row['ip_high1'], $row['ip_high2'], $row['ip_high3'], $row['ip_high4']); $output['ip'] = range2ip($low_ip, $high_ip); } elseif ($row['ban_type'] == 'hostname_ban') $output['hostname'] = str_replace('%', '*', $row['hostname']); elseif ($row['ban_type'] == 'email_ban') $output['email'] = str_replace('%', '*', $row['email_address']); elseif ($row['ban_type'] == 'user_ban') $output['user'] = array( 'name' => $row['memberName'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_MEMBER'], 'link' => '' . $row['realName'] . '' ); return $output; } function BanEdit() { global $txt, $db_prefix, $modSettings, $context, $ban_request, $scripturl; // If we're editing an existing ban, get it from the database. if (!empty($_REQUEST['bid'])) { $request = db_query(" SELECT ban.ID_BAN, ban.ban_type, ban.ip_low1, ban.ip_high1, ban.ip_low2, ban.ip_high2, ban.ip_low3, ban.ip_high3, ban.ip_low4, ban.ip_high4, ban.hostname, ban.email_address, ban.ID_MEMBER, ban.ban_time, ban.expire_time, ban.restriction_type, ban.reason, ban.notes, IFNULL(mem.memberName, ban.ID_MEMBER) AS memberName, IFNULL(mem.realName, ban.ID_MEMBER) AS realName FROM {$db_prefix}banned AS ban LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER=ban.ID_MEMBER) WHERE ID_BAN = " . (int) $_REQUEST['bid'] . " LIMIT 1", __FILE__, __LINE__); if (mysql_num_rows($request) == 0) fatal_lang_error('ban_not_found'); $row = mysql_fetch_assoc($request); mysql_free_result($request); $context['ban'] = array( 'id' => $row['ID_BAN'], 'ip' => array( 'value' => $row['ban_type'] == 'ip_ban' ? range2ip(array($row['ip_low1'], $row['ip_low2'], $row['ip_low3'], $row['ip_low4']), array($row['ip_high1'], $row['ip_high2'], $row['ip_high3'], $row['ip_high4'])) : '', 'selected' => $row['ban_type'] == 'ip_ban' ), 'hostname' => array( 'value' => $row['ban_type'] == 'hostname_ban' ? str_replace('%', '*', $row['hostname']) : '', 'selected' => $row['ban_type'] == 'hostname_ban' ), 'email' => array( 'value' => $row['ban_type'] == 'email_ban' ? str_replace('%', '*', $row['email_address']) : '', 'selected' => $row['ban_type'] == 'email_ban' ), 'banneduser' => array( 'value' => $row['ban_type'] == 'user_ban' ? $row['memberName'] : '', 'selected' => $row['ban_type'] == 'user_ban' ), 'expiration' => array( 'never' => $row['expire_time'] === null, 'days' => $row['expire_time'] > time() ? floor($row['expire_time'] / 24 * 60 * 60) : 0 ), 'reason' => $row['reason'], 'notes' => $row['notes'], 'restriction' => $row['restriction_type'], 'ban_days' => $row['expire_time'] === null ? 0 : ceil(($row['expire_time'] - time()) / (60 * 60 * 24)), ); } // Not an existing one, then it's probably a new one. else { $context['ban'] = array( 'id' => 0, 'ip' => array( 'value' => '', 'selected' => true ), 'hostname' => array( 'value' => '', 'selected' => false ), 'email' => array( 'value' => '', 'selected' => false ), 'banneduser' => array( 'value' => '', 'selected' => false ), 'expiration' => array( 'never' => true, 'days' => 1 ), 'reason' => '', 'notes' => '', 'restriction' => 'full_ban', 'ban_days' => 1 ); // Overwrite some of the default form values if a user ID was given. if (!empty($_REQUEST['u'])) { $request = db_query(" SELECT memberName, memberIP, emailAddress FROM {$db_prefix}members WHERE ID_MEMBER = " . (int) $_REQUEST['u'] . " LIMIT 1", __FILE__, __LINE__); if (mysql_num_rows($request) > 0) { list ($context['ban']['banneduser']['value'], $context['ban']['ip']['value'], $context['ban']['email']['value']) = mysql_fetch_row($request); if (preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $context['ban']['ip']['value']) && empty($modSettings['disableHostnameLookup'])) $context['ban']['hostname']['value'] = @gethostbyaddr($context['ban']['ip']['value']); } } } // Edit or add, they use the same template. $context['sub_template'] = 'ban_edit'; } function BanSave() { global $db_prefix; // Make sure they CAN update the banning. checkSession(); $newBan = empty($_POST['bid']); // Array for holding moderation log data. $modlogInfo = array(); // Check ban type data and start the query to adjust/add the ban. if ($_POST['bantype'] == 'ip_ban') { $ip_parts = ip2range($_POST['ip']); if (count($ip_parts) != 4) fatal_lang_error('invalid_ip'); if ($newBan) { $insert1 = 'ip_low1, ip_high1, ip_low2, ip_high2, ip_low3, ip_high3, ip_low4, ip_high4'; $insert2 = $ip_parts[0]['low'] . ', ' . $ip_parts[0]['high'] . ', ' . $ip_parts[1]['low'] . ', ' . $ip_parts[1]['high'] . ', ' . $ip_parts[2]['low'] . ', ' . $ip_parts[2]['high'] . ', ' . $ip_parts[3]['low'] . ', ' . $ip_parts[3]['high']; } else $update = ' ip_low1 = ' . $ip_parts[0]['low'] . ', ip_high1 = ' . $ip_parts[0]['high'] . ', ip_low2 = ' . $ip_parts[1]['low'] . ', ip_high2 = ' . $ip_parts[1]['high'] . ', ip_low3 = ' . $ip_parts[2]['low'] . ', ip_high3 = ' . $ip_parts[2]['high'] . ', ip_low4 = ' . $ip_parts[3]['low'] . ', ip_high4 = ' . $ip_parts[3]['high'] . ', hostname = NULL, email_address = NULL, ID_MEMBER = NULL'; $modlogInfo['ip_range'] = $_POST['ip']; } elseif ($_POST['bantype'] == 'hostname_ban') { if (preg_match("/[^\w.\-*]/", $_POST['hostname'])) fatal_lang_error('invalid_hostname'); // Replace the * wildcard by a MySQL compatible wildcard %. $_POST['hostname'] = str_replace('*', '%', $_POST['hostname']); if ($newBan) { $insert1 = 'hostname'; $insert2 = "'$_POST[hostname]'"; } else $update = " ip_low1 = NULL, ip_high1 = NULL, ip_low2 = NULL, ip_high2 = NULL, ip_low3 = NULL, ip_high3 = NULL, ip_low4 = NULL, ip_high4 = NULL, hostname = '$_POST[hostname]', email_address = NULL, ID_MEMBER = NULL"; $modlogInfo['hostname'] = $_POST['hostname']; } elseif ($_POST['bantype'] == 'email_ban') { if (preg_match("/[^\w.\-*@]/", $_POST['email'])) fatal_lang_error('invalid_email'); $_POST['email'] = strtolower(str_replace('*', '%', $_POST['email'])); // Check the user is not banning an admin. $request = db_query(" SELECT ID_MEMBER FROM {$db_prefix}members WHERE (ID_GROUP = 1 OR FIND_IN_SET(1, additionalGroups)) AND emailAddress = '$_POST[email]' LIMIT 1", __FILE__, __LINE__); if (mysql_num_rows($request) != 0) fatal_lang_error('no_ban_admin'); mysql_free_result($request); if ($newBan) { $insert1 = 'email_address'; $insert2 = "'$_POST[email]'"; } else $update = " ip_low1 = NULL, ip_high1 = NULL, ip_low2 = NULL, ip_high2 = NULL, ip_low3 = NULL, ip_high3 = NULL, ip_low4 = NULL, ip_high4 = NULL, hostname = NULL, email_address = '$_POST[email]', ID_MEMBER = NULL"; $modlogInfo['email'] = $_POST['email']; } elseif ($_POST['bantype'] == 'user_ban') { $request = db_query(" SELECT ID_MEMBER, (ID_GROUP = 1 OR FIND_IN_SET(1, additionalGroups)) FROM {$db_prefix}members WHERE memberName = '$_POST[banneduser]' LIMIT 1", __FILE__, __LINE__); if (mysql_num_rows($request) == 0) fatal_lang_error('invalid_username'); list ($memberid, $isAdmin) = mysql_fetch_row($request); mysql_free_result($request); if ($isAdmin) fatal_lang_error('no_ban_admin'); if ($newBan) { $insert1 = 'ID_MEMBER'; $insert2 = $memberid; } else $update = " ip_low1 = NULL, ip_high1 = NULL, ip_low2 = NULL, ip_high2 = NULL, ip_low3 = NULL, ip_high3 = NULL, ip_low4 = NULL, ip_high4 = NULL, hostname = NULL, email_address = NULL, ID_MEMBER = $memberid"; $modlogInfo['member'] = $memberid; } else fatal_lang_error('no_bantype_selected'); $_POST['reason'] = htmlspecialchars($_POST['reason'], ENT_QUOTES); $_POST['notes'] = htmlspecialchars($_POST['notes'], ENT_QUOTES); $_POST['notes'] = str_replace(array("\r", "\n", ' '), array('', '
', '  '), $_POST['notes']); if (!in_array($_POST['restriction'], array('full_ban', 'cannot_post', 'cannot_register'))) fatal_lang_error('ban_unknown_restriction_type'); if (empty($_POST['expiration']) || ($_POST['expiration'] != 'never' && (int) $_POST['expire_date'] == 0)) fatal_lang_error('invalid_expiration_date'); if ($newBan) $result = db_query(" INSERT INTO {$db_prefix}banned ($insert1, ban_type, reason, notes, restriction_type, ban_time, expire_time) VALUES ($insert2, '$_POST[bantype]', '$_POST[reason]', '$_POST[notes]', '$_POST[restriction]', " . time() . ", " . ($_POST['expiration'] == 'never' ? 'NULL' : time() + 24 * 60 * 60 * (int) $_POST['expire_date']) . ")", __FILE__, __LINE__); else $result = db_query(" UPDATE {$db_prefix}banned SET $update, ban_type = '$_POST[bantype]', reason = '$_POST[reason]', notes = '$_POST[notes]', restriction_type = '$_POST[restriction]', expire_time = " . ($_POST['expiration'] == 'never' ? 'NULL' : ($_POST['expire_date'] != $_POST['old_expire'] ? time() + 24 * 60 * 60 * (int) $_POST['expire_date'] : 'expire_time')) . " WHERE ID_BAN = $_POST[bid] LIMIT 1", __FILE__, __LINE__); // Log the ban into the moderation log. logAction('ban', $modlogInfo + array( 'new' => $newBan, 'type' => $_POST['bantype'], 'reason' => $_POST['reason'] )); // Register the last modified date. updateSettings(array('banLastUpdated' => time())); redirectexit('action=ban'); } function BanLog() { global $db_prefix, $scripturl, $context, $db_connection; $sort_columns = array( 'name' => 'mem.realName', 'ip' => 'lb.ip', 'email' => 'lb.email', 'date' => 'lb.logTime', ); // The number of entries to show per page of the ban log. $entries_per_page = 30; // Delete one or more entries. if (!empty($_POST['removeAll']) || (!empty($_POST['removeSelected']) && !empty($_POST['remove']))) { checkSession(); // 'Delete all entries' button was pressed. if (!empty($_POST['removeAll'])) { mysql_query(" TRUNCATE {$db_prefix}log_banned", $db_connection); db_query(" DELETE FROM {$db_prefix}log_banned", __FILE__, __LINE__); } // 'Delte selection' button was pressed. else { // Make sure every entry is integer. foreach ($_POST['remove'] as $index => $log_id) $_POST['remove'][$index] = (int) $log_id; db_query(" DELETE FROM {$db_prefix}log_banned WHERE ID_BAN_LOG IN (" . implode(', ', $_POST['remove']) . ')', __FILE__, __LINE__); } } // Count the total number of log entries. $request = db_query(" SELECT COUNT(ID_BAN_LOG) FROM {$db_prefix}log_banned", __FILE__, __LINE__); list ($num_ban_log_entries) = mysql_fetch_row($request); mysql_free_result($request); // Set start if not already set. $_REQUEST['start'] = empty($_REQUEST['start']) || $_REQUEST['start'] < 0 ? 0 : (int) $_REQUEST['start']; // Default to newest entries first. if (empty($_REQUEST['sort']) || !isset($sort_columns[$_REQUEST['sort']])) { $_REQUEST['sort'] = 'date'; $_REQUEST['desc'] = true; } $context['sort_direction'] = isset($_REQUEST['desc']) ? 'down' : 'up'; $context['sort'] = $_REQUEST['sort']; $context['page_index'] = constructPageIndex($scripturl . '?action=ban;sa=log;sort=' . $context['sort'] . ($context['sort_direction'] == 'down' ? ';desc' : ''), $_REQUEST['start'], $num_ban_log_entries, $entries_per_page); $context['start'] = $_REQUEST['start']; $request = db_query(" SELECT lb.ID_BAN_LOG, lb.ID_MEMBER, IFNULL(lb.ip, '-') AS ip, IFNULL(lb.email, '-') AS email, lb.logTime, IFNULL(mem.realName, '') AS realName FROM {$db_prefix}log_banned AS lb LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = lb.ID_MEMBER) ORDER BY " . $sort_columns[$context['sort']] . (isset($_REQUEST['desc']) ? ' DESC' : '') . " LIMIT $_REQUEST[start], $entries_per_page", __FILE__, __LINE__); $context['log_entries'] = array(); while ($row = mysql_fetch_assoc($request)) $context['log_entries'][] = array( 'id' => $row['ID_BAN_LOG'], 'member' => array( 'id' => $row['ID_MEMBER'], 'name' => $row['realName'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_MEMBER'], 'link' => '' . $row['realName'] . '', ), 'ip' => $row['ip'], 'email' => $row['email'], 'date' => timeformat($row['logTime']), ); $context['sub_template'] = 'ban_log'; } function range2ip($low, $high) { if (count($low) != 4 || count($high) != 4) return ''; $ip = array(); for ($i = 0; $i < 4; $i++) { if ($low[$i] == $high[$i]) $ip[$i] = $low[$i]; elseif ($low[$i] == '0' && $high[$i] == '255') $ip[$i] = '*'; else $ip[$i] = $low[$i] . '-' . $high[$i]; } // Pretending is fun... the IP can't be this, so use it for 'unknown'. if ($ip == array(255, 255, 255, 255)) return 'unknown'; return implode('.', $ip); } // Convert a single IP to a ranged IP. function ip2range($fullip) { // Pretend that 'unknown' is 255.255.255.255. (since that can't be an IP anyway.) if ($fullip == 'unknown') $fullip = '255.255.255.255'; $ip_parts = explode('.', $fullip); $ip_array = array(); if (count($ip_parts) != 4) return array(); for ($i = 0; $i < 4; $i++) { if ($ip_parts[$i] == '*') $ip_array[$i] = array('low' => '0', 'high' => '255'); elseif (preg_match('/^(\d{1,3})\-(\d{1,3})$/', $ip_parts[$i], $range)) $ip_array[$i] = array('low' => $range[1], 'high' => $range[2]); elseif (is_numeric($ip_parts[$i])) $ip_array[$i] = array('low' => $ip_parts[$i], 'high' => $ip_parts[$i]); } return $ip_array; } // Set reserved names/words.... function SetReserve() { global $txt, $db_prefix, $context, $modSettings; isAllowedTo('moderate_forum'); // Select it on the admin bar. adminIndex('edit_reserved_names'); loadTemplate('ManageMembers'); // Get the reserved word options and words. $context['reserved_words'] = explode("\n", $modSettings['reserveNames']); $context['reserved_word_options'] = array(); $context['reserved_word_options']['match_word'] = $modSettings['reserveWord'] == '1'; $context['reserved_word_options']['match_case'] = $modSettings['reserveCase'] == '1'; $context['reserved_word_options']['match_user'] = $modSettings['reserveUser'] == '1'; $context['reserved_word_options']['match_name'] = $modSettings['reserveName'] == '1'; // Ready the template...... $context['sub_template'] = 'edit_reserved_words'; $context['page_title'] = $txt[341]; } function SetReserve2() { global $db_prefix; // Only if you have proper permissions! isAllowedTo('moderate_forum'); checkSession(); // Set all the options.... updateSettings(array( 'reserveWord' => (isset($_POST['matchword']) ? '1' : '0'), 'reserveCase' => (isset($_POST['matchcase']) ? '1' : '0'), 'reserveUser' => (isset($_POST['matchuser']) ? '1' : '0'), 'reserveName' => (isset($_POST['matchname']) ? '1' : '0'), 'reserveNames' => str_replace("\r", '', $_POST['reserved']) )); redirectexit('action=admin'); } function trackUser($memID) { global $scripturl, $txt, $db_prefix; global $user_profile, $context; // Verify if the user has sufficient permissions. isAllowedTo('moderate_forum'); loadTemplate('ManageMembers'); $context['page_title'] = $txt['trackUser'] . ' - ' . $user_profile[$memID]['realName']; $context['last_ip'] = $user_profile[$memID]['memberIP']; $context['member']['name'] = $user_profile[$memID]['realName']; $ips = array(); // Get all IP addresses this user has used for his messages. $request = db_query(" SELECT posterIP FROM {$db_prefix}messages WHERE ID_MEMBER = $memID AND posterIP<>'' GROUP BY posterIP", __FILE__, __LINE__); $context['ips'] = array(); while ($row = mysql_fetch_assoc($request)) { $context['ips'][] = '' . $row['posterIP'] . ''; $ips[] = $row['posterIP']; } mysql_free_result($request); // Now also get the IP addresses from the error messages. $request = db_query(" SELECT COUNT(ID_MEMBER) AS errorCount, IP FROM {$db_prefix}log_errors WHERE ID_MEMBER = $memID GROUP BY IP", __FILE__, __LINE__); $context['error_ips'] = array(); $totalErrors = 0; while ($row = mysql_fetch_assoc($request)) { $context['error_ips'][] = '' . $row['IP'] . ''; $ips[] = $row['IP']; $totalErrors += $row['errorCount']; } mysql_free_result($request); // Create the page indexes. $context['page_index'] = constructPageIndex($scripturl . '?action=profile;u=' . $memID . ';sa=trackUser', $_REQUEST['start'], $totalErrors, 20); $context['start'] = $_REQUEST['start']; // Get a list of error messages from this ip (range). $request = db_query(" SELECT le.logTime, le.IP, le.url, le.message, IFNULL(mem.ID_MEMBER, 0) AS ID_MEMBER, IFNULL(mem.realName, '$txt[28]') AS display_name, mem.memberName FROM {$db_prefix}log_errors AS le LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = le.ID_MEMBER) WHERE le.ID_MEMBER = $memID ORDER BY le.ID_ERROR DESC LIMIT $context[start], 20", __FILE__, __LINE__); $context['error_messages'] = array(); while ($row = mysql_fetch_assoc($request)) $context['error_messages'][] = array( 'ip' => $row['IP'], 'message' => $row['message'], 'url' => $row['url'], 'time' => timeformat($row['logTime']), 'timestamp' => $row['logTime'] ); mysql_free_result($request); // Find other users that might use the same IP. $ips = array_unique($ips); $context['members_in_range'] = array(); if (!empty($ips)) { $request = db_query(" SELECT ID_MEMBER, realName FROM {$db_prefix}members WHERE ID_MEMBER != $memID AND memberIP IN ('" . implode("', '", $ips) . "')", __FILE__, __LINE__); if (mysql_num_rows($request) > 0) while ($row = mysql_fetch_assoc($request)) $context['members_in_range'][$row['ID_MEMBER']] = '' . $row['realName'] . ''; $request = db_query(" SELECT mem.ID_MEMBER, mem.realName FROM {$db_prefix}messages AS m, {$db_prefix}members AS mem WHERE mem.ID_MEMBER = m.ID_MEMBER AND mem.ID_MEMBER != $memID AND m.posterIP IN ('" . implode("', '", $ips) . "')", __FILE__, __LINE__); if (mysql_num_rows($request) > 0) while ($row = mysql_fetch_assoc($request)) $context['members_in_range'][$row['ID_MEMBER']] = '' . $row['realName'] . ''; } } function trackIP($memID = 0) { global $user_profile, $scripturl, $txt; global $db_prefix, $context; // Can the user do this? isAllowedTo('moderate_forum'); loadTemplate('ManageMembers'); if ($memID == 0) { $searchip = $_REQUEST['searchip']; loadLanguage('Profile'); $context['sub_template'] = 'trackIP'; $context['page_title'] = $txt[79]; } else $searchip = $user_profile[$memID]['memberIP']; $context['ip'] = $searchip; if (!preg_match('/^\d{1,3}\.(\d{1,3}|\*)\.(\d{1,3}|\*)\.(\d{1,3}|\*)$/', $searchip)) fatal_error($txt['invalid_ip'], false); $dbip = str_replace('*', '%', $searchip); $context['page_title'] = $txt['trackIP'] . ' - ' . $searchip; // Get some totals for pagination. $request = db_query(" SELECT COUNT(ID_MSG) FROM {$db_prefix}messages WHERE posterIP LIKE '$dbip'", __FILE__, __LINE__); list ($totalMessages) = mysql_fetch_row($request); mysql_free_result($request); $request = db_query(" SELECT COUNT(ID_MEMBER) FROM {$db_prefix}log_errors WHERE IP LIKE '$dbip'", __FILE__, __LINE__); list ($totalErrors) = mysql_fetch_row($request); mysql_free_result($request); $context['message_start'] = isset($_GET['mes']) ? $_REQUEST['start'] : 0; $context['error_start'] = isset($_GET['err']) ? $_REQUEST['start'] : 0; $context['message_page_index'] = constructPageIndex($scripturl . '?action=' . ($memID == 0 ? 'trackip;searchip=' . $context['ip'] : 'profile;u=' . $memID . ';sa=trackIP') . ';mes', $context['message_start'], $totalMessages, 20); $context['error_page_index'] = constructPageIndex($scripturl . '?action=' . ($memID == 0 ? 'trackip;searchip=' . $context['ip'] : 'profile;u=' . $memID . ';sa=trackIP') . ';err', $context['error_start'], $totalErrors, 20); $request = db_query(" SELECT ID_MEMBER, IFNULL(realName, memberName) AS display_name, memberIP FROM {$db_prefix}members WHERE memberIP LIKE '$dbip'", __FILE__, __LINE__); $context['ips'] = array(); while ($row = mysql_fetch_assoc($request)) $context['ips'][$row['memberIP']][] = '' . $row['display_name'] . ''; mysql_free_result($request); ksort($context['ips']); $request = db_query(" SELECT m.ID_MSG, m.posterIP, IFNULL(mem.realName, m.posterName) AS display_name, mem.ID_MEMBER, m.subject, m.posterTime, m.ID_TOPIC, m.ID_BOARD FROM {$db_prefix}messages AS m LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.ID_MEMBER) WHERE m.posterIP LIKE '$dbip' ORDER BY m.posterIP LIMIT $context[message_start], 20", __FILE__, __LINE__); $context['messages'] = array(); while ($row = mysql_fetch_assoc($request)) $context['messages'][] = array( 'ip' => $row['posterIP'], 'member' => array( 'id' => $row['ID_MEMBER'], 'name' => $row['display_name'], 'href' => $scripturl . '?action=profile;u=' . $row['ID_MEMBER'], 'link' => '' . $row['display_name'] . '' ), 'board' => array( 'id' => $row['ID_BOARD'], 'href' => $scripturl . '?board=' . $row['ID_BOARD'] ), 'topic' => $row['ID_TOPIC'], 'id' => $row['ID_MSG'], 'subject' => $row['subject'], 'time' => timeformat($row['posterTime']), 'timestamp' => $row['posterTime'] ); mysql_free_result($request); $request = db_query(" SELECT le.logTime, le.IP, le.url, le.message, IFNULL(mem.ID_MEMBER, 0) AS ID_MEMBER, IFNULL(mem.realName, '$txt[28]') AS display_name, mem.memberName FROM {$db_prefix}log_errors AS le LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = le.ID_MEMBER) WHERE le.IP LIKE '$dbip' ORDER BY le.IP LIMIT $context[error_start], 20", __FILE__, __LINE__); $context['error_messages'] = array(); while ($row = mysql_fetch_assoc($request)) $context['error_messages'][] = array( 'ip' => $row['IP'], 'member' => array( 'id' => $row['ID_MEMBER'], 'name' => $row['display_name'], 'href' => $row['ID_MEMBER'] > 0 ? $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] : '', 'link' => $row['ID_MEMBER'] > 0 ? '' . $row['display_name'] . '' : $row['display_name'] ), 'message' => $row['message'], 'url' => $row['url'], 'error_time' => timeformat($row['logTime']) ); mysql_free_result($request); $context['single_ip'] = strpos($searchip, '*') === false; if ($context['single_ip']) { // In the future, AfriNIC will be added to this list. $context['whois_servers'] = array( 'apnic' => array( 'name' => &$txt['whois_apnic'], 'url' => 'http://www.apnic.net/apnic-bin/whois2.pl?searchtext=' . $searchip ), 'arin' => array( 'name' => &$txt['whois_arin'], 'url' => 'http://ws.arin.net/cgi-bin/whois.pl?queryinput=' . $searchip ), 'lacnic' => array( 'name' => &$txt['whois_lacnic'], 'url' => 'http://lacnic.net/cgi-bin/lacnic/whois?lg=EN&query=' . $searchip ), 'ripe' => array( 'name' => &$txt['whois_ripe'], 'url' => 'http://www.ripe.net/perl/whois?searchtext=' . $searchip ), ); } } function showPermissions($memID) { global $scripturl, $txt, $db_prefix, $board; global $user_profile, $context, $user_info; // Verify if the user has sufficient permissions. isAllowedTo('manage_permissions'); loadTemplate('ManageMembers'); loadLanguage('ManagePermissions'); loadLanguage('Admin'); $context['member']['id'] = $memID; $context['member']['name'] = $user_profile[$memID]['realName']; $context['page_title'] = $txt['showPermissions']; $board = empty($board) ? 0 : (int) $board; $context['board'] = $board; // Load a list of boards for the jump box (but only those that have separate local permissions). $result = db_query(" SELECT b.ID_BOARD, b.name FROM {$db_prefix}boards AS b WHERE $user_info[query_see_board] AND use_local_permissions = 1", __FILE__, __LINE__); $context['boards'] = array(); while ($row = mysql_fetch_assoc($result)) $context['boards'][$row['ID_BOARD']] = array( 'id' => $row['ID_BOARD'], 'name' => $row['name'], 'selected' => $board == $row['ID_BOARD'] ); mysql_free_result($result); // Determine which groups this user is in. if (empty($user_profile[$memID]['additionalGroups'])) $curGroups = array(); else $curGroups = explode(',', $user_profile[$memID]['additionalGroups']); $curGroups[] = $user_profile[$memID]['ID_GROUP']; $curGroups[] = $user_profile[$memID]['ID_POST_GROUP']; $context['member']['permissions'] = array( 'general' => array(), 'board' => array() ); // If you're an admin we know you can do everything, we might as well leave. $context['member']['has_all_permissions'] = in_array(1, $curGroups); if ($context['member']['has_all_permissions']) return; $denied = array(); // Get all general permissions. $result = db_query(" SELECT p.permission, p.addDeny, mg.groupName, p.ID_GROUP FROM {$db_prefix}permissions AS p LEFT JOIN {$db_prefix}membergroups AS mg ON (mg.ID_GROUP = p.ID_GROUP) WHERE p.ID_GROUP IN (" . implode(', ', $curGroups) . ") ORDER BY p.permission, mg.minPosts, IF(mg.ID_GROUP < 4, mg.ID_GROUP, 4), mg.groupName", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($result)) { // We don't know about this permission, it doesn't exist :P. if (!isset($txt['permissionname_' . $row['permission']])) continue; if (empty($row['addDeny'])) $denied[] = $row['permission']; // Permissions that end with _own or _any consist of two parts. if (in_array(substr($row['permission'], -4), array('_own', '_any')) && isset($txt['permissionname_' . substr($row['permission'], 0, -4)])) $name = $txt['permissionname_' . substr($row['permission'], 0, -4)] . ' - ' . $txt['permissionname_' . $row['permission']]; else $name = $txt['permissionname_' . $row['permission']]; // Add this permission if it doesn't exist yet. if (!isset($context['member']['permissions']['general'][$row['permission']])) $context['member']['permissions']['general'][$row['permission']] = array( 'id' => $row['permission'], 'groups' => array( 'allowed' => array(), 'denied' => array() ), 'name' => $name, 'is_denied' => false, 'is_global' => true, ); // Add the membergroup to either the denied or the allowed groups. $context['member']['permissions']['general'][$row['permission']]['groups'][empty($row['addDeny']) ? 'denied' : 'allowed'][] = $row['ID_GROUP'] == 0 ? $txt['membergroups_members'] : $row['groupName']; // Once denied is always denied. $context['member']['permissions']['general'][$row['permission']]['is_denied'] = in_array($row['permission'], $denied); } mysql_free_result($result); // Retrieve the board specific permissions. $result = db_query(" SELECT bp.ID_BOARD, bp.permission, bp.addDeny, mg.groupName, bp.ID_GROUP, b.use_local_permissions, b.name FROM {$db_prefix}board_permissions AS bp LEFT JOIN {$db_prefix}boards AS b ON (b.ID_BOARD = bp.ID_BOARD) LEFT JOIN {$db_prefix}membergroups AS mg ON (mg.ID_GROUP = bp.ID_GROUP) WHERE bp.ID_GROUP IN (" . implode(', ', $curGroups) . ")" . (empty($board) ? '' : " AND bp.ID_BOARD = $board") . " ORDER BY bp.permission, b.boardOrder, mg.minPosts, IF(mg.ID_GROUP < 4, mg.ID_GROUP, 4), mg.groupName", __FILE__, __LINE__); while ($row = mysql_fetch_assoc($result)) { // We don't know about this permission, it doesn't exist :P. if (!isset($txt['permissionname_' . $row['permission']])) continue; // The name of the permission using the format 'permission name' - 'own/any topic/event/etc.'. if (in_array(substr($row['permission'], -4), array('_own', '_any')) && isset($txt['permissionname_' . substr($row['permission'], 0, -4)])) $name = $txt['permissionname_' . substr($row['permission'], 0, -4)] . ' - ' . $txt['permissionname_' . $row['permission']]; else $name = $txt['permissionname_' . $row['permission']]; // Create the structure for this permission. if (!isset($context['member']['permissions']['board'][$row['permission']])) $context['member']['permissions']['board'][$row['permission']] = array( 'id' => $row['permission'], 'groups' => array( 'allowed' => array(), 'denied' => array() ), 'name' => $name, 'boards' => array( 'allowed' => array(), 'denied' => array(), ), 'is_denied' => false, 'is_global' => false, ); // Either we're dealing with global permissions, or we've selected a board to be shown. if (empty($row['ID_BOARD']) || !empty($board)) { $context['member']['permissions']['board'][$row['permission']]['is_global'] = true; $context['member']['permissions']['board'][$row['permission']]['groups'][empty($row['addDeny']) ? 'denied' : 'allowed'][$row['ID_GROUP']] = $row['ID_GROUP'] == 0 ? $txt['membergroups_members'] : $row['groupName']; $context['member']['permissions']['board'][$row['permission']]['is_denied'] = $context['member']['permissions']['board'][$row['permission']]['is_denied'] || empty($row['addDeny']); } // This is a local permission, make sure this board actually uses local permissions. elseif (!empty($row['use_local_permissions'])) { // Deny this permission. if (empty($row['addDeny'])) { $context['member']['permissions']['board'][$row['permission']]['boards']['denied'][$row['ID_BOARD']] = $row['name']; // Remove the board from the allowed array. if (isset($context['member']['permissions']['board'][$row['permission']]['boards']['allowed'][$row['ID_BOARD']])) unset($context['member']['permissions']['board'][$row['permission']]['boards']['allowed'][$row['ID_BOARD']]); } // Allow only if it's not denied. elseif (!in_array($row['ID_BOARD'], array_keys($context['member']['permissions']['board'][$row['permission']]['boards']['denied']))) $context['member']['permissions']['board'][$row['permission']]['boards']['allowed'][$row['ID_BOARD']] = $row['name']; } } mysql_free_result($result); // Get rid of denied permissions if you're looking at a specific board. if (!empty($board)) { foreach ($context['member']['permissions']['board'] as $ID_PERM => $permission) if ($permission['is_denied']) unset($context['member']['permissions']['board'][$ID_PERM]); } else { foreach ($context['member']['permissions']['board'] as $ID_PERM => $permission) { // Get rid of permissions that are only locally set and on deny. if (!$permission['is_global'] && empty($permission['boards']['allowed'])) unset($context['member']['permissions']['board'][$ID_PERM]); // Get rid of permissions that are globally on deny and nowhere locally set. elseif ($permission['is_global'] && $permission['is_denied'] && empty($permission['boards']['allowed'])) unset($context['member']['permissions']['board'][$ID_PERM]); } } } // This function is used to reassociate members with relevant posts. function reattributePosts($memID, $email = false, $post_count = false) { global $db_prefix; // Firstly, if $email isn't passed find out the members email address. if ($email === false) { $request = db_query(" SELECT emailAddress FROM {$db_prefix}members WHERE ID_MEMBER = $memID LIMIT 1", __FILE__, __LINE__); list ($email) = mysql_fetch_row($request); mysql_free_result($request); } // If they want the post count restored then we need to do some research. if ($post_count) { $request = db_query(" SELECT COUNT(m.ID_MSG) FROM {$db_prefix}messages AS m, {$db_prefix}boards AS b WHERE m.ID_MEMBER = 0 AND m.posterEmail = '$email' AND b.ID_BOARD = m.ID_MEMBER AND b.countPosts = 1", __FILE__, __LINE__); list ($messageCount) = mysql_fetch_row($request); mysql_free_result($request); db_query(" UPDATE {$db_prefix}members SET posts = posts + $messageCount WHERE ID_MEMBER = $memID LIMIT 1", __FILE__, __LINE__); } // Finally, update the posts themselves... db_query(" UPDATE {$db_prefix}messages SET ID_MEMBER = $memID WHERE posterEmail = '$email'", __FILE__, __LINE__); return db_affected_rows(); } ?>