/** * Test validation of duplicates * * Note: no exception thrown from trackassignment.class.php for dup. */ public function test_trackassignmentvalidationpreventsduplicates() { global $DB; $this->load_csv_data(); $trackassignment = new trackassignment(array('trackid' => 1, 'classid' => 100, 'courseid' => 99999999)); $trackassignment->save(); $trackassignments = $DB->get_records(trackassignment::TABLE, array('trackid' => 1, 'classid' => 100)); $this->assertEquals(count($trackassignments), 1); }
/** * Clone a track * @param array $options options for cloning. Valid options are: * - 'targetcurriculum': the curriculum id to associate the clones with * (default: same as original track) * - 'classmap': a mapping of class IDs to use from the original track to * the cloned track. If a class from the original track is not mapped, a * new class will be created * - 'moodlecourse': whether or not to clone Moodle courses (if they were * autocreated). Values can be (default: "copyalways"): * - "copyalways": always copy course * - "copyautocreated": only copy autocreated courses * - "autocreatenew": autocreate new courses from course template * - "link": link to existing course * @return array array of array of object IDs created. Key in outer array * is type of object (plural). Key in inner array is original object ID, * value is new object ID. Outer array also has an entry called 'errors', * which is an array of any errors encountered when duplicating the * object. */ function duplicate(array $options = array()) { $objs = array('errors' => array()); if (isset($options['targetcluster'])) { $userset = $options['targetcluster']; if (!is_object($userset) || !is_a($userset, 'userset')) { $options['targetcluster'] = $userset = new userset($userset); } } // Due to lazy loading, we need to pre-load this object $this->load(); // clone main track object $clone = new track($this); unset($clone->id); if (isset($options['targetcurriculum'])) { $clone->curid = $options['targetcurriculum']; } $idnumber = $clone->idnumber; $name = $clone->name; if (isset($userset)) { $to_append = ' - ' . $userset->name; // if cluster specified, append cluster's name to course $idnumber = append_once($idnumber, $to_append, array('maxlength' => 95)); $name = append_once($name, $to_append, array('maxlength' => 250)); } //get a unique idnumber $clone->idnumber = generate_unique_identifier(track::TABLE, 'idnumber', $idnumber, array('idnumber' => $idnumber)); if ($clone->idnumber != $idnumber) { //get the suffix appended and add it to the name $parts = explode('.', $clone->idnumber); $suffix = end($parts); $clone->name = $name . '.' . $suffix; } else { $clone->name = $name; } $clone->autocreate = false; // avoid warnings $clone->save(); $objs['tracks'] = array($this->id => $clone->id); // associate with target cluster (if any) if (isset($userset)) { clustertrack::associate($userset->id, $clone->id); } // copy classes $clstrks = track_assignment_get_listing($this->id); if ($clstrks->valid() === true) { $objs['classes'] = array(); if (!isset($options['classmap'])) { $options['classmap'] = array(); } foreach ($clstrks as $clstrkdata) { $newclstrk = new trackassignment($clstrkdata); $newclstrk->trackid = $clone->id; unset($newclstrk->id); if (isset($options['classmap'][$clstrkdata->clsid])) { // use existing duplicate class $class = new pmclass($options['classmap'][$clstrkdata->clsid]); } else { // no existing duplicate -> duplicate class $class = new pmclass($clstrkdata->clsid); $rv = $class->duplicate($options); if (isset($rv['errors']) && !empty($rv['errors'])) { $objs['errors'] = array_merge($objs['errors'], $rv['errors']); } if (isset($rv['classes'])) { $objs['classes'] = $objs['classes'] + $rv['classes']; } } $newclstrk->classid = $class->id; $newclstrk->courseid = $class->courseid; $newclstrk->save(); } } unset($clstrks); return $objs; }
/** * Test available table doesn't show assigned classes. * @dataProvider dataprovider_available_doesnt_show_assigned_classes * @param array $associations An array of arrays of parameters to construct trackassignment associations. * @param int $tabletrackid The ID of the track we're going to manage. * @param array $expectedresults The expected page of results. * @param int $expectedtotal The expected number of total results. */ public function test_available_doesnt_show_assigned_classes($associations, $tabletrackid, $expectedresults, $expectedtotal) { global $USER, $DB, $CFG; $userbackup = $USER; // Set up permissions. $USER = $this->setup_permissions_test(); $this->give_permission_for_context($USER->id, 'local/elisprogram:associate', context_system::instance()); // We're not interested in the class > course > program > track requirement for this test, so assign all courses to all // programs. foreach (array(5, 6, 7) as $programid) { foreach (array(100, 101, 102) as $courseid) { $association = new curriculumcourse(array('curriculumid' => $programid, 'courseid' => $courseid)); $association->save(); } } // Create trackassignments. foreach ($associations as $association) { $trackassignment = new trackassignment($association); $trackassignment->save(); } // Construct test table. $table = new deepsight_datatable_trackclass_available_mock($DB, 'test', 'http://localhost', 'testuniqid'); $table->set_trackid($tabletrackid); // Perform test. $actualresults = $table->get_search_results(array(), array(), 0, 20); // Verify result. $this->assert_search_results($expectedresults, $expectedtotal, $actualresults); // Restore user. $USER = $userbackup; }
/** * Assign usersets to the track. * @param array $elements An array of userset information to assign to the track. * @param bool $bulkaction Whether this is a bulk-action or not. * @return array An array to format as JSON and return to the Javascript. */ protected function _respond_to_js(array $elements, $bulkaction) { global $DB; $trackid = required_param('id', PARAM_INT); $autoenrol = optional_param('autoenrol', 0, PARAM_BOOL); foreach ($elements as $classid => $label) { if ($this->can_manage_assoc($trackid, $classid) === true) { $assoc = $DB->get_record(trackassignment::TABLE, array('trackid' => $trackid, 'classid' => $classid)); if (!empty($assoc)) { $trackassignment = new trackassignment($assoc); $trackassignment->autoenrol = $autoenrol; $trackassignment->save(); } } } return array('result' => 'success', 'msg' => 'Success'); }
/** * Associate a class instance to a track, if necessary * * @param object $record The import record containing information about the track * @param int $classid The id of the class instance */ function associate_class_to_track($record, $classid) { global $CFG, $DB; require_once $CFG->dirroot . '/local/elisprogram/lib/setup.php'; require_once elispm::lib('data/track.class.php'); if (isset($record->track)) { //attempt to associate this class instance to a track if ($trackid = $DB->get_field(track::TABLE, 'id', array('idnumber' => $record->track))) { //valid track, so associate //determine whether we should auto-enrol $autoenrol = isset($record->autoenrol) && $record->autoenrol == 1 ? 1 : 0; $trackassignment = new trackassignment(array('trackid' => $trackid, 'classid' => $classid, 'autoenrol' => $autoenrol)); $trackassignment->save(); } } //TODO: return a status, add error handling }
/** * Validate that enrolling a user into a user set via IP auto-enrolls them in * an associated track, and any associated programs or class instances */ public function test_userset_enrolment_creates_track_enrolment() { global $CFG, $DB; require_once $CFG->dirroot . '/local/elisprogram/lib/setup.php'; require_once elispm::lib('data/clustertrack.class.php'); require_once elispm::lib('data/course.class.php'); require_once elispm::lib('data/curriculum.class.php'); require_once elispm::lib('data/curriculumcourse.class.php'); require_once elispm::lib('data/curriculumstudent.class.php'); require_once elispm::lib('data/pmclass.class.php'); require_once elispm::lib('data/student.class.php'); require_once elispm::lib('data/track.class.php'); require_once elispm::lib('data/user.class.php'); require_once elispm::lib('data/userset.class.php'); require_once elispm::lib('data/usertrack.class.php'); // Make sure no emails are sent. set_config('noemailever', true); // Set up data. // Test user. $user = new user(array('idnumber' => 'testuseridnumber', 'username' => 'testuserusername', 'firstname' => 'testuserfirstname', 'firstname' => 'testuserfirstname', 'lastname' => 'testuserlastname', 'email' => '*****@*****.**', 'country' => 'CA')); $user->save(); // Test user set. $userset = new userset(array('name' => 'testusersetname')); $userset->save(); // Test program and track. $program = new curriculum(array('idnumber' => 'testprogramidnumber')); $program->save(); $track = new track(array('curid' => $program->id, 'idnumber' => 'testtrackidnumber')); $track->save(); // Associate the userset to the track. $clustertrack = new clustertrack(array('clusterid' => $userset->id, 'trackid' => $track->id, 'autoenrol' => 1)); $clustertrack->save(); // Test course and class. $course = new course(array('name' => 'testcoursename', 'idnumber' => 'testcourseidnumber', 'syllabus' => '')); $course->save(); $class = new pmclass(array('courseid' => $course->id, 'idnumber' => 'testclass1idnumber')); $class->save(); // Associate course to the program. $curriculumcourse = new curriculumcourse(array('curriculumid' => $program->id, 'courseid' => $course->id)); $curriculumcourse->save(); // Associate track to the test class. $trackassignment = new trackassignment(array('trackid' => $track->id, 'classid' => $class->id, 'autoenrol' => 1)); $trackassignment->save(); // Run the assignment create action. $record = new stdClass(); $record->context = 'userset_testusersetname'; $record->user_username = '******'; $importplugin = rlip_dataplugin_factory::factory('dhimport_version1elis'); $importplugin->fslogger = new silent_fslogger(null); $importplugin->cluster_enrolment_create($record, 'bogus', 'testusersetname'); // Validation. // Userset assignment should trigger track assignment. $this->assertTrue($DB->record_exists(usertrack::TABLE, array('userid' => $user->id, 'trackid' => $track->id))); // Track assignment should trigger program assignment. $this->assertTrue($DB->record_exists(curriculumstudent::TABLE, array('userid' => $user->id, 'curriculumid' => $program->id))); // Track assignment should create a class enrolment. $this->assertTrue($DB->record_exists(student::TABLE, array('userid' => $user->id, 'classid' => $class->id))); }
public function save() { $isnew = empty($this->id); parent::save(); if (isset($this->track) && is_array($this->track)) { $param['classid'] = $this->id; $param['courseid'] = $this->courseid; foreach ($this->track as $t) { if (trackassignment::exists(array(new field_filter('classid', $this->id), new field_filter('trackid', $t)))) { continue; } $param['trackid'] = $t; $trackassignobj = new trackassignment($param); $trackassignobj->save(); } } if (isset($this->unlink_attached_course) && isset($this->moodlecourseid)) { // process unlink moodle course id request $return = moodle_detach_class($this->id, $this->moodlecourseid); $this->moodlecourseid = 0; } if ($this->moodlecourseid || $this->autocreate) { moodle_attach_class($this->id, $this->moodlecourseid, '', true, true, $this->autocreate); } if (!$isnew) { if (!empty($this->oldmax) && (!$this->maxstudents || $this->oldmax < $this->maxstudents) && ($waiting = waitlist::count_records($this->id)) > 0) { $start = student_count_records($this->id); $max = $this->maxstudents ? $this->maxstudents : $start + $waiting + 1; //error_log("pmclass.class.php::save() oldmax = {$this->oldmax}, start = {$start}, newmax = {$this->maxstudents}, waiting = {$waiting} ... max = {$max}"); for ($i = $start; $i < $max; $i++) { $next_student = waitlist::get_next($this->id); if (empty($next_student)) { break; } $next_student->enrol(); } } } field_data::set_for_context_from_datarecord(CONTEXT_ELIS_CLASS, $this); }
/** * Set up data that is needed for testing */ private function set_up_required_data($assignusertouserset = true, $assigncoursetoclass = true, $assigntracktoclass = true, $initclusterprofile = false, $initusersetfielddata = true) { global $CFG, $DB; require_once $CFG->dirroot . '/local/elisprogram/lib/setup.php'; require_once $CFG->dirroot . '/course/lib.php'; require_once $CFG->dirroot . '/lib/enrollib.php'; require_once elis::lib('data/customfield.class.php'); require_once elispm::file('accesslib.php'); require_once elispm::lib('data/classmoodlecourse.class.php'); require_once elispm::lib('data/clusterassignment.class.php'); require_once elispm::lib('data/clustertrack.class.php'); require_once elispm::lib('data/course.class.php'); require_once elispm::lib('data/curriculum.class.php'); require_once elispm::lib('data/pmclass.class.php'); require_once elispm::lib('data/track.class.php'); require_once elispm::lib('data/user.class.php'); require_once elispm::lib('data/userset.class.php'); require_once elispm::lib('data/usertrack.class.php'); $fieldcategoryid = $DB->get_field(field_category::TABLE, 'id', array('name' => 'Associated Group')); $this->assertNotEquals(false, $fieldcategoryid); $fieldcategory = new field_category($fieldcategoryid); $fieldcategory->load(); // Set up the test user. $user = new user(array('idnumber' => 'testuseridnumber', 'username' => 'testuserusername', 'firstname' => 'testuserfirstname', 'lastname' => 'testuserlastname', 'email' => '*****@*****.**', 'country' => 'CA')); $user->save(); // Set up the test course description and class instance. $course = new course(array('name' => 'testcoursename', 'idnumber' => 'testcourseidnumber', 'syllabus' => '')); $course->save(); $pmclass = new pmclass(array('courseid' => $course->id, 'idnumber' => 'testclassidnumber')); $pmclass->save(); $category = new stdClass(); $category->name = 'testcategoryname'; $category->id = $DB->insert_record('course_categories', $category); // Set up the test Moodle course. set_config('enrol_plugins_enabled', 'manual'); set_config('defaultenrol', 1, 'enrol_manual'); set_config('status', ENROL_INSTANCE_ENABLED, 'enrol_manual'); $course = new stdClass(); $course->category = $category->id; $course->shortname = 'testcourseshortname'; $course->fullname = 'testcoursefullname'; $course = create_course($course); if ($assigncoursetoclass) { // Assign the Moodle course to a class instance. $classmoodlecourse = new classmoodlecourse(array('classid' => $pmclass->id, 'moodlecourseid' => $course->id)); $classmoodlecourse->save(); } // Set up the test program and track. $curriculum = new curriculum(array('idnumber' => 'testcurriculumidnumber')); $curriculum->save(); $track = new track(array('curid' => $curriculum->id, 'idnumber' => 'testtrackidnumber')); $track->save(); if ($assigntracktoclass) { // Assign the test track to the test class instance. $trackassignment = new trackassignment(array('trackid' => $track->id, 'classid' => $pmclass->id, 'autoenrol' => 1)); $trackassignment->save(); } // Set up the test userset. $userset = new userset(); $usersetdata = array('name' => 'testusersetname'); if ($initusersetfielddata) { $usersetdata['field_userset_group'] = 1; $usersetdata['field_userset_groupings'] = 1; } $userset->set_from_data((object) $usersetdata); $userset->save(); // Assign the test user to the test track. $usertrack = new usertrack(array('userid' => $user->id, 'trackid' => $track->id)); $usertrack->save(); $clustertrack = new clustertrack(array('clusterid' => $userset->id, 'trackid' => $track->id)); $clustertrack->save(); if ($assignusertouserset) { // Assign the test user to the test userset. $clusterassignment = new clusterassignment(array('userid' => $user->id, 'clusterid' => $userset->id, 'plugin' => 'manual')); $clusterassignment->save(); } if ($initclusterprofile) { // Set up a file we can use to auto-associate users to a userset. $field = new field(array('categoryid' => $fieldcategory->id, 'shortname' => 'autoassociate', 'name' => 'autoassociate', 'datatype' => 'bool')); $field->save(); // Ensure manual field owner exists for syncing. field_owner::ensure_field_owner_exists($field, 'manual'); $ownerid = $DB->get_field(field_owner::TABLE, 'id', array('fieldid' => $field->id, 'plugin' => 'manual')); $owner = new field_owner($ownerid); $owner->param_control = 'checkbox'; $owner->save(); field_owner::ensure_field_owner_exists($field, 'moodle_profile'); $DB->execute("UPDATE {" . field_owner::TABLE . "} SET exclude = ?", array(pm_moodle_profile::sync_to_moodle)); $fieldcontextlevel = new field_contextlevel(array('fieldid' => $field->id, 'contextlevel' => CONTEXT_ELIS_USER)); $fieldcontextlevel->save(); // The associated Moodle user profile field. require_once $CFG->dirroot . '/user/profile/definelib.php'; require_once $CFG->dirroot . '/user/profile/field/checkbox/define.class.php'; $profiledefinecheckbox = new profile_define_checkbox(); $data = new stdClass(); $data->datatype = 'checkbox'; $data->categoryid = 99999; $data->shortname = 'autoassociate'; $data->name = 'autoassociate'; $profiledefinecheckbox->define_save($data); $mfield = $DB->get_record('user_info_field', array('shortname' => 'autoassociate')); // The "cluster-profile" association. $usersetprofile = new userset_profile(array('clusterid' => $userset->id, 'fieldid' => $mfield->id, 'value' => true)); $usersetprofile->save(); } // Enrol the user in the Moodle course. $mdluserid = $DB->get_field('user', 'id', array('username' => 'testuserusername')); $roleid = create_role('testrole', 'testrole', 'testrole'); enrol_try_internal_enrol($course->id, $mdluserid, $roleid); // Set up the necessary config data. set_config('userset_groups', 1, 'elisprogram_usetgroups'); set_config('siteguest', ''); // Validate setup. $this->assertEquals(0, $DB->count_records('groups')); }