/** * 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('~&#(\\d{4,5}|[2-9]\\d{2,4}|1[2-9]\\d);~', '&#$1;', htmlspecialchars($moderator_string, ENT_QUOTES, 'UTF-8')), array('"' => '"')); 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']) ? '' : '"' . implode('", "', $context['group']['moderators']) . '"'; 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'); }
/** * 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('"' => '"')); 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'); }