/** * 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; }
/** * Test enrol_all_track_users_in_class function. */ public function test_enrol_all_track_users_in_class() { // Fixture. $dataset = $this->createCsvDataset(array(course::TABLE => elispm::file('tests/fixtures/pmcourse.csv'), pmclass::TABLE => elispm::file('tests/fixtures/pmclass.csv'), trackassignment::TABLE => elispm::file('tests/fixtures/trackassignment.csv'), usertrack::TABLE => elispm::file('tests/fixtures/user_track.csv'), user::TABLE => elispm::file('tests/fixtures/user2.csv'))); $this->loadDataSet($dataset); // Test. $trackassignment = new trackassignment(); $trackassignment->classid = 100; $trackassignment->trackid = 1; ob_start(); $trackassignment->enrol_all_track_users_in_class(); $output = ob_get_contents(); ob_end_clean(); $this->assertEquals(get_string('n_users_enrolled', 'local_elisprogram', 1), $output); }
/** * Display enrol all action. */ public function display_enrolall() { // ELIS-3761: changed from do_enrolall() // since enrol_all_track_users_in_class() outputs message(s)! $id = required_param('id', PARAM_INT); $aid = required_param('association_id', PARAM_INT); $trackassignment = new trackassignment($aid); $trackassignment->enrol_all_track_users_in_class(); $tmppage = new trackassignmentpage(array('id' => $id)); redirect($tmppage->url, '', 15); }
function count_assigned_classes_from_track() { //return $this->_db->count_records(trackassignment::TABLE, array('trackid' => $this->trackid)); $trackassignments = trackassignment::count(new field_filter('trackid', $this->trackid), $this->_db); return $trackassignments; }
/** * items in the form * * @uses $USER */ public function definition() { global $USER; $fields = field::get_for_context_level('track'); foreach ($fields as $rec) { $field = new field($rec); if (strcmp($field->datatype, "num") == 0) { $fieldname = "field_{$field->shortname}"; if (isset($this->_customdata['obj']->{$fieldname})) { $formatnum = $field->format_number($this->_customdata['obj']->{$fieldname}); $this->_customdata['obj']->{$fieldname} = $formatnum; } } } $this->set_data($this->_customdata['obj']); $mform =& $this->_form; $mform->addElement('hidden', 'id'); $mform->setType('id', PARAM_INT); $curs = array(); if (!empty($USER->id)) { // TBD: and/or capability 'local/elisprogram:track_edit|view' ? // This is necessary for creating a new track but will prevent a parent programs from appearing // when the user has track edit permissions but not track creation permission -- ELIS-5954 $contexts = get_contexts_by_capability_for_user('curriculum', 'local/elisprogram:track_create', $USER->id); $curs = curriculum_get_listing('name', 'ASC', 0, 0, '', '', $contexts); } if (empty($this->_customdata['obj']->id)) { $curid_options = array(); if (!empty($curs)) { foreach ($curs as $cur) { $curid_options[$cur->id] = '(' . $cur->idnumber . ') ' . $cur->name; } } $mform->addElement('select', 'curid', get_string('curriculum', 'local_elisprogram') . ':', $curid_options); $mform->addRule('curid', get_string('required'), 'required', NULL, 'client'); $mform->addHelpButton('curid', 'trackform:curriculum_curid', 'local_elisprogram'); } else { // Track editing, do not allow the user to change curriculum // Make sure that the parent program for this track is always included otherwise the display is messed up // and hitting the form Cancel button causes a DB error -- ELIS-5954 $track = new track($this->_customdata['obj']->id); $curs = curriculum_get_listing('name', 'ASC', 0, 0, $track->curriculum->name); $mform->addElement('static', 'curidstatic', get_string('curriculum', 'local_elisprogram') . ':', $curs[$this->_customdata['obj']->curid]->name); $mform->addHelpButton('curidstatic', 'trackform:curriculum_curidstatic', 'local_elisprogram'); $mform->addElement('hidden', 'curid'); $mform->setType('curid', PARAM_INT); } $mform->addElement('text', 'idnumber', get_string('track_idnumber', 'local_elisprogram') . ':'); $mform->setType('idnumber', PARAM_TEXT); $mform->addRule('idnumber', get_string('required'), 'required', NULL, 'client'); $mform->addRule('idnumber', null, 'maxlength', 100); $mform->addHelpButton('idnumber', 'trackform:track_idnumber', 'local_elisprogram'); $mform->addElement('text', 'name', get_string('track_name', 'local_elisprogram') . ':'); $mform->setType('name', PARAM_TEXT); $mform->addRule('name', null, 'maxlength', 255); $mform->addRule('name', get_string('required'), 'required', NULL, 'client'); $mform->addHelpButton('name', 'trackform:track_name', 'local_elisprogram'); $mform->addElement('textarea', 'description', get_string('track_description', 'local_elisprogram') . ':'); $mform->setType('description', PARAM_CLEAN); $mform->addHelpButton('description', 'trackform:track_description', 'local_elisprogram'); $mform->addElement('date_selector', 'startdate', get_string('track_startdate', 'local_elisprogram') . ':', array('optional' => true)); $mform->addElement('date_selector', 'enddate', get_string('track_enddate', 'local_elisprogram') . ':', array('optional' => true)); $mform->addHelpButton('startdate', 'trackform:track_startdate', 'local_elisprogram'); if (!empty($this->_customdata['obj']->id)) { $trackassignobj = new trackassignment(array('trackid' => $this->_customdata['obj']->id)); } // Only show auto-create checkbox if the track does not have any classes assigned if (!isset($trackassignobj) || 0 == $trackassignobj->count_assigned_classes_from_track()) { $mform->addElement('checkbox', 'autocreate', get_string('track_autocreate', 'local_elisprogram') . ':'); $mform->addHelpButton('autocreate', 'trackform:track_autocreate', 'local_elisprogram'); } // custom fields $this->add_custom_fields('track', 'local/elisprogram:track_edit', 'local/elisprogram:track_view', 'curriculum'); $this->add_action_buttons(); }
/** * Returns an array of cluster ids that are associated to the supplied class through tracks and * the current user has access to enrol users into * * @param int $clsid The class whose association ids we care about * @return int array The array of accessible cluster ids */ public static function get_allowed_clusters($clsid) { global $USER; $context = pm_context_set::for_user_with_capability('cluster', 'local/elisprogram:assign_userset_user_class_instructor', $USER->id); $allowed_clusters = array(); // TODO: Ugly, this needs to be overhauled $cpage = new pmclasspage(); if ($cpage->_has_capability('local/elisprogram:assign_userset_user_class_instructor', $clsid)) { require_once elispm::lib('data/clusterassignment.class.php'); $cmuserid = pm_get_crlmuserid($USER->id); $userclusters = clusterassignment::find(new field_filter('userid', $cmuserid)); foreach ($userclusters as $usercluster) { $allowed_clusters[] = $usercluster->clusterid; } } //we first need to go through tracks to get to clusters $track_listing = new trackassignment(array('classid' => $clsid)); $tracks = $track_listing->get_assigned_tracks(); //iterate over the track ides, which are the keys of the array if (!empty($tracks)) { foreach (array_keys($tracks) as $track) { //get the clusters and check the context against them $clusters = clustertrack::get_clusters($track); $allowed_track_clusters = $context->get_allowed_instances($clusters, 'cluster', 'clusterid'); //append all clusters that are allowed by the available clusters contexts foreach ($allowed_track_clusters as $allowed_track_cluster) { $allowed_clusters[] = $allowed_track_cluster; } } } return $allowed_clusters; }
/** * Unassign the usersets from the track. * @param array $elements An array of userset information to unassign from 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); foreach ($elements as $classid => $label) { if ($this->can_unassign($trackid, $classid) === true) { $assignrec = $DB->get_record(trackassignment::TABLE, array('trackid' => $trackid, 'classid' => $classid)); $trackassignment = new trackassignment($assignrec); $trackassignment->delete(); } } return array('result' => 'success', 'msg' => 'Success'); }
/** * Load the options into the track selection boxes based on the * selected course. */ function definition_after_data() { $mform =& $this->_form; $courseid = $mform->getElementValue('courseid'); if ($courseid) { $courseid = (int) array_shift($courseid); } else { if (!empty($this->_customdata['obj']->courseid)) { $courseid = $this->_customdata['obj']->courseid; } else { if (!empty($this->firstcourse)) { $courseid = $this->firstcourse->id; } } } if ($courseid) { $unassigned = array(); $assigned = array(); // Multi select box for choosing tracks $tracks = track_get_listing(); $tracks = empty($tracks) ? array() : $tracks; $curcrsassign = curriculumcourse_get_list_by_course($courseid); foreach ($curcrsassign as $recid => $curcrsrec) { foreach ($tracks as $trackid => $trackrec) { if ($trackrec->curid == $curcrsrec->curriculumid) { if (!empty($this->_customdata['obj']->id)) { $trkobj = new trackassignment(array('classid' => $this->_customdata['obj']->id, 'trackid' => $trackid)); if (!$trkobj->is_class_assigned_to_track()) { $unassigned[$trackid] = $trackrec->name; } else { // Create list for currently assigned tracks $assigned[$trackid] = $trackrec->name; } } else { $unassigned[$trackid] = $trackrec->name; } } } } unset($curcrsassign); $temp = array('assignedtrack' => array_keys($assigned)); $this->set_data($temp); if ($mform->elementExists('assignedtrack')) { $track_el =& $mform->getElement('assignedtrack'); $track_el->load($assigned); } if ($mform->elementExists('track')) { $track_el =& $mform->getElement('track'); $track_el->load($unassigned); } } }
/** * Determines whether the current user is allowed to enrol users into the provided class * * @param int $classid The id of the class we are checking permissions on * * @return boolean Whether the user is allowed to enrol users into the class * */ static function can_enrol_into_class($classid) { global $USER; //check the standard capability // TODO: Ugly, this needs to be overhauled $cpage = new pmclasspage(); if ($cpage->_has_capability('local/elisprogram:class_enrol', $classid) || $cpage->_has_capability('local/elisprogram:class_enrol_userset_user', $classid)) { return true; } //get the context for the "indirect" capability $context = pm_context_set::for_user_with_capability('cluster', 'local/elisprogram:class_enrol_userset_user', $USER->id); //we first need to go through tracks to get to clusters $track_listing = new trackassignment(array('classid' => $classid)); $tracks = $track_listing->get_assigned_tracks(); //iterate over the track ides, which are the keys of the array if (!empty($tracks)) { foreach (array_keys($tracks) as $track) { //get the clusters and check the context against them $clusters = clustertrack::get_clusters($track); if (!empty($clusters)) { foreach ($clusters as $cluster) { if ($context->context_allowed($cluster->clusterid, 'cluster')) { return true; } } } } } return false; }
/** * 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')); }