Example #1
0
/**
 * Loads an array of users' data by ID or member_name.
 *
 * @param int[]|int|string[]|string $users An array of users by id or name
 * @param bool $is_name = false $users is by name or by id
 * @param string $set = 'normal' What kind of data to load (normal, profile, minimal)
 * @return array|bool The ids of the members loaded or false
 */
function loadMemberData($users, $is_name = false, $set = 'normal')
{
    global $user_profile, $modSettings, $board_info, $context;
    $db = database();
    // Can't just look for no users :P.
    if (empty($users)) {
        return false;
    }
    // Pass the set value
    $context['loadMemberContext_set'] = $set;
    // Make sure it's an array.
    $users = !is_array($users) ? array($users) : array_unique($users);
    $loaded_ids = array();
    if (!$is_name && !empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 3) {
        $users = array_values($users);
        for ($i = 0, $n = count($users); $i < $n; $i++) {
            $data = cache_get_data('member_data-' . $set . '-' . $users[$i], 240);
            if ($data == null) {
                continue;
            }
            $loaded_ids[] = $data['id_member'];
            $user_profile[$data['id_member']] = $data;
            unset($users[$i]);
        }
    }
    // Used by default
    $select_columns = '
			IFNULL(lo.log_time, 0) AS is_online, IFNULL(a.id_attach, 0) AS id_attach, a.filename, a.attachment_type,
			mem.signature, mem.personal_text, mem.location, mem.gender, mem.avatar, mem.id_member, mem.member_name,
			mem.real_name, mem.email_address, mem.hide_email, mem.date_registered, mem.website_title, mem.website_url,
			mem.birthdate, mem.member_ip, mem.member_ip2, mem.posts, mem.last_login, mem.likes_given, mem.likes_received,
			mem.karma_good, mem.id_post_group, mem.karma_bad, mem.lngfile, mem.id_group, mem.time_offset, mem.show_online,
			mg.online_color AS member_group_color, IFNULL(mg.group_name, {string:blank_string}) AS member_group,
			pg.online_color AS post_group_color, IFNULL(pg.group_name, {string:blank_string}) AS post_group,
			mem.is_activated, mem.warning, ' . (!empty($modSettings['titlesEnable']) ? 'mem.usertitle, ' : '') . '
			CASE WHEN mem.id_group = 0 OR mg.icons = {string:blank_string} THEN pg.icons ELSE mg.icons END AS icons';
    $select_tables = '
			LEFT JOIN {db_prefix}log_online AS lo ON (lo.id_member = mem.id_member)
			LEFT JOIN {db_prefix}attachments AS a ON (a.id_member = mem.id_member)
			LEFT JOIN {db_prefix}membergroups AS pg ON (pg.id_group = mem.id_post_group)
			LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = mem.id_group)';
    // We add or replace according to the set
    switch ($set) {
        case 'normal':
            $select_columns .= ', mem.buddy_list';
            break;
        case 'profile':
            $select_columns .= ', mem.openid_uri, mem.id_theme, mem.pm_ignore_list, mem.pm_email_notify, mem.receive_from,
			mem.time_format, mem.secret_question, mem.additional_groups, mem.smiley_set,
			mem.total_time_logged_in, mem.notify_announcements, mem.notify_regularity, mem.notify_send_body,
			mem.notify_types, lo.url, mem.ignore_boards, mem.password_salt, mem.pm_prefs, mem.buddy_list';
            break;
        case 'minimal':
            $select_columns = '
			mem.id_member, mem.member_name, mem.real_name, mem.email_address, mem.hide_email, mem.date_registered,
			mem.posts, mem.last_login, mem.member_ip, mem.member_ip2, mem.lngfile, mem.id_group';
            $select_tables = '';
            break;
        default:
            trigger_error('loadMemberData(): Invalid member data set \'' . $set . '\'', E_USER_WARNING);
    }
    // Allow addons to easily add to the selected member data
    call_integration_hook('integrate_load_member_data', array(&$select_columns, &$select_tables, $set));
    if (!empty($users)) {
        // Load the member's data.
        $request = $db->query('', '
			SELECT' . $select_columns . '
			FROM {db_prefix}members AS mem' . $select_tables . '
			WHERE mem.' . ($is_name ? 'member_name' : 'id_member') . (count($users) == 1 ? ' = {' . ($is_name ? 'string' : 'int') . ':users}' : ' IN ({' . ($is_name ? 'array_string' : 'array_int') . ':users})'), array('blank_string' => '', 'users' => count($users) == 1 ? current($users) : $users));
        $new_loaded_ids = array();
        while ($row = $db->fetch_assoc($request)) {
            $new_loaded_ids[] = $row['id_member'];
            $loaded_ids[] = $row['id_member'];
            $row['options'] = array();
            $user_profile[$row['id_member']] = $row;
        }
        $db->free_result($request);
    }
    // Custom profile fields as well
    if (!empty($new_loaded_ids) && $set !== 'minimal' && in_array('cp', $context['admin_features'])) {
        $request = $db->query('', '
			SELECT id_member, variable, value
			FROM {db_prefix}custom_fields_data
			WHERE id_member' . (count($new_loaded_ids) == 1 ? ' = {int:loaded_ids}' : ' IN ({array_int:loaded_ids})'), array('loaded_ids' => count($new_loaded_ids) == 1 ? $new_loaded_ids[0] : $new_loaded_ids));
        while ($row = $db->fetch_assoc($request)) {
            $user_profile[$row['id_member']]['options'][$row['variable']] = $row['value'];
        }
        $db->free_result($request);
    }
    // Anthing else integration may want to add to the user_profile array
    if (!empty($new_loaded_ids)) {
        call_integration_hook('integrate_add_member_data', array($new_loaded_ids, $set));
    }
    if (!empty($new_loaded_ids) && !empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 3) {
        for ($i = 0, $n = count($new_loaded_ids); $i < $n; $i++) {
            cache_put_data('member_data-' . $set . '-' . $new_loaded_ids[$i], $user_profile[$new_loaded_ids[$i]], 240);
        }
    }
    // Are we loading any moderators?  If so, fix their group data...
    if (!empty($loaded_ids) && !empty($board_info['moderators']) && $set === 'normal' && count($temp_mods = array_intersect($loaded_ids, array_keys($board_info['moderators']))) !== 0) {
        if (($group_info = cache_get_data('moderator_group_info', 480)) == null) {
            require_once SUBSDIR . '/Membergroups.subs.php';
            $group_info = membergroupById(3, true);
            cache_put_data('moderator_group_info', $group_info, 480);
        }
        foreach ($temp_mods as $id) {
            // By popular demand, don't show admins or global moderators as moderators.
            if ($user_profile[$id]['id_group'] != 1 && $user_profile[$id]['id_group'] != 2) {
                $user_profile[$id]['member_group'] = $group_info['group_name'];
            }
            // If the Moderator group has no color or icons, but their group does... don't overwrite.
            if (!empty($group_info['icons'])) {
                $user_profile[$id]['icons'] = $group_info['icons'];
            }
            if (!empty($group_info['online_color'])) {
                $user_profile[$id]['member_group_color'] = $group_info['online_color'];
            }
        }
    }
    return empty($loaded_ids) ? false : $loaded_ids;
}
Example #2
0
/**
 * Updates the properties of a copied membergroup.
 *
 * @package Membergroups
 * @param int $id_group
 * @param int $copy_from
 */
function updateCopiedGroup($id_group, $copy_from)
{
    $db = database();
    require_once SUBSDIR . '/Membergroups.subs.php';
    $group_info = membergroupById($copy_from, true);
    // update the new membergroup
    $db->query('', '
		UPDATE {db_prefix}membergroups
		SET
			online_color = {string:online_color},
			max_messages = {int:max_messages},
			icons = {string:icons}
			WHERE id_group = {int:current_group}', array('max_messages' => $group_info['max_messages'], 'current_group' => $id_group, 'online_color' => $group_info['online_color'], 'icons' => $group_info['icons']));
}
 /**
  * Editing a membergroup.
  *
  * What it does:
  * - Screen to edit a specific membergroup.
  * - Called by ?action=admin;area=membergroups;sa=edit;group=x.
  * - It requires the manage_membergroups permission.
  * - Also handles the delete button of the edit form.
  * - Redirects to ?action=admin;area=membergroups.
  *
  * @uses the edit_group sub template of ManageMembergroups.
  */
 public function action_edit()
 {
     global $context, $txt, $modSettings;
     $current_group_id = isset($_REQUEST['group']) ? (int) $_REQUEST['group'] : 0;
     if (!empty($modSettings['deny_boards_access'])) {
         loadLanguage('ManagePermissions');
     }
     require_once SUBSDIR . '/Membergroups.subs.php';
     // Make sure this group is editable.
     if (!empty($current_group_id)) {
         $current_group = membergroupById($current_group_id);
     }
     // Now, do we have a valid id?
     if (!allowedTo('admin_forum') && !empty($current_group_id) && $current_group['group_type'] == 1) {
         fatal_lang_error('membergroup_does_not_exist', false);
     }
     // The delete this membergroup button was pressed.
     if (isset($_POST['delete'])) {
         checkSession();
         validateToken('admin-mmg');
         if (empty($current_group_id)) {
             fatal_lang_error('membergroup_does_not_exist', false);
         }
         // Let's delete the group
         deleteMembergroups($current_group['id_group']);
         redirectexit('action=admin;area=membergroups;');
     } elseif (isset($_POST['save'])) {
         // Validate the session.
         checkSession();
         validateToken('admin-mmg');
         if (empty($current_group_id)) {
             fatal_lang_error('membergroup_does_not_exist', false);
         }
         require_once SUBSDIR . '/DataValidator.class.php';
         $validator = new Data_Validator();
         // Cleanup the inputs! :D
         $validator->sanitation_rules(array('max_messages' => 'intval', 'min_posts' => 'intval|abs', 'group_type' => 'intval', 'group_desc' => 'trim|Util::htmlspecialchars', 'group_name' => 'trim|Util::htmlspecialchars', 'group_hidden' => 'intval', 'group_inherit' => 'intval', 'icon_count' => 'intval', 'icon_image' => 'trim|Util::htmlspecialchars', 'online_color' => 'trim|valid_color'));
         $validator->input_processing(array('boardaccess' => 'array'));
         $validator->validation_rules(array('boardaccess' => 'contains[allow,ignore,deny]'));
         $validator->validate($_POST);
         // Can they really inherit from this group?
         if ($validator->group_inherit != -2 && !allowedTo('admin_forum')) {
             $inherit_type = membergroupById($validator->group_inherit);
         }
         $min_posts = $validator->group_type == -1 && $validator->min_posts >= 0 && $current_group['id_group'] > 3 ? $validator->min_posts : ($current_group['id_group'] == 4 ? 0 : -1);
         $group_inherit = $current_group['id_group'] > 1 && $current_group['id_group'] != 3 && (empty($inherit_type['group_type']) || $inherit_type['group_type'] != 1) ? $validator->group_inherit : -2;
         //@todo Don't set online_color for the Moderators group?
         // Do the update of the membergroup settings.
         $properties = array('max_messages' => $validator->max_messages, 'min_posts' => $min_posts, 'group_type' => $validator->group_type < 0 || $validator->group_type > 3 || $validator->group_type == 1 && !allowedTo('admin_forum') ? 0 : $validator->group_type, 'hidden' => !$validator->group_hidden || $min_posts != -1 || $current_group['id_group'] == 3 ? 0 : $validator->group_hidden, 'id_parent' => $group_inherit, 'current_group' => $current_group['id_group'], 'group_name' => $validator->group_name, 'online_color' => $validator->online_color, 'icons' => $validator->icon_count <= 0 ? '' : min($validator->icon_count, 10) . '#' . $validator->icon_image, 'description' => $current_group['id_group'] == 1 || $validator->group_type != -1 ? $validator->group_desc : '');
         updateMembergroupProperties($properties);
         call_integration_hook('integrate_save_membergroup', array($current_group['id_group']));
         // Time to update the boards this membergroup has access to.
         if ($current_group['id_group'] == 2 || $current_group['id_group'] > 3) {
             $changed_boards = array();
             $changed_boards['allow'] = array();
             $changed_boards['deny'] = array();
             $changed_boards['ignore'] = array();
             if ($validator->boardaccess) {
                 foreach ($validator->boardaccess as $group_id => $action) {
                     $changed_boards[$action][] = (int) $group_id;
                 }
             }
             foreach (array('allow', 'deny') as $board_action) {
                 // Find all board this group is in, but shouldn't be in.
                 detachGroupFromBoards($current_group['id_group'], $changed_boards, $board_action);
                 // Add the membergroup to all boards that hadn't been set yet.
                 if (!empty($changed_boards[$board_action])) {
                     assignGroupToBoards($current_group['id_group'], $changed_boards, $board_action);
                 }
             }
         }
         // Remove everyone from this group!
         if ($min_posts != -1) {
             detachDeletedGroupFromMembers($current_group['id_group']);
         } elseif ($current_group['id_group'] != 3) {
             // Making it a hidden group? If so remove everyone with it as primary group (Actually, just make them additional).
             if ($validator->group_hidden == 2) {
                 setGroupToHidden($current_group['id_group']);
             }
             // Either way, let's check our "show group membership" setting is correct.
             validateShowGroupMembership();
         }
         // Do we need to set inherited permissions?
         if ($group_inherit != -2 && $group_inherit != $_POST['old_inherit']) {
             require_once SUBSDIR . '/Permission.subs.php';
             updateChildPermissions($group_inherit);
         }
         // Finally, moderators!
         $moderator_string = isset($_POST['group_moderators']) ? trim($_POST['group_moderators']) : '';
         detachGroupModerators($current_group['id_group']);
         if ((!empty($moderator_string) || !empty($_POST['moderator_list'])) && $min_posts == -1 && $current_group['id_group'] != 3) {
             // Get all the usernames from the string
             if (!empty($moderator_string)) {
                 $moderator_string = strtr(preg_replace('~&amp;#(\\d{4,5}|[2-9]\\d{2,4}|1[2-9]\\d);~', '&#$1;', htmlspecialchars($moderator_string, ENT_QUOTES, 'UTF-8')), array('&quot;' => '"'));
                 preg_match_all('~"([^"]+)"~', $moderator_string, $matches);
                 $moderators = array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $moderator_string)));
                 for ($k = 0, $n = count($moderators); $k < $n; $k++) {
                     $moderators[$k] = trim($moderators[$k]);
                     if (strlen($moderators[$k]) == 0) {
                         unset($moderators[$k]);
                     }
                 }
                 // Find all the id_member's for the member_name's in the list.
                 if (!empty($moderators)) {
                     $group_moderators = getIDMemberFromGroupModerators($moderators);
                 }
             } else {
                 $moderators = array();
                 foreach ($_POST['moderator_list'] as $moderator) {
                     $moderators[] = (int) $moderator;
                 }
                 $group_moderators = array();
                 if (!empty($moderators)) {
                     require_once SUBSDIR . '/Members.subs.php';
                     $members = getBasicMemberData($moderators);
                     foreach ($members as $member) {
                         $group_moderators[] = $member['id_member'];
                     }
                 }
             }
             // Found some?
             if (!empty($group_moderators)) {
                 assignGroupModerators($current_group['id_group'], $group_moderators);
             }
         }
         // There might have been some post group changes.
         updateStats('postgroups');
         // We've definitely changed some group stuff.
         updateSettings(array('settings_updated' => time()));
         // Log the edit.
         logAction('edited_group', array('group' => $validator->group_name), 'admin');
         redirectexit('action=admin;area=membergroups');
     }
     // Fetch the current group information.
     $row = membergroupById($current_group['id_group'], true);
     if (empty($row) || !allowedTo('admin_forum') && $row['group_type'] == 1) {
         fatal_lang_error('membergroup_does_not_exist', false);
     }
     $row['icons'] = explode('#', $row['icons']);
     $context['group'] = array('id' => $row['id_group'], 'name' => $row['group_name'], 'description' => htmlspecialchars($row['description'], ENT_COMPAT, 'UTF-8'), 'editable_name' => $row['group_name'], 'color' => $row['online_color'], 'min_posts' => $row['min_posts'], 'max_messages' => $row['max_messages'], 'icon_count' => (int) $row['icons'][0], 'icon_image' => isset($row['icons'][1]) ? $row['icons'][1] : '', 'is_post_group' => $row['min_posts'] != -1, 'type' => $row['min_posts'] != -1 ? 0 : $row['group_type'], 'hidden' => $row['min_posts'] == -1 ? $row['hidden'] : 0, 'inherited_from' => $row['id_parent'], 'allow_post_group' => $row['id_group'] == 2 || $row['id_group'] > 4, 'allow_delete' => $row['id_group'] == 2 || $row['id_group'] > 4, 'allow_protected' => allowedTo('admin_forum'));
     // Get any moderators for this group
     $context['group']['moderators'] = getGroupModerators($row['id_group']);
     $context['group']['moderator_list'] = empty($context['group']['moderators']) ? '' : '&quot;' . implode('&quot;, &quot;', $context['group']['moderators']) . '&quot;';
     if (!empty($context['group']['moderators'])) {
         list($context['group']['last_moderator_id']) = array_slice(array_keys($context['group']['moderators']), -1);
     }
     // Get a list of boards this membergroup is allowed to see.
     $context['boards'] = array();
     if ($row['id_group'] == 2 || $row['id_group'] > 3) {
         require_once SUBSDIR . '/Boards.subs.php';
         $context += getBoardList(array('override_permissions' => true, 'access' => $row['id_group'], 'not_redirection' => true));
         // Include a list of boards per category for easy toggling.
         foreach ($context['categories'] as $category) {
             $context['categories'][$category['id']]['child_ids'] = array_keys($category['boards']);
         }
     }
     // Finally, get all the groups this could be inherited off.
     $context['inheritable_groups'] = getInheritableGroups($row['id_group']);
     call_integration_hook('integrate_view_membergroup');
     $context['sub_template'] = 'edit_group';
     $context['page_title'] = $txt['membergroups_edit_group'];
     // Use the autosuggest script when needed
     if ($context['group']['id'] != 3 && $context['group']['id'] != 4) {
         loadJavascriptFile('suggest.js', array('defer' => true));
     }
     createToken('admin-mmg');
 }
 /**
  * This function actually saves modifications to a membergroup's board permissions.
  */
 public function action_modify2()
 {
     global $context;
     checkSession();
     validateToken('admin-mp');
     // We'll need to init illegal permissions, update child permissions, etc.
     require_once SUBSDIR . '/Permission.subs.php';
     require_once SUBSDIR . '/ManagePermissions.subs.php';
     loadIllegalPermissions();
     $current_group_id = (int) $_GET['group'];
     $_GET['pid'] = (int) $_GET['pid'];
     // Cannot modify predefined profiles.
     if ($_GET['pid'] > 1 && $_GET['pid'] < 5) {
         fatal_lang_error('no_access', false);
     }
     // Verify this isn't inherited.
     if ($current_group_id == -1 || $current_group_id == 0) {
         $parent = -2;
     } else {
         require_once SUBSDIR . '/Membergroups.subs.php';
         $group = membergroupById($current_group_id, true);
         $parent = $group['id_parent'];
     }
     if ($parent != -2) {
         fatal_lang_error('cannot_edit_permissions_inherited');
     }
     $givePerms = array('membergroup' => array(), 'board' => array());
     // Guest group, we need illegal, guest permissions.
     if ($current_group_id == -1) {
         loadIllegalGuestPermissions();
         $context['illegal_permissions'] = array_merge($context['illegal_permissions'], $context['non_guest_permissions']);
     }
     // Prepare all permissions that were set or denied for addition to the DB.
     if (isset($_POST['perm']) && is_array($_POST['perm'])) {
         foreach ($_POST['perm'] as $perm_type => $perm_array) {
             if (is_array($perm_array)) {
                 foreach ($perm_array as $permission => $value) {
                     if ($value == 'on' || $value == 'deny') {
                         // Don't allow people to escalate themselves!
                         if (!empty($context['illegal_permissions']) && in_array($permission, $context['illegal_permissions'])) {
                             continue;
                         }
                         $givePerms[$perm_type][] = array($permission, $current_group_id, $value == 'deny' ? 0 : 1);
                     }
                 }
             }
         }
     }
     // Insert the general permissions.
     if ($current_group_id != 3 && empty($_GET['pid'])) {
         deleteInvalidPermissions($current_group_id, $context['illegal_permissions']);
         if (!empty($givePerms['membergroup'])) {
             replacePermission($givePerms['membergroup']);
         }
     }
     // Insert the boardpermissions.
     $profileid = max(1, $_GET['pid']);
     deleteAllBoardPermissions($current_group_id, $profileid);
     if (!empty($givePerms['board'])) {
         foreach ($givePerms['board'] as $k => $v) {
             $givePerms['board'][$k][] = $profileid;
         }
         replaceBoardPermission($givePerms['board']);
     }
     // Update any inherited permissions as required.
     updateChildPermissions($current_group_id, $_GET['pid']);
     // Clear cached privs.
     updateSettings(array('settings_updated' => time()));
     redirectexit('action=admin;area=permissions;pid=' . $_GET['pid']);
 }
Example #5
0
 /**
  * Display members of a group, and allow adding of members to a group.
  *
  * What it does:
  * - It can be called from ManageMembergroups if it needs templating within the admin environment.
  * - It shows a list of members that are part of a given membergroup.
  * - It is called by ?action=moderate;area=viewgroups;sa=members;group=x
  * - It requires the manage_membergroups permission.
  * - It allows to add and remove members from the selected membergroup.
  * - It allows sorting on several columns.
  * - It redirects to itself.
  * @uses ManageMembergroups template, group_members sub template.
  */
 public function action_members()
 {
     global $txt, $scripturl, $context, $modSettings, $user_info, $settings;
     $current_group = isset($_REQUEST['group']) ? (int) $_REQUEST['group'] : 0;
     // These will be needed
     require_once SUBSDIR . '/Membergroups.subs.php';
     require_once SUBSDIR . '/Members.subs.php';
     // Load up the group details.
     $context['group'] = membergroupById($current_group, true, true);
     // No browsing of guests, membergroup 0 or moderators or non-existing groups.
     if ($context['group'] === false || in_array($current_group, array(-1, 0, 3))) {
         fatal_lang_error('membergroup_does_not_exist', false);
     }
     $context['group']['id'] = $context['group']['id_group'];
     $context['group']['name'] = $context['group']['group_name'];
     // Fix the membergroup icons.
     $context['group']['icons'] = explode('#', $context['group']['icons']);
     $context['group']['icons'] = !empty($context['group']['icons'][0]) && !empty($context['group']['icons'][1]) ? str_repeat('<img src="' . $settings['images_url'] . '/group_icons/' . $context['group']['icons'][1] . '" alt="*" />', $context['group']['icons'][0]) : '';
     $context['group']['can_moderate'] = allowedTo('manage_membergroups') && (allowedTo('admin_forum') || $context['group']['group_type'] != 1);
     // The template is very needy
     $context['linktree'][] = array('url' => $scripturl . '?action=groups;sa=members;group=' . $context['group']['id'], 'name' => $context['group']['name']);
     $context['can_send_email'] = allowedTo('send_email_to_members');
     $context['sort_direction'] = isset($_REQUEST['desc']) ? 'down' : 'up';
     $context['start'] = $_REQUEST['start'];
     $context['can_moderate_forum'] = allowedTo('moderate_forum');
     // @todo: use createList
     // Load all the group moderators, for fun.
     $context['group']['moderators'] = array();
     $moderators = getGroupModerators($current_group);
     foreach ($moderators as $id_member => $name) {
         $context['group']['moderators'][] = array('id' => $id_member, 'name' => $name);
         if ($user_info['id'] == $id_member && $context['group']['group_type'] != 1) {
             $context['group']['can_moderate'] = true;
         }
     }
     // If this group is hidden then it can only "exist" if the user can moderate it!
     if ($context['group']['hidden'] && !$context['group']['can_moderate']) {
         fatal_lang_error('membergroup_does_not_exist', false);
     }
     // You can only assign membership if you are the moderator and/or can manage groups!
     if (!$context['group']['can_moderate']) {
         $context['group']['assignable'] = 0;
     } elseif ($context['group']['id'] == 1 && !allowedTo('admin_forum')) {
         $context['group']['assignable'] = 0;
     }
     // Removing member from group?
     if (isset($_POST['remove']) && !empty($_REQUEST['rem']) && is_array($_REQUEST['rem']) && $context['group']['assignable']) {
         // Security first
         checkSession();
         validateToken('mod-mgm');
         // Make sure we're dealing with integers only.
         foreach ($_REQUEST['rem'] as $key => $group) {
             $_REQUEST['rem'][$key] = (int) $group;
         }
         removeMembersFromGroups($_REQUEST['rem'], $current_group, true);
     } elseif (isset($_REQUEST['add']) && (!empty($_REQUEST['toAdd']) || !empty($_REQUEST['member_add'])) && $context['group']['assignable']) {
         // Make sure you can do this
         checkSession();
         validateToken('mod-mgm');
         $member_query = array(array('and' => 'not_in_group'));
         $member_parameters = array('not_in_group' => $current_group);
         // Get all the members to be added... taking into account names can be quoted ;)
         $_REQUEST['toAdd'] = strtr(Util::htmlspecialchars($_REQUEST['toAdd'], ENT_QUOTES), array('&quot;' => '"'));
         preg_match_all('~"([^"]+)"~', $_REQUEST['toAdd'], $matches);
         $member_names = array_unique(array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $_REQUEST['toAdd']))));
         foreach ($member_names as $index => $member_name) {
             $member_names[$index] = trim(Util::strtolower($member_names[$index]));
             if (strlen($member_names[$index]) == 0) {
                 unset($member_names[$index]);
             }
         }
         // Any members passed by ID?
         $member_ids = array();
         if (!empty($_REQUEST['member_add'])) {
             foreach ($_REQUEST['member_add'] as $id) {
                 if ($id > 0) {
                     $member_ids[] = (int) $id;
                 }
             }
         }
         // Construct the query pelements, first for adds by name
         if (!empty($member_ids)) {
             $member_query[] = array('or' => 'member_ids');
             $member_parameters['member_ids'] = $member_ids;
         }
         // And then adds by ID
         if (!empty($member_names)) {
             $member_query[] = array('or' => 'member_names');
             $member_parameters['member_names'] = $member_names;
         }
         // Get back the ones that were not already in the group
         $members = membersBy($member_query, $member_parameters);
         // Do the updates...
         if (!empty($members)) {
             addMembersToGroup($members, $current_group, $context['group']['hidden'] ? 'only_additional' : 'auto', true);
         }
     }
     // Sort out the sorting!
     $sort_methods = array('name' => 'real_name', 'email' => allowedTo('moderate_forum') ? 'email_address' : 'hide_email ' . (isset($_REQUEST['desc']) ? 'DESC' : 'ASC') . ', email_address', 'active' => 'last_login', 'registered' => 'date_registered', 'posts' => 'posts');
     // They didn't pick one, or tried a wrong one, so default to by name..
     if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']])) {
         $context['sort_by'] = 'name';
         $querySort = 'real_name' . (isset($_REQUEST['desc']) ? ' DESC' : ' ASC');
     } else {
         $context['sort_by'] = $_REQUEST['sort'];
         $querySort = $sort_methods[$_REQUEST['sort']] . (isset($_REQUEST['desc']) ? ' DESC' : ' ASC');
     }
     // The where on the query is interesting. Non-moderators should only see people who are in this group as primary.
     if ($context['group']['can_moderate']) {
         $where = $context['group']['is_post_group'] ? 'in_post_group' : 'in_group';
     } else {
         $where = $context['group']['is_post_group'] ? 'in_post_group' : 'in_group_no_add';
     }
     // Count members of the group.
     $context['total_members'] = countMembersBy($where, array($where => $current_group));
     $context['total_members'] = comma_format($context['total_members']);
     // Create the page index.
     $context['page_index'] = constructPageIndex($scripturl . '?action=' . ($context['group']['can_moderate'] ? 'moderate;area=viewgroups' : 'groups') . ';sa=members;group=' . $current_group . ';sort=' . $context['sort_by'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $context['total_members'], $modSettings['defaultMaxMembers']);
     // Fetch the members that meet the where criteria
     $context['members'] = membersBy($where, array($where => $current_group, 'order' => $querySort), true);
     foreach ($context['members'] as $id => $row) {
         $last_online = empty($row['last_login']) ? $txt['never'] : standardTime($row['last_login']);
         // Italicize the online note if they aren't activated.
         if ($row['is_activated'] % 10 != 1) {
             $last_online = '<em title="' . $txt['not_activated'] . '">' . $last_online . '</em>';
         }
         $context['members'][$id] = array('id' => $row['id_member'], 'name' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>', 'email' => $row['email_address'], 'show_email' => showEmailAddress(!empty($row['hide_email']), $row['id_member']), 'ip' => '<a href="' . $scripturl . '?action=trackip;searchip=' . $row['member_ip'] . '">' . $row['member_ip'] . '</a>', 'registered' => standardTime($row['date_registered']), 'last_online' => $last_online, 'posts' => comma_format($row['posts']), 'is_activated' => $row['is_activated'] % 10 == 1);
     }
     if (!empty($context['group']['assignable'])) {
         loadJavascriptFile('suggest.js', array('defer' => true));
     }
     // Select the template.
     $context['sub_template'] = 'group_members';
     $context['page_title'] = $txt['membergroups_members_title'] . ': ' . $context['group']['name'];
     createToken('mod-mgm');
 }