Exemplo n.º 1
0
 /**
  * Edit program - course associations.
  * @param array $elements An array of course information to edit.
  * @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;
     $programid = required_param('id', PARAM_INT);
     $assocdata = required_param('assocdata', PARAM_CLEAN);
     $assocdata = $this->process_incoming_assoc_data($assocdata, $bulkaction);
     if (!is_array($assocdata)) {
         throw new Exception('Did not receive valid enrolment data.');
     }
     if (!empty($assocdata)) {
         foreach ($elements as $courseid => $label) {
             if ($this->can_manage_assoc($programid, $courseid) === true) {
                 $assoc = $DB->get_record(curriculumcourse::TABLE, array('curriculumid' => $programid, 'courseid' => $courseid));
                 if (!empty($assoc)) {
                     $curriculumcourse = new curriculumcourse($assoc);
                     $fields = array('required', 'frequency', 'timeperiod', 'position');
                     foreach ($fields as $field) {
                         if (isset($assocdata[$field])) {
                             $curriculumcourse->{$field} = $assocdata[$field];
                         }
                     }
                     $curriculumcourse->save();
                 }
             }
         }
     }
     $formatteddata = $this->format_assocdata_for_display($assocdata);
     return array('result' => 'success', 'msg' => 'Success', 'displaydata' => $formatteddata, 'saveddata' => $assocdata);
 }
Exemplo n.º 2
0
 /**
  * Validate that track-class associations can be created during a class instance
  * update action
  *
  * @param mixed $autoenrol The appropriate autoenrol value specified
  * @param int $dbautoenrol The value expected to be set in the db for autoenrol
  * @dataProvider autoenrol_provider
  */
 public function test_associate_track_during_class_update($autoenrol, $dbautoenrol)
 {
     global $CFG, $DB;
     require_once $CFG->dirroot . '/local/elisprogram/lib/setup.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/pmclass.class.php');
     require_once elispm::lib('data/track.class.php');
     // Create the course description.
     $course = new course(array('name' => 'testcoursename', 'idnumber' => 'testcourseidnumber', 'syllabus' => ''));
     $course->save();
     // Create the class instance.
     $pmclass = new pmclass(array('courseid' => $course->id, 'idnumber' => 'testclassidnumber'));
     $pmclass->save();
     // Create the curriculum / program.
     $curriculum = new curriculum(array('idnumber' => 'testcurriculumidnumber'));
     $curriculum->save();
     // Associate the course description to the program.
     $curriculumcourse = new curriculumcourse(array('curriculumid' => $curriculum->id, 'courseid' => $course->id));
     $curriculumcourse->save();
     // Create the track.
     $track = new track(array('curid' => $curriculum->id, 'idnumber' => 'testtrackidnumber'));
     $track->save();
     // Run the class instance update action.
     $record = new stdClass();
     $record->assignment = 'testcourseidnumber';
     $record->idnumber = 'testclassidnumber';
     $record->track = 'testtrackidnumber';
     if ($autoenrol !== null) {
         $record->autoenrol = $autoenrol;
     }
     $importplugin = rlip_dataplugin_factory::factory('dhimport_version1elis');
     $importplugin->fslogger = new silent_fslogger(null);
     $importplugin->class_update($record, 'bogus');
     // Validation.
     $classid = $DB->get_field(pmclass::TABLE, 'id', array('idnumber' => 'testclassidnumber'));
     $this->assertTrue($DB->record_exists(trackassignment::TABLE, array('trackid' => $track->id, 'classid' => $classid, 'autoenrol' => $dbautoenrol)));
 }
 /**
  * Test available table only shows classes that the assigner has the local/elisprogram::associate permission on.
  * @dataProvider dataprovider_available_permissions_associate
  * @param array $contextstoassign An array of information specifying the contexts to assign the associate permission on.
  *                                This is formatted like array('system' => true, 'class' => array(1, 2, 3))
  * @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_permissions_associate($contextstoassign, $tabletrackid, $expectedresults, $expectedtotal)
 {
     global $USER, $DB, $CFG;
     $userbackup = $USER;
     // Set up permissions.
     $USER = $this->setup_permissions_test();
     // 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();
         }
     }
     // Set up capabilities.
     foreach ($contextstoassign as $contexttype => $ids) {
         if ($contexttype === 'system') {
             $this->give_permission_for_context($USER->id, 'local/elisprogram:associate', context_system::instance());
         } else {
             foreach ($ids as $contextinstanceid) {
                 switch ($contexttype) {
                     case 'class':
                         $context = \local_elisprogram\context\pmclass::instance($contextinstanceid);
                         break;
                 }
                 $this->give_permission_for_context($USER->id, 'local/elisprogram:associate', $context);
             }
         }
     }
     accesslib_clear_all_caches(true);
     // 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 available table doesn't show assigned courses.
  * @dataProvider dataprovider_available_doesnt_show_assigned_courses
  * @param array $associations An array of arrays of parameters to construct curriculumcourse associations.
  * @param int $tableprogramid The ID of the program 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_courses($associations, $tableprogramid, $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());
     foreach ($associations as $association) {
         $curriculumcourse = new curriculumcourse($association);
         $curriculumcourse->save();
     }
     // Construct test table.
     $table = new deepsight_datatable_programcourse_available_mock($DB, 'test', 'http://localhost', 'testuniqid');
     $table->set_programid($tableprogramid);
     // Perform test.
     $actualresults = $table->get_search_results(array(), array(), 0, 20);
     // Verify result.
     $this->assert_search_results($expectedresults, $expectedtotal, $actualresults);
     // Restore user.
     $USER = $userbackup;
 }
Exemplo n.º 5
0
 /**
  * Test validation of duplicates
  * @expectedException data_object_validation_exception
  */
 public function test_curriculumcourse_validationpreventsduplicates()
 {
     $this->load_csv_data();
     $curriculumcourse = new curriculumcourse(array('curriculumid' => 1, 'courseid' => 1));
     $curriculumcourse->save();
 }
 /**
  * Validate that mappings are applied during the track create action
  */
 public function test_mapping_applied_during_track_create()
 {
     global $CFG, $DB;
     require_once $CFG->dirroot . '/local/eliscore/lib/data/customfield.class.php';
     require_once $CFG->dirroot . '/local/elisprogram/accesslib.php';
     require_once $CFG->dirroot . '/local/elisprogram/lib/data/course.class.php';
     require_once $CFG->dirroot . '/local/elisprogram/lib/data/curriculum.class.php';
     require_once $CFG->dirroot . '/local/elisprogram/lib/data/curriculumcourse.class.php';
     require_once $CFG->dirroot . '/local/elisprogram/lib/data/pmclass.class.php';
     require_once $CFG->dirroot . '/local/elisprogram/lib/data/track.class.php';
     $this->init_mapping();
     $customfieldid = $this->create_custom_field(CONTEXT_ELIS_TRACK);
     $course = new course(array('name' => 'testcoursename', 'idnumber' => 'testcourseidnumber', 'syllabus' => ''));
     $course->save();
     $program = new curriculum(array('idnumber' => 'testprogramidnumber'));
     $program->save();
     $curriculumcourse = new curriculumcourse(array('curriculumid' => $program->id, 'courseid' => $course->id));
     $curriculumcourse->save();
     // Run the track create action.
     $record = new stdClass();
     $record->customaction = 'create';
     $record->customcontext = 'track';
     $record->customidnumber = 'testtrackidnumber';
     $record->customname = 'testtrackname';
     $record->customdescription = 'testtrackdescription';
     $record->customstartdate = 'Jan/01/2012';
     $record->customenddate = 'Jan/01/2012';
     $record->customautocreate = 1;
     $record->customassignment = 'testprogramidnumber';
     $record->customtestfieldshortname = '1';
     $this->run_pmentity_import((array) $record);
     // Validation.
     $data = array('idnumber' => 'testtrackidnumber', 'name' => 'testtrackname', 'startdate' => rlip_timestamp(0, 0, 0, 1, 1, 2012), 'enddate' => rlip_timestamp(0, 0, 0, 1, 1, 2012));
     $this->assertTrue($DB->record_exists(track::TABLE, $data));
     $record = $DB->get_record(track::TABLE, array('idnumber' => 'testtrackidnumber'));
     $this->assertEquals('testtrackdescription', $record->description);
     $this->assertEquals(1, $DB->count_records(pmclass::TABLE));
     $instance = \local_elisprogram\context\track::instance(1);
     $this->assertTrue($DB->record_exists(field_data_int::TABLE, array('fieldid' => $customfieldid, 'contextid' => $instance->id, 'data' => 1)));
 }
Exemplo n.º 7
0
 /**
  * Add a new corequisite for a course.
  *
  * @param int $cid The course ID to add as a corequisite.
  * @param bool True on success, False otherwise.
  */
 function add_corequisite($cid, $add_to_curriculum = false)
 {
     if (empty($this->id)) {
         return false;
     }
     if ($this->is_prerequisite($cid) || $this->is_corequisite($cid)) {
         return false;
     }
     $cp = new stdClass();
     $cp->curriculumcourseid = $this->id;
     $cp->courseid = $cid;
     $cp->id = $this->_db->insert_record(coursecorequisite::TABLE, $cp);
     $result = !empty($cp->id);
     if ($result && $add_to_curriculum) {
         $data = new object();
         $data->curriculumid = $this->curriculumid;
         $data->courseid = $cid;
         $data->timeperiod = 'year';
         $currprereq = new curriculumcourse($data);
         if (!$currprereq->is_recorded()) {
             $currprereq->save();
         }
     }
     return $result;
 }
Exemplo n.º 8
0
 /**
  * Add a course to a curricula
  *
  * @param array $curriculums array value is the curriculum id
  * @return nothing
  * TODO: need to add some error checking
  */
 function add_course_to_curricula($curriculums = array())
 {
     $curcourse = new curriculumcourse();
     // Add course to curricula (one or more)
     $curcrsrecord = array();
     $curcrsrecord['id'] = 0;
     $curcrsrecord['courseid'] = $this->id;
     $curcrsrecord['required'] = 0;
     $curcrsrecord['frequency'] = 0;
     $curcrsrecord['timeperiod'] = key($curcourse->timeperiod_values);
     $curcrsrecord['position'] = 0;
     if (is_array($curriculums)) {
         foreach ($curriculums as $curr) {
             $curcrsrecord['curriculumid'] = $curr;
             $newcurcrs = new curriculumcourse($curcrsrecord);
             $status = $newcurcrs->save();
             if ($status !== true) {
                 if (!empty($status->message)) {
                     //$output .= cm_error('Record not created. Reason: '.$status->message);
                 } else {
                     //echo cm_error('Record not created.');
                 }
             } else {
                 //echo 'New record created.';
             }
         }
     }
 }
Exemplo n.º 9
0
 /**
  * Update a course
  * @todo: consider factoring this some more once other actions exist
  *
  * @param object $record One record of import data
  * @param string $filename The import file name, used for logging
  * @return boolean true on success, otherwise false
  */
 function course_update($record, $filename)
 {
     global $CFG, $DB;
     require_once $CFG->dirroot . '/local/elisprogram/lib/data/course.class.php';
     $message = "";
     //field length checking
     $lengthcheck = $this->check_course_field_lengths($record, $filename);
     if (!$lengthcheck) {
         return false;
     }
     if (isset($record->idnumber)) {
         if (!($crsid = $DB->get_field(course::TABLE, 'id', array('idnumber' => $record->idnumber)))) {
             $identifier = $this->get_field_mapping('idnumber');
             $this->fslogger->log_failure("{$identifier} value of \"{$record->idnumber}\" does not refer to a valid course description.", 0, $filename, $this->linenumber, $record, "course");
             return false;
         }
     }
     $currid = 0;
     if (isset($record->assignment)) {
         if (!($currid = $DB->get_field(curriculum::TABLE, 'id', array('idnumber' => $record->assignment)))) {
             $identifier = $this->get_field_mapping('assignment');
             $this->fslogger->log_failure("{$identifier} value of \"{$record->assignment}\" does not refer to a valid program.", 0, $filename, $this->linenumber, $record, "course");
             return false;
         } else {
             if ($DB->record_exists(curriculumcourse::TABLE, array('curriculumid' => $currid, 'courseid' => $crsid))) {
                 $identifier = $this->get_field_mapping('idnumber');
                 $message = "Course description with {$identifier} \"{$record->idnumber}\" already assigned to program with idnumber \"{$record->assignment}\".";
             }
         }
     }
     if (!$this->validate_course_data('update', $record, $filename)) {
         return false;
     }
     $record = $this->add_custom_field_prefixes($record);
     //custom field validation
     if (!$this->validate_custom_field_data('update', $record, $filename, 'course')) {
         return false;
     }
     $record = $this->initialize_course_fields($record);
     $record->id = $crsid;
     $course = new course();
     $course->set_from_data($record);
     $course->save();
     if ($currid != 0) {
         $currcrs = new curriculumcourse();
         $assoc = new stdClass();
         $assoc->curriculumid = $currid;
         $assoc->courseid = $course->id;
         $currcrs->set_from_data($assoc);
         $currcrs->save();
     }
     //associate this course description to a Moodle course, if necessary
     $this->associate_course_to_moodle_course($record, $course->id);
     //log success
     $success_message = "Course description with idnumber \"{$record->idnumber}\" successfully updated.";
     $this->fslogger->log_success($success_message, 0, $filename, $this->linenumber);
     return true;
 }
 /**
  * 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)));
 }
Exemplo n.º 11
0
 /**
  * Clone a curriculum.
  * @param array $options options for cloning.  Valid options are:
  * - 'tracks': whether or not to clone tracks (default: false)
  * - 'courses': whether or not to clone courses (default: false)
  * - 'classes': whether or not to clone classes (default: false)
  * - 'moodlecourses': 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
  * - 'targetcluster': the cluster id or cluster object (if any) to
  *   associate the clones with (default: none)
  * @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())
 {
     require_once elispm::lib('data/track.class.php');
     $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 curriculum object
     $clone = new curriculum($this);
     unset($clone->id);
     $idnumber = $clone->idnumber;
     $name = $clone->name;
     if (isset($userset)) {
         $to_append = ' - ' . $userset->name;
         // if cluster specified, append cluster's name to curriculum
         $idnumber = append_once($idnumber, $to_append, array('maxlength' => 95));
         $name = append_once($name, $to_append, array('maxlength' => 59));
     }
     //get a unique idnumber
     $clone->idnumber = generate_unique_identifier(curriculum::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 = new curriculum($clone);
     $clone->save();
     $objs['curricula'] = array($this->id => $clone->id);
     $options['targetcurriculum'] = $clone->id;
     // associate with target cluster (if any)
     if (isset($userset)) {
         clustercurriculum::associate($userset->id, $clone->id);
     }
     if (!empty($options['courses'])) {
         // copy courses
         $currcrs = curriculumcourse_get_list_by_curr($this->id);
         if ($currcrs->valid()) {
             $objs['courses'] = array();
             $objs['classes'] = array();
             foreach ($currcrs as $currcrsdata) {
                 $course = new course($currcrsdata->courseid);
                 $rv = $course->duplicate($options);
                 if (isset($rv['errors']) && !empty($rv['errors'])) {
                     $objs['errors'] = array_merge($objs['errors'], $rv['errors']);
                 }
                 if (isset($rv['courses'])) {
                     $objs['courses'] = $objs['courses'] + $rv['courses'];
                 }
                 if (isset($rv['classes'])) {
                     $objs['classes'] = $objs['classes'] + $rv['classes'];
                 }
                 // associate with curriculum
                 if (isset($rv['courses'][$course->id])) {
                     $curcrs = new curriculumcourse($currcrsdata);
                     unset($curcrs->id);
                     $curcrs->courseid = $rv['courses'][$course->id];
                     $curcrs->curriculumid = $clone->id;
                     $curcrs->save();
                 }
             }
         }
         unset($currcrs);
     }
     if (!empty($objs['errors'])) {
         return $objs;
     }
     if (!empty($options['tracks'])) {
         // copy tracks
         $tracks = track_get_listing('name', 'ASC', 0, 0, '', '', $this->id);
         if (isset($objs['courses'])) {
             $options['coursemap'] = $objs['courses'];
         }
         if (!empty($tracks)) {
             $objs['tracks'] = array();
             if (isset($objs['courses'])) {
                 $options['coursemap'] = $objs['courses'];
             }
             if (!isset($objs['classes'])) {
                 $objs['classes'] = array();
             }
             foreach ($tracks as $track) {
                 $track = new track($track);
                 $options['classmap'] = $objs['classes'];
                 $rv = $track->duplicate($options);
                 if (isset($rv['errors']) && !empty($rv['errors'])) {
                     $objs['errors'] = array_merge($objs['errors'], $rv['errors']);
                 }
                 if (isset($rv['tracks'])) {
                     $objs['tracks'] = $objs['tracks'] + $rv['tracks'];
                 }
                 if (isset($rv['classes'])) {
                     $objs['classes'] = $objs['classes'] + $rv['classes'];
                 }
             }
         }
     }
     return $objs;
 }