function validation($data, $files) { global $CFG, $COURSE; $errors = parent::validation($data, $files); if ($data['allocateby'] != 'no') { if (!($users = groups_get_potential_members($data['courseid'], $data['roleid']))) { $errors['roleid'] = get_string('nousersinrole', 'group'); } /// Check the number entered is sane if ($data['groupby'] == 'groups') { $usercnt = count($users); if ($data['number'] > $usercnt || $data['number'] < 1) { $errors['number'] = get_string('toomanygroups', 'group', $usercnt); } } } //try to detect group name duplicates $name = groups_parse_name(stripslashes(trim($data['namingscheme'])), 0); if (groups_get_group_by_name($COURSE->id, $name)) { $errors['namingscheme'] = get_string('groupnameexists', 'group', $name); } // check grouping name duplicates if (isset($data['grouping']) && $data['grouping'] == '-1') { $name = trim(stripslashes($data['groupingname'])); if (empty($name)) { $errors['groupingname'] = get_string('required'); } else { if (groups_get_grouping_by_name($COURSE->id, $name)) { $errors['groupingname'] = get_string('groupingnameexists', 'group', $name); } } } /// Check the naming scheme $matchcnt = preg_match_all('/[#@]{1,1}/', $data['namingscheme'], $matches); if ($matchcnt != 1) { $errors['namingscheme'] = get_string('badnamingscheme', 'group'); } return $errors; }
public function test_groups_create_autogroups() { global $DB; $this->resetAfterTest(); $course = $this->getDataGenerator()->create_course(); $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); $group3 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); $grouping1 = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id)); $this->getDataGenerator()->create_grouping_group(array('groupid' => $group2->id, 'groupingid' => $grouping1->id)); $this->getDataGenerator()->create_grouping_group(array('groupid' => $group3->id, 'groupingid' => $grouping1->id)); $user1 = $this->getDataGenerator()->create_user(); $user2 = $this->getDataGenerator()->create_user(); $user3 = $this->getDataGenerator()->create_user(); $user4 = $this->getDataGenerator()->create_user(); $this->getDataGenerator()->enrol_user($user1->id, $course->id); $this->getDataGenerator()->enrol_user($user2->id, $course->id); $this->getDataGenerator()->enrol_user($user3->id, $course->id); $this->getDataGenerator()->enrol_user($user4->id, $course->id); $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)); $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id)); $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user3->id)); $this->getDataGenerator()->create_group_member(array('groupid' => $group3->id, 'userid' => $user4->id)); // Test autocreate group based on all course users. $users = groups_get_potential_members($course->id); $group4 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); foreach ($users as $user) { $this->getDataGenerator()->create_group_member(array('groupid' => $group4->id, 'userid' => $user->id)); } $this->assertEquals(4, $DB->count_records('groups_members', array('groupid' => $group4->id))); // Test autocreate group based on existing group. $source = array(); $source['groupid'] = $group1->id; $users = groups_get_potential_members($course->id, 0, $source); $group5 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); foreach ($users as $user) { $this->getDataGenerator()->create_group_member(array('groupid' => $group5->id, 'userid' => $user->id)); } $this->assertEquals(2, $DB->count_records('groups_members', array('groupid' => $group5->id))); // Test autocreate group based on existing grouping. $source = array(); $source['groupingid'] = $grouping1->id; $users = groups_get_potential_members($course->id, 0, $source); $group6 = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); foreach ($users as $user) { $this->getDataGenerator()->create_group_member(array('groupid' => $group6->id, 'userid' => $user->id)); } $this->assertEquals(2, $DB->count_records('groups_members', array('groupid' => $group6->id))); }
switch ($data->allocateby) { case 'no': case 'random': case 'lastname': $orderby = 'lastname, firstname'; break; case 'firstname': $orderby = 'firstname, lastname'; break; case 'idnumber': $orderby = 'idnumber'; break; default: error('Unknown ordering'); } $users = groups_get_potential_members($data->courseid, $data->roleid, $orderby); $usercnt = count($users); if ($data->allocateby == 'random') { srand($data->seed); shuffle($users); } $groups = array(); // Plan the allocation if ($data->groupby == 'groups') { $numgrps = $data->number; $userpergrp = floor($usercnt / $numgrps); } else { // members $numgrps = ceil($usercnt / $data->number); $userpergrp = $data->number; if (!empty($data->nosmallgroups) and $usercnt % $data->number != 0) {
default: print_error('unknoworder'); } $source = array(); if ($data->cohortid) { $source['cohortid'] = $data->cohortid; } if ($data->groupingid) { $source['groupingid'] = $data->groupingid; } if ($data->groupid) { $source['groupid'] = $data->groupid; } // Display only active users if the option was selected or they do not have the capability to view suspended users. $onlyactive = !empty($data->includeonlyactiveenrol) || !has_capability('moodle/course:viewsuspendedusers', $context); $users = groups_get_potential_members($data->courseid, $data->roleid, $source, $orderby, !empty($data->notingroup), $onlyactive); $usercnt = count($users); if ($data->allocateby == 'random') { srand($data->seed); shuffle($users); } $groups = array(); // Plan the allocation if ($data->groupby == 'groups') { $numgrps = $data->number; $userpergrp = floor($usercnt / $numgrps); } else { // members $numgrps = ceil($usercnt / $data->number); $userpergrp = $data->number; if (!empty($data->nosmallgroups) and $usercnt % $data->number != 0) {
/** * Performs validation of the form information * * @param array $data * @param array $files * @return array $errors An array of $errors */ function validation($data, $files) { global $CFG, $COURSE; $errors = parent::validation($data, $files); if ($data['allocateby'] != 'no') { $source = array(); if ($data['cohortid']) { $source['cohortid'] = $data['cohortid']; } if ($data['groupingid']) { $source['groupingid'] = $data['groupingid']; } if ($data['groupid']) { $source['groupid'] = $data['groupid']; } if (!$users = groups_get_potential_members($data['courseid'], $data['roleid'], $source)) { $errors['roleid'] = get_string('nousersinrole', 'group'); } /// Check the number entered is sane if ($data['groupby'] == 'groups') { $usercnt = count($users); if ($data['number'] > $usercnt || $data['number'] < 1) { $errors['number'] = get_string('toomanygroups', 'group', $usercnt); } } } //try to detect group name duplicates $name = groups_parse_name(trim($data['namingscheme']), 0); if (groups_get_group_by_name($COURSE->id, $name)) { $errors['namingscheme'] = get_string('groupnameexists', 'group', $name); } // check grouping name duplicates if ( isset($data['grouping']) && $data['grouping'] == '-1') { $name = trim($data['groupingname']); if (empty($name)) { $errors['groupingname'] = get_string('required'); } else if (groups_get_grouping_by_name($COURSE->id, $name)) { $errors['groupingname'] = get_string('groupingnameexists', 'group', $name); } } /// Check the naming scheme if ($data['groupby'] == 'groups' and $data['number'] == 1) { // we can use the name as is because there will be only one group max } else { $matchcnt = preg_match_all('/[#@]{1,1}/', $data['namingscheme'], $matches); if ($matchcnt != 1) { $errors['namingscheme'] = get_string('badnamingscheme', 'group'); } } return $errors; }
/** * Outputs the content of the creation tab and manages actions taken in this tab */ public function view_creation() { global $SESSION, $OUTPUT, $PAGE, $DB; $id = $this->cm->id; $context = context_course::instance($this->course->id); // Get applicable roles! $rolenames = array(); if ($roles = get_profile_roles($context)) { foreach ($roles as $role) { $rolenames[$role->id] = strip_tags(role_get_name($role, $context)); } } // Check if everything has been confirmed, so we can finally start working! if (optional_param('confirm', 0, PARAM_BOOL)) { if (isset($SESSION->grouptool->view_administration->createGroups)) { require_capability('mod/grouptool:create_groups', $this->context); // Create groups! $data = $SESSION->grouptool->view_administration; switch ($data->mode) { case GROUPTOOL_GROUPS_AMOUNT: // Allocate members from the selected role to groups! switch ($data->allocateby) { case 'no': case 'random': case 'lastname': $orderby = 'lastname, firstname'; break; case 'firstname': $orderby = 'firstname, lastname'; break; case 'idnumber': $orderby = 'idnumber'; break; default: print_error('unknoworder'); } $users = groups_get_potential_members($this->course->id, $data->roleid, $data->cohortid, $orderby); $usercnt = count($users); $numgrps = $data->amount; $userpergrp = floor($usercnt / $numgrps); list($error, $preview) = $this->create_groups($data, $users, $userpergrp, $numgrps); break; case GROUPTOOL_MEMBERS_AMOUNT: // Allocate members from the selected role to groups! switch ($data->allocateby) { case 'no': case 'random': case 'lastname': $orderby = 'lastname, firstname'; break; case 'firstname': $orderby = 'firstname, lastname'; break; case 'idnumber': $orderby = 'idnumber'; break; default: print_error('unknoworder'); } $users = groups_get_potential_members($this->course->id, $data->roleid, $data->cohortid, $orderby); $usercnt = count($users); $numgrps = ceil($usercnt / $data->amount); $userpergrp = $data->amount; if (!empty($data->nosmallgroups) and $usercnt % $data->amount != 0) { /* * If there would be one group with a small number of member * reduce the number of groups */ $missing = $userpergrp * $numgrps - $usercnt; if ($missing > $userpergrp * (1 - GROUPTOOL_AUTOGROUP_MIN_RATIO)) { // Spread the users from the last small group! $numgrps--; $userpergrp = floor($usercnt / $numgrps); } } list($error, $preview) = $this->create_groups($data, $users, $userpergrp, $numgrps); break; case GROUPTOOL_1_PERSON_GROUPS: $users = groups_get_potential_members($this->course->id, $data->roleid, $data->cohortid); if (!isset($data->groupingname)) { $data->groupingname = null; } list($error, $prev) = $this->create_one_person_groups($users, $data->namingscheme, $data->grouping, $data->groupingname); $preview = $prev; break; case GROUPTOOL_FROMTO_GROUPS: if (!isset($data->groupingname)) { $data->groupingname = null; } list($error, $preview) = $this->create_fromto_groups($data); break; } $class = $error ? 'notifyproblem' : 'notifysuccess'; $preview = $OUTPUT->notification($preview, $class); echo $OUTPUT->box(html_writer::tag('div', $preview, array('class' => 'centered')), 'generalbox'); } unset($SESSION->grouptool->view_administration); } // Create the form-object! $mform = new \mod_grouptool\group_creation_form(null, array('id' => $id, 'roles' => $rolenames, 'show_grpsize' => $this->grouptool->use_size && $this->grouptool->use_individual)); if ($fromform = $mform->get_data()) { require_capability('mod/grouptool:create_groups', $this->context); // Save submitted data in session and show confirmation dialog! if (!isset($SESSION->grouptool)) { $SESSION->grouptool = new stdClass(); } if (!isset($SESSION->grouptool->view_administration)) { $SESSION->grouptool->view_administration = new stdClass(); } $SESSION->grouptool->view_administration = $fromform; $data = $SESSION->grouptool->view_administration; $preview = ""; switch ($data->mode) { case GROUPTOOL_GROUPS_AMOUNT: // Allocate members from the selected role to groups! switch ($data->allocateby) { case 'no': case 'random': case 'lastname': $orderby = 'lastname, firstname'; break; case 'firstname': $orderby = 'firstname, lastname'; break; case 'idnumber': $orderby = 'idnumber'; break; default: print_error('unknoworder'); } $users = groups_get_potential_members($this->course->id, $data->roleid, $data->cohortid, $orderby); $usercnt = count($users); $numgrps = clean_param($data->amount, PARAM_INT); $userpergrp = floor($usercnt / $numgrps); list($error, $preview) = $this->create_groups($data, $users, $userpergrp, $numgrps, true); break; case GROUPTOOL_MEMBERS_AMOUNT: // Allocate members from the selected role to groups! switch ($data->allocateby) { case 'no': case 'random': case 'lastname': $orderby = 'lastname, firstname'; break; case 'firstname': $orderby = 'firstname, lastname'; break; case 'idnumber': $orderby = 'idnumber'; break; default: print_error('unknoworder'); } $users = groups_get_potential_members($this->course->id, $data->roleid, $data->cohortid, $orderby); $usercnt = count($users); $numgrps = ceil($usercnt / $data->amount); $userpergrp = clean_param($data->amount, PARAM_INT); if (!empty($data->nosmallgroups) and $usercnt % clean_param($data->amount, PARAM_INT) != 0) { /* * If there would be one group with a small number of member * reduce the number of groups */ $missing = $userpergrp * $numgrps - $usercnt; if ($missing > $userpergrp * (1 - GROUPTOOL_AUTOGROUP_MIN_RATIO)) { // Spread the users from the last small group! $numgrps--; $userpergrp = floor($usercnt / $numgrps); } } list($error, $preview) = $this->create_groups($data, $users, $userpergrp, $numgrps, true); break; case GROUPTOOL_1_PERSON_GROUPS: $users = groups_get_potential_members($this->course->id, $data->roleid, $data->cohortid); if (!isset($data->groupingname)) { $data->groupingname = null; } list($error, $prev) = $this->create_one_person_groups($users, $data->namingscheme, $data->grouping, $data->groupingname, true); $preview = $prev; break; case GROUPTOOL_FROMTO_GROUPS: if (!isset($data->groupingname)) { $data->groupingname = null; } list($error, $preview) = $this->create_fromto_groups($data, true); break; } $preview = html_writer::tag('div', $preview, array('class' => 'centered')); $tab = required_param('tab', PARAM_ALPHANUMEXT); if ($error) { $text = get_string('create_groups_confirm_problem', 'grouptool'); $url = new moodle_url("view.php?id={$id}&tab=" . $tab); $back = new single_button($url, get_string('back'), 'post'); $confirmboxcontent = $this->confirm($text, $back); } else { $continue = "view.php?id={$id}&tab=" . $tab . "&confirm=true"; $cancel = "view.php?id={$id}&tab=" . $tab; $text = get_string('create_groups_confirm', 'grouptool'); $confirmboxcontent = $this->confirm($text, $continue, $cancel); } echo $OUTPUT->heading(get_string('preview'), 2, 'centered') . $OUTPUT->box($preview, 'generalbox') . $confirmboxcontent; } else { $mform->display(); } }
/** * This function calculates all unassigned students for a particular grouping. * We enforce a rule that students can only be a member of one group in the * grouping. * * @return array {IDs => names) of potential members. * */ public function get_potential_students() { $student = get_archetype_roles('student'); $student = reset($student); $allmembers = groups_get_potential_members($this->courseid, $student->id); $allocatedmembers = $this->get_all_grouped_students(); $potentialmemberids = array(); foreach ($allmembers as $allmember) { if (array_search($allmember->id, $allocatedmembers) === false) { $potentialmemberids[] = $allmember->id; } } sort($potentialmemberids); $potentialmembernames = block_skills_group_retrieve_names($potentialmemberids); // Note: array_combine() will not work with empty arrays. if (count($potentialmemberids) > 0) { return array_combine($potentialmemberids, $potentialmembernames); } else { return array(); } }