/** * Completely update the membership of a group * * @param int $groupid ID of group * @param array $members list of members and roles, structured like this: * array( * userid => role, * userid => role, * ... * ) * @param lines_done Number of lines in the file that have been completed so far * @param num_lines Number of lines in the file (this and the previous values * are used to update the progress meter. */ function group_update_members($groupid, $members, $lines_done = 0, $num_lines = 0) { global $USER; $groupid = group_param_groupid($groupid); if (!($group = get_record('group', 'id', $groupid, 'deleted', 0))) { throw new NotFoundException("group_update_members: group not found: {$groupid}"); } if ($group->institution && !$USER->can_edit_institution($group->institution) || !$group->institution && !$USER->get('admin')) { throw new AccessDeniedException("group_update_members: access denied"); } if (!is_array($members)) { throw new SystemException("group_update_members: members must be an array"); } $badroles = array_unique(array_diff($members, array_keys(group_get_role_info($groupid)))); if (!empty($badroles)) { throw new UserException("group_update_members: invalid role(s) specified for group {$group->name} (id {$groupid}): " . join(', ', $badroles)); } if (!in_array('admin', $members)) { $groupname = get_field('group', 'name', 'id', $groupid); throw new UserException("group_update_members: no group admins listed for group {$group->name} (id {$groupid})"); } // Check the new members list for invalid users if (!empty($members)) { $userids = array_map('intval', array_keys($members)); if ($group->institution && $group->institution != 'mahara') { $gooduserids = get_column_sql(' SELECT usr FROM {usr_institution} WHERE usr IN (' . join(',', $userids) . ') AND institution = ?', array($group->institution)); if ($baduserids = array_diff($userids, $gooduserids)) { if (!(count($baduserids) == 1 && $baduserids[0] == $USER->id)) { throw new UserException("group_update_members: some members are not in the institution {$group->institution}: " . join(',', $baduserids)); } } } else { $gooduserids = get_column_sql(' SELECT id FROM {usr} WHERE id IN (' . join(',', $userids) . ') AND deleted = 0', array()); if ($baduserids = array_diff($userids, $gooduserids)) { throw new UserException("group_update_members: some new members do not exist: " . join(',', $baduserids)); } } } // Update group members $oldmembers = get_records_assoc('group_member', 'group', $groupid, '', 'member,role'); $added = 0; $removed = 0; $updated = 0; $to_add = count(array_diff_key($members, $oldmembers)); $to_remove = count(array_diff_key($oldmembers, $members)); $to_update = count($members) - $to_add; db_begin(); foreach ($members as $userid => $role) { if (!isset($oldmembers[$userid])) { group_add_user($groupid, $userid, $role); $added++; if (!(($lines_done + $added) % 25)) { set_progress_info('uploadgroupmemberscsv', $num_lines + 9 * ($lines_done + count($members) * $added / ($to_add + $to_remove)), $num_lines * 10, get_string('committingchanges', 'admin')); } } else { if ($oldmembers[$userid]->role != $role) { set_field('group_member', 'role', $role, 'group', $groupid, 'member', $userid); $updated++; } } } foreach (array_keys($oldmembers) as $userid) { if (!isset($members[$userid])) { group_remove_user($groupid, $userid, true); $removed++; if (!(($lines_done + $added + $removed) % 25)) { set_progress_info('uploadgroupmemberscsv', $num_lines + 9 * ($lines_done + count($members) * ($added + $removed) / ($to_add + $to_remove)), $num_lines * 10, get_string('committingchanges', 'admin')); } } } db_commit(); if ($added == 0 && $removed == 0 && $updated == 0) { return null; } return array('added' => $added, 'removed' => $removed, 'updated' => $updated); }
/** * Adds a member to a group. * * Doesn't do any jointype checking, that should be handled by the caller. * * TODO: it should though. We should probably have group_user_can_be_added * * @param int $groupid * @param int $userid * @param string $role */ function group_add_user($groupid, $userid, $role = null) { $groupid = group_param_groupid($groupid); $userid = group_param_userid($userid); $gm = new StdClass(); $gm->member = $userid; $gm->group = $groupid; $gm->ctime = db_format_timestamp(time()); if (!$role) { $role = get_field_sql('SELECT gt.defaultrole FROM {grouptype} gt, {group} g WHERE g.id = ? AND g.grouptype = gt.name', array($groupid)); } $gm->role = $role; db_begin(); insert_record('group_member', $gm); delete_records('group_member_request', 'group', $groupid, 'member', $userid); handle_event('userjoinsgroup', $gm); db_commit(); }