public function validate_class_prerequisites() { // check prerequisites $pmclass = $this->pmclass; // get all the curricula that the user is in $curricula = $this->users->get_programassignments(); foreach ($curricula as $curriculum) { $curcrs = new curriculumcourse(); $curcrs->courseid = $pmclass->courseid; $curcrs->curriculumid = $curriculum->curriculumid; if (!$curcrs->prerequisites_satisfied($this->userid)) { // prerequisites not satisfied throw new unsatisfied_prerequisites_exception($this); /* $status = new Object(); $status->message = get_string('unsatisfiedprereqs', self::LANG_FILE); $status->code = 'unsatisfiedprereqs'; //error_log('student.class::add() - student missing prereqs!'); return $status; */ } else { return true; } } }
/** * Test get_corequisites function. */ public function test_get_corequisites() { $dataset = $this->createCsvDataSet(array(curriculumcourse::TABLE => elispm::file('tests/fixtures/curriculum_course.csv'), coursecorequisite::TABLE => elispm::file('tests/fixtures/pmcourse_corequisite.csv'))); $this->loadDataSet($dataset); $curriculumcourse = new curriculumcourse(); $curriculumcourse->id = 2; $coreqs = $curriculumcourse->get_corequisites(); $this->assertEquals(array(100), $coreqs); }
/** * 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; }
function action_coreqedit() { $id = $this->required_param('id', PARAM_INT); $curcrsid = $this->required_param('association_id', PARAM_INT); $curcrs = new curriculumcourse($curcrsid); $curcrs->seturl(null, array('s' => $this->pagename, 'action' => 'coreqedit', 'id' => $id)); $coreqform = $curcrs->create_corequisite_form(); if ($coreqform->is_cancelled()) { $this->action_default(); return; } else { if ($coreqform->is_submitted() && $coreqform->is_validated()) { $form_data = $coreqform->get_data(); $output = ''; $added = 0; $deleted = 0; /// Process requested corequisite deletions. $scoreqs = isset($form_data->scoreqs) ? $form_data->scoreqs : array(); foreach ($scoreqs as $scoreq) { if ($curcrs->del_corequisite($scoreq)) { $deleted++; } } /// Process requested corequisite additions. $coreqs = isset($form_data->coreqs) ? $form_data->coreqs : array(); foreach ($coreqs as $coreq) { if (coursepage::_has_capability('block/curr_admin:course:view', $prereq) && $curcrs->add_corequisite($coreq, !empty($form_data->add_to_curriculum))) { $added++; } } if ($deleted > 0) { $delString = $deleted > 1 ? 'deleted_corequisites' : 'deleted_corequisite'; $output .= get_string($delString, 'block_curr_admin', $deleted); } if ($added > 0) { $addString = $added > 1 ? 'added_corequisites' : 'added_corequisite'; $output .= ($deleted > 0 ? ' / ' : '') . get_string($addString, 'block_curr_admin', $added); } if ($deleted > 0 || $added > 0) { $output .= "\n"; } $curriculum = $curcrs->curriculum; if ($curriculum->iscustom) { $curassid = $CURMAN->db->get_field(CURASSTABLE, 'id', 'curriculumid', $curriculum->id); $stucur = new curriculumstudent($curassid); redirect('index.php?s=stucur&section=curr&id=' . $stucur->id . '&action=edit', $output, 3); } echo $output; // recreate the form, to reflect changes in the lists $coreqform = $curcrs->create_corequisite_form(); } } $coreqform->display(); }
/** * Perform all necessary tasks to add a student enrolment to the system. * * @param array $checks what checks to perform before adding enrolling the * user. e.g. array('prereq' => 1, 'waitlist' => 1) will check that * prerequisites are satisfied, and that the class is not full * @param boolean $notify whether or not notifications should be sent if a * check fails */ function add($checks = array(), $notify = false) { global $CURMAN, $CFG, $USER; $status = true; if ($CURMAN->db->record_exists(STUTABLE, 'userid', $this->userid, 'classid', $this->classid)) { // already enrolled -- pretend we succeeded return true; } // check that the student can be enrolled first if (!empty($checks['prereq'])) { // check prerequisites $cmclass = new cmclass($this->classid); // get all the curricula that the user is in $curricula = curriculumstudent::get_curricula($this->userid); foreach ($curricula as $curriculum) { $curcrs = new curriculumcourse(); $curcrs->courseid = $cmclass->courseid; $curcrs->curriculumid = $curriculum->curid; if (!$curcrs->prerequisites_satisfied($this->userid)) { // prerequisites not satisfied if ($notify) { $data = new stdClass(); $data->userid = $this->userid; $data->classid = $this->classid; //$data->trackid = $trackid; events_trigger('crlm_prereq_unsatisfied', $data); } $status = new Object(); $status->message = get_string('unsatisfiedprereqs', 'block_curr_admin'); $status->code = 'unsatisfiedprereqs'; return $status; } } } if (!empty($checks['waitlist'])) { // check class enrolment limit $cmclass = new cmclass($this->classid); $limit = $cmclass->maxstudents; if (!empty($limit) && $limit <= student::count_enroled($this->classid)) { // class is full // put student on wait list $wait_list = new waitlist($this); $wait_list->timecreated = time(); $wait_list->position = 0; $wait_list->add(); if ($notify) { $subject = get_string('user_waitlisted', 'block_curr_admin'); $a = new object(); $a->user = $this->user->idnumber; $a->cmclass = $cmclass->idnumber; $message = get_string('user_waitlisted_msg', 'block_curr_admin', $a); $from = $user = get_admin(); notification::notify($message, $user, $from); email_to_user($user, $from, $subject, $message); } $status = new Object(); $status->message = get_string('user_waitlisted', 'block_curr_admin'); $status->code = 'user_waitlisted'; return $status; } } //set end time based on class duration $studentclass = new cmclass($this->classid); if (empty($this->endtime)) { if (isset($studentclass->duration) && $studentclass->duration) { $this->endtime = $this->enrolmenttime + $studentclass->duration; } else { // no class duration -> no end time $this->endtime = 0; } } $status = $this->data_insert_record(); // TBD: we should check this! /// Get the Moodle user ID or create a new account for this user. if (!($muserid = cm_get_moodleuserid($this->userid))) { $user = new user($this->userid); if (!($muserid = $user->synchronize_moodle_user(true, true))) { $status = new Object(); $status->message = get_string('errorsynchronizeuser', 'block_curr_admin'); $muserid = false; } } /// Enrol them into the Moodle class. if ($moodlecourseid = moodle_get_course($this->classid)) { if ($mcourse = get_record('course', 'id', $moodlecourseid)) { $enrol = $mcourse->enrol; if (!$enrol) { $enrol = $CFG->enrol; } if ($CURMAN->config->restrict_to_elis_enrolment_plugin && $enrol != 'elis') { $status = new Object(); $status->message = get_string('error_not_using_elis_enrolment', 'block_curr_admin'); return $status; } $timestart = $this->enrolmenttime; $timeend = $this->endtime; if ($role = get_default_course_role($mcourse)) { $context = get_context_instance(CONTEXT_COURSE, $mcourse->id); if (!empty($muserid)) { if (!role_assign($role->id, $muserid, 0, $context->id, $timestart, $timeend, 0, 'manual')) { $status = new Object(); $status->message = get_string('errorroleassign', 'block_curr_admin'); } } } } } else { if (!empty($muserid)) { $sturole = $CURMAN->config->enrolment_role_sync_student_role; // ELIS-2776: must still trigger events for notifications $ra = new stdClass(); $ra->roleid = !empty($sturole) ? $sturole : get_field('role', 'id', 'shortname', 'student'); $ra->contextid = context_level_base::get_custom_context_level('class', 'block_curr_admin'); // TBD $ra->userid = $muserid; $ra->component = ''; // TBD: 'enrol_elis' $ra->itemid = $this->classid; // TBD $ra->timemodified = time(); $ra->modifierid = empty($USER->id) ? 0 : $USER->id; events_trigger('role_assigned', $ra); } } return $status; }
/** * Assign a class to a track, this function also creates * and assigns the class to the curriculum default track * * @return TODO: add meaningful return value */ function save() { //add() if (empty($this->courseid)) { $this->courseid = $this->_db->get_field(pmclass::TABLE, 'courseid', array('id' => $this->classid)); } if ((empty($this->trackid) or empty($this->classid) or empty($this->courseid)) and empty(elis::$config->local_elisprogram->userdefinedtrack)) { cm_error('trackid and classid have not been properly initialized'); return false; } else { if ((empty($this->courseid) or empty($this->classid)) and elis::$config->local_elisprogram->userdefinedtrack) { cm_error('courseid has not been properly initialized'); } } if (!isset($this->id) && $this->is_class_assigned_to_track()) { //trying to re-add an existing association return; } // Determine whether class is required $curcrsobj = new curriculumcourse(array('curriculumid' => $this->track->curid, 'courseid' => $this->courseid)); // TBV: was $this->classid // insert assignment record parent::save(); //updated for ELIS2 from $this->data_insert_record() if ($this->autoenrol && $this->is_autoenrollable()) { // autoenrol all users in the track // ELIS-7582 @set_time_limit(0); $users = usertrack::get_users($this->trackid); foreach ($users as $user) { // ELIS-3460: Must check pre-requisites ... if (!$curcrsobj->prerequisites_satisfied($user->userid)) { //error_log("/local/elisprogram/lib/data/track.class.php:trackassignment::save(); pre-requisites NOT satisfied for course: {$this->courseid}, curriculum: {$this->track->curid}"); continue; } $now = time(); $stu_record = new object(); $stu_record->userid = $user->userid; $stu_record->user_idnumber = $user->idnumber; $stu_record->classid = $this->classid; $stu_record->enrolmenttime = $now; $enrolment = new student($stu_record); // check enrolment limits try { $enrolment->save(); } catch (pmclass_enrolment_limit_validation_exception $e) { // autoenrol into waitlist $wait_record = new object(); $wait_record->userid = $user->userid; $wait_record->classid = $this->classid; $wait_record->enrolmenttime = $now; $wait_record->timecreated = $now; $wait_record->position = 0; $wait_list = new waitlist($wait_record); $wait_list->save(); } catch (Exception $e) { $param = array('message' => $e->getMessage()); echo cm_error(get_string('record_not_created_reason', 'local_elisprogram', $param)); } } } events_trigger('pm_track_class_associated', $this); }
/** * 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; }
/** * Enrols a user in a track. * * @param int $userid The user id * @param int $trackid The track id */ public static function enrol($userid, $trackid) { global $DB; // make sure we don't double-enrol if ($DB->record_exists(self::TABLE, array('userid' => $userid, 'trackid' => $trackid))) { return false; } $record = new usertrack(); $record->userid = $userid; $record->trackid = $trackid; $record->save(); $user = new user($userid); $track = new track($trackid); if (!$DB->record_exists(curriculumstudent::TABLE, array('userid' => $userid, 'curriculumid' => $track->curid))) { $curstu = new curriculumstudent(); $curstu->userid = $userid; $curstu->curriculumid = $track->curid; $curstu->completed = 0; $curstu->credits = 0; $curstu->locked = 0; $curstu->save(); } events_trigger('track_assigned', $record); /** * Get autoenrollable classes in the track. Classes are autoenrollable * if: * - the autoenrol flag is set * - it is the only class in that course slot for the track */ $sql = 'SELECT classid, courseid ' . 'FROM {' . trackassignment::TABLE . '} ' . 'WHERE trackid = ? ' . 'GROUP BY courseid ' . 'HAVING COUNT(*) = 1 AND MAX(autoenrol) = 1'; $params = array($trackid); $classes = $DB->get_recordset_sql($sql, $params); foreach ($classes as $class) { // ELIS-3460: check pre-requisites ... $curcrs = new curriculumcourse(array('courseid' => $class->courseid, 'curriculumid' => $track->curid)); if (!$curcrs->prerequisites_satisfied($userid)) { //error_log("/local/elisprogram/lib/data/usertrack.class.php::enrol({$userid}); pre-requisites NOT satisfied for course: {$class->courseid}, curriculum: {$track->curid}"); continue; } $now = time(); // enrol user in each autoenrolable class $stu_record = new object(); $stu_record->userid = $userid; $stu_record->classid = $class->classid; $stu_record->enrolmenttime = $now; $enrolment = new student($stu_record); // catch enrolment limits try { $status = $enrolment->save(); } catch (pmclass_enrolment_limit_validation_exception $e) { // autoenrol into waitlist $wait_record = new object(); $wait_record->userid = $userid; $wait_record->classid = $class->classid; $wait_record->enrolmenttime = $now; $wait_record->timecreated = $now; $wait_record->position = 0; $wait_list = new waitlist($wait_record); $wait_list->save(); $status = true; } catch (Exception $e) { $param = array('message' => $e->getMessage()); echo cm_error(get_string('record_not_created_reason', 'local_elisprogram', $param)); } } unset($classes); return true; }
public function delete() { $level = context_level_base::get_custom_context_level('course', 'block_curr_admin'); $return = curriculumcourse::delete_for_course($this->id); $return = $return && cmclass::delete_for_course($this->id); $return = $return && taginstance::delete_for_course($this->id); $return = $return && coursetemplate::delete_for_course($this->id); $return = $return && delete_context($level, $this->id); return $return && $this->data_delete_record(); }
/** * Unassign the courses from the program. * @param array $elements An array of course information to unassign from the program. * @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); foreach ($elements as $courseid => $label) { if ($this->can_unassign($programid, $courseid) === true) { $assignrec = $DB->get_record(curriculumcourse::TABLE, array('curriculumid' => $programid, 'courseid' => $courseid)); $curriculumcourse = new curriculumcourse($assignrec); $curriculumcourse->delete(); } } return array('result' => 'success', 'msg' => 'Success'); }
/** * 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; }
/** * 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; }
/** * Display form to manage corequisites. */ public function display_coreqedit() { $id = $this->required_param('id', PARAM_INT); $curcrsid = $this->required_param('association_id', PARAM_INT); $curcrs = new curriculumcourse($curcrsid); $curcrs->seturl(null, array('s' => $this->pagename, 'action' => 'coreqedit', 'id' => $id)); $coreqform = $curcrs->create_corequisite_form(); if ($coreqform->is_cancelled()) { $this->display_default(); return; } else { if ($coreqform->is_submitted() && $coreqform->is_validated()) { $formdata = $coreqform->get_data(); $output = ''; $added = 0; $deleted = 0; // Process requested corequisite deletions. $scoreqs = isset($formdata->scoreqs) ? $formdata->scoreqs : array(); foreach ($scoreqs as $scoreq) { if ($curcrs->del_corequisite($scoreq)) { $deleted++; } } // Process requested corequisite additions. $coreqs = isset($formdata->coreqs) ? $formdata->coreqs : array(); // TODO: Ugly, this needs to be overhauled. $cpage = new coursepage(); foreach ($coreqs as $coreq) { if ($cpage->_has_capability('local/elisprogram:course_view', $coreq) && $curcrs->add_corequisite($coreq, !empty($formdata->add_to_curriculum))) { $added++; } } if ($deleted > 0) { $delstring = $deleted > 1 ? 'deleted_corequisites' : 'deleted_corequisite'; $output .= get_string($delstring, 'local_elisprogram', $deleted); } if ($added > 0) { $addstring = $added > 1 ? 'added_corequisites' : 'added_corequisite'; $output .= ($deleted > 0 ? ' / ' : '') . get_string($addstring, 'local_elisprogram', $added); } if ($deleted > 0 || $added > 0) { $output .= "\n"; } $curriculum = $curcrs->curriculum; if ($curriculum->iscustom) { $curassid = $this->_db->get_field(curriculumstudent::TABLE, 'id', array('curriculumid' => $curriculum->id)); $stucur = new curriculumstudent($curassid); redirect('index.php?s=stucur&section=curr&id=' . $stucur->id . '&action=edit', $output, 3); } echo $output; // Recreate the form, to reflect changes in the lists. $coreqform = $curcrs->create_corequisite_form(); } } $coreqform->display(); }
/** * Updates resulting enrolments that are auto-created after users are * assigned to user sets (specifically user-track assignments, user-program * assignments, and class enrolments in a track's default class) * * Note: This is essentially equivalent to cluster_assigned_handler but * runs a fixed number of queries for scalability reasons * * @param int $userid A specific PM user id to filter on for * consideration, or all users if zero * @param int $clusterid A specific cluster / user set id to filter * on for consideration, or all users if zero */ static function update_enrolments($userid = 0, $clusterid = 0) { global $DB; require_once elispm::lib('data/usermoodle.class.php'); // error_log("/local/elisprogram/lib/data/clusterassignment.class.php::update_enrolments({$userid}, {$clusterid})"); // ELIS-7582 @set_time_limit(0); // convert provided parameters to SQL conditions $extraconditions = array(); $extraparams = array(); if (!empty($userid)) { $users = array($userid); $extraconditions[] = 'u.id = ?'; $extraparams[] = $userid; } else { $users = clusterassignment::find(new field_filter('clusterid', $clusterid)); } if (!empty($clusterid)) { $extraconditions[] = 'clu.clusterid = ?'; $extraparams[] = $clusterid; } $extrawhere = ''; if (!empty($extraconditions)) { $extrawhere = ' AND ' . implode(' AND ', $extraconditions); } //use the current time as the time created and modified for curriculum //assignments $timenow = time(); //assign to curricula based on user-cluster and cluster-curriculum //associations $sql = "INSERT INTO {" . curriculumstudent::TABLE . "}\n (userid, curriculumid, timecreated, timemodified)\n SELECT DISTINCT u.id, clucur.curriculumid, {$timenow}, {$timenow}\n FROM {" . clusterassignment::TABLE . "} clu\n JOIN {" . user::TABLE . "} u ON u.id = clu.userid\n JOIN {" . clustercurriculum::TABLE . "} clucur\n ON clucur.clusterid = clu.clusterid\n LEFT JOIN {" . curriculumstudent::TABLE . "} ca\n ON ca.userid = u.id\n AND ca.curriculumid = clucur.curriculumid\n WHERE ca.curriculumid IS NULL\n AND clucur.autoenrol = 1\n {$extrawhere}"; $DB->execute($sql, $extraparams); //assign to curricula based on user-cluster and cluster-track //associations (assigning a user to a track auto-assigns them to //the track's curriculum, track assignment happens below) $sql = "INSERT INTO {" . curriculumstudent::TABLE . "}\n (userid, curriculumid, timecreated, timemodified)\n SELECT DISTINCT u.id, trk.curid, {$timenow}, {$timenow}\n FROM {" . clusterassignment::TABLE . "} clu\n JOIN {" . user::TABLE . "} u\n ON u.id = clu.userid\n JOIN {" . clustertrack::TABLE . "} clutrk\n ON clutrk.clusterid = clu.clusterid\n JOIN {" . track::TABLE . "} trk\n ON clutrk.trackid = trk.id\n LEFT JOIN {" . curriculumstudent::TABLE . "} ca\n ON ca.userid = u.id\n AND ca.curriculumid = trk.curid\n WHERE ca.curriculumid IS NULL\n AND clutrk.autoenrol = 1\n {$extrawhere}"; $DB->execute($sql, $extraparams); //this represents the tracks that users will be assigned to //based on user-cluster and cluster-track associations //(actual assignment happens below) $exists = "EXISTS (SELECT DISTINCT u.id, clutrk.trackid\n FROM {" . clusterassignment::TABLE . "} clu\n JOIN {" . user::TABLE . "} u\n ON u.id = clu.userid\n JOIN {" . clustertrack::TABLE . "} clutrk\n ON clutrk.clusterid = clu.clusterid\n LEFT JOIN {" . usertrack::TABLE . "} ta\n ON ta.userid = u.id\n AND ta.trackid = clutrk.trackid\n WHERE ta.trackid IS NULL\n AND clutrk.autoenrol = 1\n AND outerta.trackid = clutrk.trackid\n\t {$extrawhere})"; /** * Get autoenrollable classes in the track. Classes are autoenrollable * if: * - the autoenrol flag is set * - it is the only class in that course slot for the track */ // group the classes from the same course together // only select the ones that are the only class for that course in // the given track, and if the autoenrol flag is set $sql = "SELECT outerta.classid, outerta.courseid, trk.curid\n FROM {" . trackassignment::TABLE . "} outerta\n JOIN {" . track::TABLE . "} trk ON trk.id = outerta.trackid\n WHERE {$exists}\n GROUP BY courseid\n HAVING COUNT(*) = 1 AND MAX(autoenrol) = 1"; //go through and assign user(s) to the autoenollable classes $classes = $DB->get_records_sql($sql, $extraparams); if (!empty($classes)) { foreach ($users as $user) { $userid = is_object($user) ? $user->userid : $user; foreach ($classes as $class) { // check pre-requisites $curcrs = new curriculumcourse(array('courseid' => $class->courseid, 'curriculumid' => $class->curid)); if (!$curcrs->prerequisites_satisfied($userid)) { continue; } $now = time(); // enrol user in each autoenrolable class $stu_record = new object(); $stu_record->userid = $userid; $stu_record->classid = $class->classid; $stu_record->enrolmenttime = $now; $enrolment = new student($stu_record); // catch enrolment limits try { $enrolment->save(); } catch (pmclass_enrolment_limit_validation_exception $e) { // autoenrol into waitlist $wait_record = new object(); $wait_record->userid = $userid; $wait_record->classid = $class->classid; $wait_record->enrolmenttime = $now; $wait_record->timecreated = $now; $wait_record->position = 0; $wait_list = new waitlist($wait_record); $wait_list->save(); } catch (Exception $e) { $param = array('message' => $e->getMessage()); if (in_cron()) { mtrace(get_string('record_not_created_reason', 'local_elisprogram', $param)); } else { echo cm_error(get_string('record_not_created_reason', 'local_elisprogram', $param)); } } } } } //assign to tracks based on user-cluster and cluster-track //associations $sql = "INSERT INTO {" . usertrack::TABLE . "}\n (userid, trackid)\n SELECT DISTINCT u.id, clutrk.trackid\n FROM {" . clusterassignment::TABLE . "} clu\n JOIN {" . user::TABLE . "} u\n ON u.id = clu.userid\n JOIN {" . clustertrack::TABLE . "} clutrk\n ON clutrk.clusterid = clu.clusterid\n LEFT JOIN {" . usertrack::TABLE . "} ta\n ON ta.userid = u.id\n AND ta.trackid = clutrk.trackid\n WHERE ta.trackid IS NULL\n AND clutrk.autoenrol = 1\n {$extrawhere}"; $DB->execute($sql, $extraparams); //update site-level "cluster groups" //TODO: make sure all "cluster groups" scenarios are handled here, and look at //performance in more detal if (!empty($userid) && file_exists(elispm::file('plugins/usetgroups/lib.php'))) { require_once elispm::file('plugins/usetgroups/lib.php'); //need the Moodle user id $mdluserid = $DB->get_field(usermoodle::TABLE, 'muserid', array('cuserid' => $userid)); if ($mdluserid) { //find all assignments for this user $assignments = $DB->get_recordset(clusterassignment::TABLE, array('userid' => $userid)); foreach ($assignments as $assignment) { //update site-level group assignments userset_groups_update_site_course($assignment->clusterid, true, $mdluserid); } } //update course-level group assignment userset_groups_update_groups(array('mdlusr.cuserid' => $userid)); } }
public function delete() { //delete associated classes $filter = new field_filter('courseid', $this->id); pmclass::delete_records($filter, $this->_db); //clean up associated records curriculumcourse::delete_records($filter, $this->_db); coursetemplate::delete_records($filter, $this->_db); // ELIS-8528: Remove LOs/completion elements. coursecompletion::delete_records($filter, $this->_db); parent::delete(); $context = \local_elisprogram\context\course::instance($this->id); $context->delete(); }
/** * 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))); }
/** * 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($options = array()) { require_once CURMAN_DIRLOCATION . '/lib/track.class.php'; $objs = array('errors' => array()); if (isset($options['targetcluster'])) { $cluster = $options['targetcluster']; if (!is_object($cluster) || !is_a($cluster, 'cluster')) { $options['targetcluster'] = $cluster = new cluster($cluster); } } // clone main curriculum object $clone = new curriculum($this); unset($clone->id); if (isset($cluster)) { // if cluster specified, append cluster's name to curriculum $clone->name = $clone->name . ' - ' . $cluster->name; $clone->idnumber = $clone->idnumber . ' - ' . $cluster->name; } $clone = new curriculum(addslashes_recursive($clone)); if (!$clone->add()) { $objs['errors'][] = get_string('failclustcpycurr', 'block_curr_admin', $this); return $objs; } $objs['curricula'] = array($this->id => $clone->id); $options['targetcurriculum'] = $clone->id; // associate with target cluster (if any) if (isset($cluster)) { clustercurriculum::associate($cluster->id, $clone->id); } if (!empty($options['courses'])) { // copy courses $currcrs = curriculumcourse_get_list_by_curr($this->id); if (!empty($currcrs)) { $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->add(); } } } } 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; }
/** * Assign a class to a track, this function also creates * and assigns the class to the curriculum default track * * @return TODO: add meaningful return value */ function add() { global $CURMAN; if (empty($this->courseid)) { $this->courseid = $CURMAN->db->get_field(CLSTABLE, 'courseid', 'id', $this->classid); } if ((empty($this->trackid) or empty($this->classid) or empty($this->courseid)) and empty($CURMAN->config->userdefinedtrack)) { cm_error('trackid and classid have not been properly initialized'); return false; } elseif ((empty($this->courseid) or empty($this->classid)) and $CURMAN->config->userdefinedtrack) { cm_error('courseid has not been properly initialized'); } if (empty($CURMAN->config->userdefinedtrack)) { if ($this->is_class_assigned_to_track()) { return false; } // Determine whether class is required $curcrsobj = new curriculumcourse(array('curriculumid' => $this->track->curid, 'courseid' => $this->classid)); // insert assignment record $this->data_insert_record(); if ($this->autoenrol && $this->is_autoenrollable()) { // autoenrol all users in the track $users = usertrack::get_users($this->trackid); if (!empty($users)) { foreach ($users as $user) { $stu_record = new object(); $stu_record->userid = $user->userid; $stu_record->user_idnumber = $user->idnumber; $stu_record->classid = $this->classid; $stu_record->enrolmenttime = time(); $enrolment = new student($stu_record); // check prerequisites and enrolment limits $enrolment->add(array('prereq' => 1, 'waitlist' => 1)); } } } } else { // Look for all the curricula course is linked to - // then pull up the default system track for each curricula - // and add class to each default system track $currculums = curriculumcourse_get_list_by_course($this->courseid); $currculums = is_array($currculums) ? $currculums : array(); foreach ($currculums as $recid => $record) { // Create default track for curriculum $trkojb = new track(array('curid' => $record->curriculumid)); $trkid = $trkojb->create_default_track(); // Create track assignment object $trkassign = new trackassignmentclass(array('trackid' => $trkid, 'classid' => $this->classid, 'courseid' => $this->courseid)); // Check if class is already assigned to default track if (!$trkassign->is_class_assigned_to_default_track()) { // Determine whether class is required $curcrsobj = new curriculumcourse(array('curriculumid' => $trkassign->track->curid, 'courseid' => $trkassign->courseid)); // Get required field and determine if class is autoenrol eligible $trkassign->autoenrol = (1 == $trkassign->cmclass->count_course_assignments($trkassign->cmclass->courseid) and true === $curcrsobj->is_course_required()) ? 1 : 0; // assign class to the curriculum's default track $trkassign->assign_class_to_default_track(); } } } events_trigger('crlm_track_class_associated', $this); return true; }
public function body_definition() { $mform =& $this->_form; $parent_obj = $this->_customdata['parent_obj']; $curriculumid = $parent_obj->id; $coursecurriculum = new curriculumcourse(); $coursecurriculum->curriculumid = $curriculumid; $mform->addElement('hidden', 'curriculumid', $curriculumid); $mform->setType('curriculumid', PARAM_INT); $mform->addElement('text', 'curriculumname', get_string('curriculum', 'block_curr_admin') . ':', 'readonly="readonly"'); $mform->setType('curriculumname', PARAM_TEXT); $mform->setHelpButton('curriculumname', array('coursecurriculumform/curriculumname', get_string('curriculum', 'block_curr_admin'), 'block_curr_admin')); $contexts = coursepage::get_contexts('block/curr_admin:associate'); $courses_avail = $coursecurriculum->get_courses_avail(array('contexts' => $contexts)); $courses = array(); if (isset($this->_customdata['obj'])) { $course = $this->_customdata['obj']->course; $curriculum = $this->_customdata['obj']->curriculum; $courses[$course->id] = $course->name; } else { if (is_array($courses_avail)) { foreach ($courses_avail as $crsid => $c) { $courses[$crsid] = $c->name . ' (' . $c->idnumber . ')'; } natcasesort($courses); } } $mform->addElement('select', 'courseid', get_string('course', 'block_curr_admin') . ':', $courses); $mform->addRule('courseid', null, 'required', null, 'client'); $mform->setHelpButton('courseid', array('coursecurriculumform/coursename', get_string('course', 'block_curr_admin'), 'block_curr_admin')); $this->set_data(array('curriculumname' => $parent_obj->name)); }
/** * 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))); }
/** * 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))); }
function xmldb_block_curr_admin_upgrade($oldversion = 0) { global $CFG, $THEME, $db; $result = true; if ($oldversion < 2009010102) { $context = get_context_instance(CONTEXT_SYSTEM, SITEID); if ($role = get_record('role', 'shortname', 'curriculumadmin')) { if ($role->name == 'Bundle Administrator') { $role->name = 'Curriculum Administrator'; addslashes_object($role); update_record('role', $role); } } if (!empty($role->id)) { require_once dirname(__FILE__) . '/access.php'; if (!empty($block_curr_admin_capabilities)) { foreach ($block_curr_admin_capabilities as $capname => $caprules) { $result = $result && assign_capability($capname, CAP_ALLOW, $role->id, $context->id); } } } } if ($oldversion < 2009010103) { $table = new XMLDBTable('crlm_curriculum'); $field = new XMLDBField('timetocomplete'); $field->setAttributes(XMLDB_TYPE_CHAR, '64', NULL, XMLDB_NOTNULL, NULL, NULL, NULL, '0h, 0d, 0w, 0m, 0y', 'timemodified'); $result = $result && add_field($table, $field); $field = new XMLDBField('frequency'); $field->setAttributes(XMLDB_TYPE_CHAR, '64', NULL, XMLDB_NOTNULL, NULL, NULL, NULL, '0h, 0d, 0w, 0m, 0y', 'timetocomplete'); $result = $result && add_field($table, $field); } if ($oldversion < 2009010104) { $table = new XMLDBTable('crlm_config'); $table->comment = 'Curriculum management configuration values.'; // fields $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $f = $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, false, null, null, null, null); $f = $table->addFieldInfo('value', XMLDB_TYPE_TEXT, 'medium', null, false, null, null, null, null); // PK and indexes $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); $table->addIndexInfo('name_ix', XMLDB_INDEX_UNIQUE, array('name')); $result = $result && create_table($table); } if ($oldversion < 2009010105) { $table = new XMLDBTable('crlm_coursetemplate'); $table->comment = 'Course templates'; // fields $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $f = $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, null, null, null, null); $f = $table->addFieldInfo('location', XMLDB_TYPE_CHAR, '255', null, false, null, null, null, null); $f = $table->addFieldInfo('templateclass', XMLDB_TYPE_CHAR, '255', null, false, null, null, null, null); // PK and indexes $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); $table->addIndexInfo('courseid_ix', XMLDB_INDEX_UNIQUE, array('courseid')); $result = $result && create_table($table); } if ($oldversion < 2009010106) { $table = new XMLDBTable('crlm_cluster_curriculum'); $table->comment = 'Association between clusters and curricula'; // fields $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $f = $table->addFieldInfo('clusterid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'id'); $f->comment = 'Foreign key to cluster id'; $f = $table->addFieldInfo('curriculumid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'clusterid'); $f->comment = 'Foreign key to curriculum id'; // PK and indexes $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); $table->addIndexInfo('cluster_idx', XMLDB_INDEX_NOTUNIQUE, array('clusterid')); $result = $result && create_table($table); } if ($oldversion < 2009010108) { $table = new XMLDBTable('crlm_cluster_track'); $table->comment = 'Association between clusters and tracks'; // fields $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $f = $table->addFieldInfo('clusterid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'id'); $f->comment = 'Foreign key to cluster id'; $f = $table->addFieldInfo('trackid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'clusterid'); $f->comment = 'Foreign key to track id'; $f = $table->addFieldInfo('autounenrol', XMLDB_TYPE_INTEGER, '1', null, true, null, null, null, null, 'trackid'); $f->comment = 'Whether or not to remove a user from classes when removed from cluster'; // PK and indexes $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); $table->addIndexInfo('cluster_idx', XMLDB_INDEX_NOTUNIQUE, array('clusterid')); $result = $result && create_table($table); $table = new XMLDBTable('crlm_usercluster'); $f = new XMLDBField('autoenrol'); $f->setAttributes(XMLDB_TYPE_INTEGER, '1', null, true, null, null, null, 1, 'clusterid'); $f->comment = 'Whether users should be autoenrolled in tracks associated with this cluster.'; $result = $result && add_field($table, $f); } if ($oldversion < 2009010109) { /// Define table crlm_class_moodle to be created $table = new XMLDBTable('crlm_class_moodle'); /// Adding fields to table crlm_class_moodle $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('classid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $table->addFieldInfo('moodlecourseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $table->addFieldInfo('enroltype', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, null, null, null, null, '0'); $table->addFieldInfo('enrolplugin', XMLDB_TYPE_CHAR, '20', null, null, null, null, null, 'crlm'); $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); /// Adding keys to table crlm_class_moodle $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); $table->addKeyInfo('mdl_currclasmood_clamoo_uix', XMLDB_KEY_UNIQUE, array('classid', 'moodlecourseid')); /// Launch create table for crlm_class_moodle $result = $result && create_table($table); } if ($oldversion < 2009010110) { $table = new XMLDBTable('crlm_user_track'); $table->comment = 'User enrolment in tracks'; // fields $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $f = $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'id'); $f->comment = 'Foreign key to user id'; $f = $table->addFieldInfo('trackid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'userid'); $f->comment = 'Foreign key to track id'; // PK and indexes $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); $result = $result && create_table($table); } if ($result && $oldversion < 2009010112) { /// Define table crlm_notification_log to be created $table = new XMLDBTable('crlm_notification_log'); /// Adding fields to table crlm_notification_log $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('event', XMLDB_TYPE_CHAR, '166', null, null, null, null, null, null); $table->addFieldInfo('instance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $table->addFieldInfo('data', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null); $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); /// Adding keys to table crlm_notification_log $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Adding indexes to table crlm_notification_log $table->addIndexInfo('event_inst_user_ix', XMLDB_INDEX_NOTUNIQUE, array('event', 'instance', 'userid')); /// Launch create table for crlm_notification_log $result = $result && create_table($table); } if ($result && $oldversion < 2009010113) { /// Define index event_inst_user_ix (not unique) to be dropped from crlm_notification_log $table = new XMLDBTable('crlm_notification_log'); $index = new XMLDBIndex('event_inst_user_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('event', 'instance', 'userid')); /// Launch drop index event_inst_user_ix $result = $result && drop_index($table, $index); /// Define index event_inst_user_ix (not unique) to be added to crlm_notification_log $table = new XMLDBTable('crlm_notification_log'); $index = new XMLDBIndex('event_inst_user_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('userid', 'instance', 'event')); /// Launch add index event_inst_user_ix $result = $result && add_index($table, $index); } if ($result && $oldversion < 2009010114) { // Creating track table $table = new XMLDBTable('crlm_track'); $table->comment = 'Track table'; // fields $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $f = $table->addFieldInfo('curid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $f = $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, null); $f = $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null); $f = $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null); $f = $table->addFieldInfo('startdate', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $f = $table->addFieldInfo('enddate', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $f = $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $f = $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); // PK and indexes $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); $table->addIndexInfo('track_curr_idx', XMLDB_INDEX_NOTUNIQUE, array('curid')); $result = $result && create_table($table); $table = new XMLDBTable('crlm_track_class'); $table->comment = 'Track class table'; $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $f = $table->addFieldInfo('trackid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $f = $table->addFieldInfo('classid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $f = $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $f = $table->addFieldInfo('requried', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $f = $table->addFieldInfo('autoenrol', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $f = $table->addFieldInfo('default', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $f = $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $f = $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); $table->addIndexInfo('trackid_idx', XMLDB_INDEX_NOTUNIQUE, array('trackid')); $table->addIndexInfo('track_classid_idx', XMLDB_INDEX_NOTUNIQUE, array('classid')); $table->addIndexInfo('track_courseid_idx', XMLDB_INDEX_NOTUNIQUE, array('courseid')); $result = $result && create_table($table); } if ($result && $oldversion < 2009010115) { /// Define table crlm_cluster_profile to be created $table = new XMLDBTable('crlm_cluster_profile'); /// Adding fields to table crlm_cluster_profile $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('clusterid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('value', XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null, null, null); /// Adding keys to table crlm_cluster_profile $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Launch create table for crlm_cluster_profile $result = $result && create_table($table); /// Define table crlm_cluster_assignments to be created $table = new XMLDBTable('crlm_cluster_assignments'); /// Adding fields to table crlm_cluster_assignments $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('clusterid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('plugin', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, null, null); /// Adding keys to table crlm_cluster_assignments $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Launch create table for crlm_cluster_assignments $result = $result && create_table($table); } if ($result && $oldversion < 2009010116) { $table = new XMLDBTable('crlm_track_class'); $field = new XMLDBField('default'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', 'autoenrol'); $result = $result && drop_field($table, $field); $field = new XMLDBField('defaulttrack'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', 'autoenrol'); $result = $result && add_field($table, $field); } if ($result && $oldversion < 2009010117) { /// Remove obsolete job code tables if they exist. $table = new XMLDBTable('crlm_jobcode_list'); if (table_exists($table)) { drop_table($table); } $table = new XMLDBTable('crlm_curriculum_jobcode'); if (table_exists($table)) { drop_table($table); } } if ($result && $oldversion < 2009010118) { /// Removing defaulttrack column from table $table = new XMLDBTable('crlm_track_class'); $field = new XMLDBField('defaulttrack'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', 'autoenrol'); $result = $result && drop_field($table, $field); /// Adding defaulttrack column to table $table = new XMLDBTable('crlm_track'); $field = new XMLDBField('defaulttrack'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', 'enddate'); $result = $result && add_field($table, $field); } if ($result && $oldversion < 2009010119) { /// Define field completed to be added to crlm_curriculum_assignment $table = new XMLDBTable('crlm_curriculum_assignment'); $field = new XMLDBField('completed'); $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'curriculumid'); /// Launch add field completed $result = $result && add_field($table, $field); /// Define field completiontime to be added to crlm_curriculum_assignment $field = new XMLDBField('timecompleted'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'completed'); /// Launch add field completiontime $result = $result && add_field($table, $field); /// Define field credits to be added to crlm_curriculum_assignment $field = new XMLDBField('credits'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'timecompleted'); /// Launch add field credits $result = $result && add_field($table, $field); /// Define field locked to be added to crlm_curriculum_assignment $table = new XMLDBTable('crlm_curriculum_assignment'); $field = new XMLDBField('locked'); $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'credits'); /// Launch add field locked $result = $result && add_field($table, $field); /// Define key mdl_currcurrassi_usecur_uix (unique) to be dropped from crlm_curriculum_assignment $key = new XMLDBKey('mdl_currcurrassi_usecur_uix'); $key->setAttributes(XMLDB_KEY_UNIQUE, array('userid', 'curriculumid')); /// Launch drop key mdl_currcurrassi_usecur_uix $result = $result && drop_key($table, $key); /// Define index mdl_currcurrassi_usecurcom_ix (not unique) to be added to crlm_curriculum_assignment $index = new XMLDBIndex('mdl_currcurrassi_usecurcom_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('userid', 'curriculumid', 'completed')); /// Launch add index mdl_currcurrassi_usecurcom_ix $result = $result && add_index($table, $index); /// Define index completed_ix (not unique) to be added to crlm_curriculum_assignment $index = new XMLDBIndex('completed_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('completed')); /// Launch add index completed_ix $result = $result && add_index($table, $index); } if ($result && $oldversion < 2009010120) { /// Define field autoenrol to be added to crlm_cluster_assignments $table = new XMLDBTable('crlm_cluster_assignments'); $field = new XMLDBField('autoenrol'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'plugin'); /// Launch add field autoenrol $result = $result && add_field($table, $field); } if ($result && $oldversion < 2009010121) { if (!record_exists('mnet_application', 'name', 'java')) { $application = new stdClass(); $application->name = 'java'; $application->display_name = 'Java servlet'; $application->xmlrpc_server_url = '/mnet/server'; $application->sso_land_url = '/mnet/land.jsp'; $result = $result && insert_record('mnet_application', $application, false); } } if ($result && $oldversion < 2009010122) { $table = new XMLDBTable('crlm_track_class'); $field = new XMLDBField('requried'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'courseid'); $result = $result && drop_field($table, $field); } if ($result && $oldversion < 2009010125) { $result = $result && execute_sql('CREATE OR REPLACE VIEW `courseNforums` AS select `f`.`id` AS `forumid`,concat(`c`.`shortname`,_utf8\' | \',`f`.`name`) AS `courseNforumname` from (`mdl_forum` `f` join `mdl_course` `c` on((`c`.`id` = `f`.`course`))) order by `c`.`shortname`,`f`.`name`'); } if ($result && $oldversion < 2009010126) { $table = new XMLDBTable('crlm_cluster_curriculum'); $table->comment = 'Association between clusters and curricula'; // fields $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $f = $table->addFieldInfo('clusterid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'id'); $f->comment = 'Foreign key to cluster id'; $f = $table->addFieldInfo('curriculumid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'clusterid'); $f->comment = 'Foreign key to curriculum id'; // PK and indexes $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); $table->addIndexInfo('cluster_idx', XMLDB_INDEX_NOTUNIQUE, array('clusterid')); $result = $result && (table_exists($table) || create_table($table)); $table = new XMLDBTable('crlm_cluster_track'); $table->comment = 'Association between clusters and tracks'; // fields $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $f = $table->addFieldInfo('clusterid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'id'); $f->comment = 'Foreign key to cluster id'; $f = $table->addFieldInfo('trackid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'clusterid'); $f->comment = 'Foreign key to track id'; $f = $table->addFieldInfo('autounenrol', XMLDB_TYPE_INTEGER, '1', null, true, null, null, null, null, 'trackid'); $f->comment = 'Whether or not to remove a user from classes when removed from cluster'; // PK and indexes $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); $table->addIndexInfo('cluster_idx', XMLDB_INDEX_NOTUNIQUE, array('clusterid')); $result = $result && (table_exists($table) || create_table($table)); } if ($result && $oldversion < 2009010127) { // fix silly typos $newtable = new XMLDBTable('crlm_user_track'); $oldtable = new XMLDBTable('clrm_user_track'); $result = $result && (table_exists($newtable) || rename_table($oldtable, 'crlm_user_track')); $oldtable = new XMLDBTable('clrm_cluster_track'); $result = $result && (!table_exists($oldtable) || drop_table($oldtable)); $oldtable = new XMLDBTable('clrm_cluster_curriculum'); $result = $result && (!table_exists($oldtable) || drop_table($oldtable)); } if ($result && $oldversion < 2009010128) { require_once $CFG->dirroot . '/curriculum/lib/lib.php'; cm_migrate_moodle_users(); } if ($result && $oldversion < 2009010131) { /// Get rid of any outdated cluster data we might have lying around. if ($CFG->dbfamily == 'postgres') { $sql = "DELETE FROM {$CFG->prefix}crlm_cluster_assignments\n WHERE id IN (\n SELECT ca.clusterid\n FROM {$CFG->prefix}crlm_cluster_assignments ca\n LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = ca.clusterid\n WHERE c.id IS NULL\n )"; $result = $result && execute_sql($sql); $sql = "DELETE FROM {$CFG->prefix}crlm_cluster_curriculum\n WHERE id IN (\n SELECT cc.clusterid\n FROM {$CFG->prefix}crlm_cluster_curriculum cc\n LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = cc.clusterid\n WHERE c.id IS NULL\n )"; $result = $result && execute_sql($sql); $sql = "DELETE FROM {$CFG->prefix}crlm_cluster_profile\n WHERE id IN (\n SELECT cp.clusterid\n FROM {$CFG->prefix}crlm_cluster_profile cp\n LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = cp.clusterid\n WHERE c.id IS NULL\n )"; $result = $result && execute_sql($sql); $sql = "DELETE FROM {$CFG->prefix}crlm_cluster_track\n WHERE id IN (\n SELECT ct.clusterid\n FROM {$CFG->prefix}crlm_cluster_track ct\n LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = ct.clusterid\n WHERE c.id IS NULL\n )"; $result = $result && execute_sql($sql); $sql = "DELETE FROM {$CFG->prefix}crlm_usercluster\n WHERE id IN (\n SELECT uc.clusterid\n FROM {$CFG->prefix}crlm_usercluster uc\n LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = uc.clusterid\n WHERE c.id IS NULL\n )"; $result = $result && execute_sql($sql); } else { $sql = "DELETE ca FROM {$CFG->prefix}crlm_cluster_assignments ca\n LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = ca.clusterid\n WHERE c.id IS NULL"; $result = $result && execute_sql($sql); $sql = "DELETE cc FROM {$CFG->prefix}crlm_cluster_curriculum cc\n LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = cc.clusterid\n WHERE c.id IS NULL"; $result = $result && execute_sql($sql); $sql = "DELETE cp FROM {$CFG->prefix}crlm_cluster_profile cp\n LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = cp.clusterid\n WHERE c.id IS NULL"; $result = $result && execute_sql($sql); $sql = "DELETE ct FROM {$CFG->prefix}crlm_cluster_track ct\n LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = ct.clusterid\n WHERE c.id IS NULL"; $result = $result && execute_sql($sql); $sql = "DELETE uc FROM {$CFG->prefix}crlm_usercluster uc\n LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = uc.clusterid\n WHERE c.id IS NULL"; $result = $result && execute_sql($sql); } } if ($result && $oldversion < 2009010133) { /// Define field leader to be added to crlm_cluster_assignments $table = new XMLDBTable('crlm_cluster_assignments'); $field = new XMLDBField('leader'); $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'autoenrol'); /// Launch add field leader $result = $result && add_field($table, $field); /// Define field leader to be added to crlm_usercluster $table = new XMLDBTable('crlm_usercluster'); $field = new XMLDBField('leader'); $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'autoenrol'); /// Launch add field leader $result = $result && add_field($table, $field); } if ($result && $oldversion < 2009010134) { /// Define field inactive to be added to crlm_user $table = new XMLDBTable('crlm_user'); $field = new XMLDBField('inactive'); $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, '0', 'timemodified'); /// Launch add field inactive $result = $result && add_field($table, $field); } if ($result && $oldversion < 2009010137) { $roleid = get_field('role', 'id', 'shortname', 'curriculumadmin'); if (!empty($roleid)) { $context = get_context_instance(CONTEXT_SYSTEM, SITEID); require_once dirname(dirname(__FILE__)) . '/db/access.php'; if (!empty($block_curr_admin_capabilities)) { foreach ($block_curr_admin_capabilities as $capname => $caprules) { $result = $result && assign_capability($capname, CAP_ALLOW, $roleid, $context->id); } } } } if ($result && $oldversion < 2009010139) { global $CURMAN; require_once $CFG->dirroot . '/curriculum/lib/classmoodlecourse.class.php'; $moodleclasses = moodle_get_classes(); if (!empty($moodleclasses)) { foreach ($moodleclasses as $class) { $context = get_context_instance(CONTEXT_COURSE, $class->moodlecourseid); $sql = "DELETE cmce\n FROM {$CURMAN->db->prefix_table('user')} u\n JOIN {$CURMAN->db->prefix_table('role_assignments')} ra ON u.id = ra.userid\n JOIN {$CURMAN->db->prefix_table(STUTABLE)} cmce ON u.idnumber = cmce.user_idnumber\n WHERE ra.roleid NOT IN ({$CFG->gradebookroles})\n AND ra.contextid " . get_related_contexts_string($context) . "AND cmce.classid = {$class->classid}"; $result = $result && execute_sql($sql); } } } if ($result && $oldversion < 2009010140) { delete_records('crlm_cluster_profile', 'fieldid', 0); } if ($result && $oldversion < 2009010141) { set_config('field_lock_idnumber', 'locked', 'auth/manual'); } if ($result && $oldversion < 2009010143) { /// Define table crlm_wait_list to be created $table = new XMLDBTable('crlm_wait_list'); /// Adding fields to table crlm_wait_list $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('classid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $table->addFieldInfo('position', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null); /// Adding keys to table crlm_wait_list $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Launch create table for crlm_wait_list $result = $result && create_table($table); } if ($result && $oldversion < 2009010145) { $table = new XMLDBTable('crlm_wait_list'); $field = new XMLDBField('enrolmenttime'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $result = $result && add_field($table, $field); } if ($result && $oldversion < 2009010146) { // make sure trackclass's courseids are set // Let's just assume that all non-Postgres DB's use the same syntax as MySQL and call it a day. if ($CFG->dbfamily == 'postgres') { $sql = "UPDATE {$CFG->prefix}crlm_track_class\n SET courseid = c.courseid\n FROM {$CFG->prefix}crlm_track_class tc, {$CFG->prefix}crlm_class c\n WHERE tc.classid = c.id AND tc.courseid = 0"; } else { $sql = "UPDATE {$CFG->prefix}crlm_track_class tc, {$CFG->prefix}crlm_class c\n SET tc.courseid = c.courseid\n WHERE tc.classid = c.id AND tc.courseid = 0"; } $result = $result && execute_sql($sql); } if ($result && $oldversion < 2009010147) { // make sure all users have an idnumber $users = get_records('crlm_user', 'idnumber', ''); foreach ($users as $user) { $user = addslashes_recursive($user); $mu = addslashes_recursive(get_record('user', 'username', $user->username)); if (empty($mu->idnumber)) { $user->idnumber = $mu->idnumber = $mu->username; update_record('user', $mu); update_record('crlm_user', $user); } else { if (!get_record('crlm_user', 'idnumber', $mu->idnumber)) { $user->idnumber = $mu->idnumber; update_record('crlm_user', $user); } else { if (!get_record('crlm_user', 'idnumber', $user->username)) { $user->idnumber = $mu->idnumber; update_record('crlm_user', $user); } } } } } if ($result && $oldversion < 2009010149) { /// Define index clusterid_idx (not unique) to be added to crlm_cluster_assignments $table = new XMLDBTable('crlm_cluster_assignments'); $index = new XMLDBIndex('clusterid_idx'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('clusterid')); /// Launch add index clusterid_idx $result = $result && add_index($table, $index); /// Define index userid_idx (not unique) to be added to crlm_cluster_assignments $table = new XMLDBTable('crlm_cluster_assignments'); $index = new XMLDBIndex('userid_idx'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('userid')); /// Launch add index userid_idx $result = $result && add_index($table, $index); /// Define index clusterid_idx (not unique) to be added to crlm_cluster_profile $table = new XMLDBTable('crlm_cluster_profile'); $index = new XMLDBIndex('clusterid_idx'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('clusterid')); /// Launch add index clusterid_idx $result = $result && add_index($table, $index); } if ($result && $oldversion < 2009010151) { $table = new XMLDBTable('crlm_curriculum'); $field = new XMLDBField('priority'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $result = $result && add_field($table, $field); } if ($result && $oldversion < 2009010150) { require_once CURMAN_DIRLOCATION . '/lib/curriculumcourse.class.php'; $sql = "SELECT cp.id, cp.courseid, cc.curriculumid\n FROM {$CFG->prefix}crlm_course_prerequisite cp\n JOIN {$CFG->prefix}crlm_curriculum_course cc ON cc.id = cp.curriculumcourseid\n WHERE cp.courseid NOT IN (\n SELECT _cc.courseid\n FROM {$CFG->prefix}crlm_curriculum_course _cc\n WHERE _cc.curriculumid = cc.curriculumid\n )"; $students = get_records_sql($sql); $retval = 0; foreach ($students as $student) { $data = new object(); $data->curriculumid = $student->curriculumid; $data->courseid = $student->courseid; $data->timeperiod = 'year'; $currprereq = new curriculumcourse($data); $retval = $result && $currprereq->add(); } $results = $retval; } if ($result && $oldversion < 2009103001) { $table = new XMLDBTable('crlm_curriculum'); $field = new XMLDBField('priority'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0'); $result = $result && add_field($table, $field); /// Define table context_levels to be created $table = new XMLDBTable('context_levels'); /// Adding fields to table context_levels $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('component', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); /// Adding keys to table context_levels $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Adding indexes to table context_levels $table->addIndexInfo('name', XMLDB_INDEX_NOTUNIQUE, array('name')); $table->addIndexInfo('component', XMLDB_INDEX_NOTUNIQUE, array('component')); /// Launch create table for context_levels $result = $result && create_table($table); } if ($result && $oldversion < 2009103003) { /// Define table crlm_field to be created $table = new XMLDBTable('crlm_field'); /// Adding fields to table crlm_field $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('shortname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('name', XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('datatype', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null); $table->addFieldInfo('categoryid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('required', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('visible', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('forceunique', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('defaultdata', XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null); $table->addFieldInfo('params', XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null); $table->addFieldInfo('syncwithmoodle', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); /// Adding keys to table crlm_field $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Adding indexes to table crlm_field $table->addIndexInfo('shortname_idx', XMLDB_INDEX_NOTUNIQUE, array('shortname')); /// Launch create table for crlm_field $result = $result && create_table($table); /// Define table crlm_field_category to be created $table = new XMLDBTable('crlm_field_category'); /// Adding fields to table crlm_field_category $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); /// Adding keys to table crlm_field_category $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Launch create table for crlm_field_category $result = $result && create_table($table); /// Define table crlm_field_contextlevel to be created $table = new XMLDBTable('crlm_field_contextlevel'); /// Adding fields to table crlm_field_contextlevel $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('contextlevel', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); /// Adding keys to table crlm_field_contextlevel $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Launch create table for crlm_field_contextlevel $result = $result && create_table($table); /// Define table crlm_field_data to be created $table = new XMLDBTable('crlm_field_data'); /// Adding fields to table crlm_field_data $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('contextid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('data', XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null, null, null); /// Adding keys to table crlm_field_data $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Adding indexes to table crlm_field_data $table->addIndexInfo('context_idx', XMLDB_INDEX_NOTUNIQUE, array('contextid')); /// Launch create table for crlm_field_data $result = $result && create_table($table); } //if ($result && $oldversion < 2010040501) { // require_once($CFG->dirroot . '/blocks/curr_admin/lib.php'); // $result = $result && create_views(); // create with default prefix // $result = $result && create_views(''); // create with no prefix //} if ($result && $oldversion < 2010040501) { $table = new XMLDBTable('crlm_field_map'); /// Adding fields to table crlm_field_data $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('context', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('type', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('elis_field', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('data_field', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); /// Adding keys to table crlm_field_data $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Launch create table for crlm_field_data $result = $result && create_table($table); } if ($result && $oldversion < 2010040501) { require_once "{$CFG->dirroot}/curriculum/lib/customfield.class.php"; // make sure all ELIS users have a context update_capabilities('block/curr_admin'); $ctxlvl = context_level_base::get_custom_context_level('user', 'block_curr_admin'); $rs = get_recordset('crlm_user'); while ($rec = rs_fetch_next_record($rs)) { get_context_instance($ctxlvl, $rec->id); } // sync profile fields $fields = field::get_for_context_level($ctxlvl); $fields = $fields ? $fields : array(); require_once $CFG->dirroot . '/curriculum/plugins/moodle_profile/custom_fields.php'; foreach ($fields as $field) { $fieldobj = new field($field); $sync_profile_field_with_moodle(); } } if ($result && $oldversion < 2010040501) { require_once $CFG->dirroot . '/curriculum/lib/notifications.php'; if (!empty($CFG->coursemanager)) { $context_course = CONTEXT_COURSE; $sql = "SELECT role_assignments.* FROM {$CFG->prefix}role_assignments role_assignments\n JOIN {$CFG->prefix}context context\n ON role_assignments.contextid = context.id\n WHERE role_assignments.roleid IN ({$CFG->coursemanager})\n AND context.contextlevel = {$context_course}"; if ($records = get_records_sql($sql)) { foreach ($records as $record) { cm_assign_instructor_from_mdl($record); } } } } if ($result && $oldversion < 2010063001) { $table = new XMLDBTable('crlm_curriculum_assignment'); $field = new XMLDBField('user_idnumber'); $result = $result && drop_field($table, $field); $table = new XMLDBTable('crlm_class_enrolment'); $field = new XMLDBField('user_idnumber'); $result = $result && drop_field($table, $field); $table = new XMLDBTable('crlm_class_instructor'); $field = new XMLDBField('user_idnumber'); $result = $result && drop_field($table, $field); $table = new XMLDBTable('crlm_class_attendance'); $field = new XMLDBField('user_idnumber'); $result = $result && drop_field($table, $field); } //if ($result && $oldversion < 2010063002) { // require_once($CFG->dirroot . '/blocks/curr_admin/lib.php'); // $result = $result && create_views(); // create with default prefix // $result = $result && create_views(''); // create with no prefix //} if ($result && $oldversion < 2010040505) { require_once $CFG->dirroot . '/curriculum/lib/lib.php'; $result = $result && cm_notify_duplicate_user_info(true); } if ($result && $oldversion < 2010040506 && $oldversion >= 2010040501) { global $CFG, $CURMAN; // fix instructor assignments that were migrated incorrectly in the // 2010040501 upgrade code (ELIS-1171) // remove the obvious errors (instructors assigned to a non-existent class) $context_course = CONTEXT_COURSE; $sql = "DELETE\n FROM {$CFG->prefix}crlm_class_instructor\n WHERE NOT EXISTS (SELECT 'x' FROM {$CFG->prefix}crlm_class cmclass\n WHERE cmclass.id = {$CFG->prefix}crlm_class_instructor.classid)"; $result = $result && execute_sql($sql); // warn about other potentially incorrect instructor assignments require_once $CFG->dirroot . '/curriculum/lib/lib.php'; cm_notify_incorrect_instructor_assignment(true); // make sure the correct assignments are added if (!empty($CFG->coursemanager)) { require_once $CFG->dirroot . '/curriculum/lib/notifications.php'; $context_course = CONTEXT_COURSE; $sql = "SELECT role_assignments.* FROM {$CFG->prefix}role_assignments role_assignments\n JOIN {$CFG->prefix}context context\n ON role_assignments.contextid = context.id\n WHERE role_assignments.roleid IN ({$CFG->coursemanager})\n AND context.contextlevel = {$context_course}"; if ($records = get_records_sql($sql)) { foreach ($records as $record) { cm_assign_instructor_from_mdl($record); } } } } if ($result && $oldversion < 2010063002) { //get the class table $table = new XMLDBTable('crlm_class'); //add the auto enrol enabled flag $field = new XMLDBField('enrol_from_waitlist'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, '0'); $result = $result && add_field($table, $field); } if ($result && $oldversion < 2010063005) { /// Define table crlm_field_data to be dropped $table = new XMLDBTable('crlm_field_map'); /// Launch drop table for crlm_field_data $result = $result && drop_table($table); } if ($result && $oldversion < 2010063006) { /// Define table crlm_field_data to be renamed to crlm_field_data_text $table = new XMLDBTable('crlm_field_data'); /// Define index context_idx (not unique) to be dropped form crlm_field_data_text $index = new XMLDBIndex('context_idx'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('contextid')); /// Launch drop index context_idx $result = $result && drop_index($table, $index); /// Changing nullability of field contextid on table crlm_field_data_text to null $field = new XMLDBField('contextid'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'id'); /// Define index context_idx (not unique) to be added to crlm_field_data_text $index = new XMLDBIndex('context_idx'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('contextid')); /// Launch add index context_idx $result = $result && add_index($table, $index); /// Define index field_idx (not unique) to be added to crlm_field_data_text $index = new XMLDBIndex('field_idx'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('fieldid')); /// Launch add index field_idx $result = $result && add_index($table, $index); /// Launch change of nullability for field contextid $result = $result && change_field_notnull($table, $field); /// Launch rename table for crlm_field_data $result = $result && rename_table($table, 'crlm_field_data_text'); /// Define table crlm_field_owner to be created $table = new XMLDBTable('crlm_field_owner'); /// Adding fields to table crlm_field_owner $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null); $table->addFieldInfo('plugin', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null); $table->addFieldInfo('exclude', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, '0'); $table->addFieldInfo('params', XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null); /// Adding keys to table crlm_field_owner $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Adding indexes to table crlm_field_owner $table->addIndexInfo('field_idx', XMLDB_INDEX_NOTUNIQUE, array('fieldid')); /// Launch create table for crlm_field_owner $result = $result && create_table($table); /// Define table crlm_field_category_context to be created $table = new XMLDBTable('crlm_field_category_context'); /// Adding fields to table crlm_field_category_context $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('categoryid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null); $table->addFieldInfo('contextlevel', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null); /// Adding keys to table crlm_field_category_context $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Adding indexes to table crlm_field_category_context $table->addIndexInfo('contextlevel_idx', XMLDB_INDEX_NOTUNIQUE, array('contextlevel')); $table->addIndexInfo('category_idx', XMLDB_INDEX_NOTUNIQUE, array('categoryid')); /// Launch create table for crlm_field_category_context $result = $result && create_table($table); $usercontextid = context_level_base::get_custom_context_level('user', 'block_curr_admin'); if ($usercontextid) { $sql = "INSERT INTO {$CFG->prefix}crlm_field_category_context\n (categoryid, contextlevel)\n SELECT id, {$usercontextid}\n FROM {$CFG->prefix}crlm_field_category"; $result = $result && execute_sql($sql); } /// Define table crlm_field_data_int to be created $table = new XMLDBTable('crlm_field_data_int'); /// Adding fields to table crlm_field_data_int $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('contextid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null); $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('data', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null); /// Adding keys to table crlm_field_data_int $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Adding indexes to table crlm_field_data_int $table->addIndexInfo('context_idx', XMLDB_INDEX_NOTUNIQUE, array('contextid')); $table->addIndexInfo('field_idx', XMLDB_INDEX_NOTUNIQUE, array('fieldid')); /// Launch create table for crlm_field_data_int $result = $result && create_table($table); /// Define table crlm_field_data_num to be created $table = new XMLDBTable('crlm_field_data_num'); /// Adding fields to table crlm_field_data_num $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('contextid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null); $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('data', XMLDB_TYPE_NUMBER, '15, 5', null, XMLDB_NOTNULL, null, null, null, null); /// Adding keys to table crlm_field_data_num $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Adding indexes to table crlm_field_data_num $table->addIndexInfo('context_idx', XMLDB_INDEX_NOTUNIQUE, array('contextid')); $table->addIndexInfo('field_idx', XMLDB_INDEX_NOTUNIQUE, array('fieldid')); /// Launch create table for crlm_field_data_num $result = $result && create_table($table); /// Define table crlm_field_data_char to be created $table = new XMLDBTable('crlm_field_data_char'); /// Adding fields to table crlm_field_data_char $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); $table->addFieldInfo('contextid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null); $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); $table->addFieldInfo('data', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null); /// Adding keys to table crlm_field_data_char $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /// Adding indexes to table crlm_field_data_char $table->addIndexInfo('context_idx', XMLDB_INDEX_NOTUNIQUE, array('contextid')); $table->addIndexInfo('field_idx', XMLDB_INDEX_NOTUNIQUE, array('fieldid')); /// Launch create table for crlm_field_data_char $result = $result && create_table($table); $records = get_records('crlm_field'); if ($records) { // FIXME: set data type based on old data type foreach ($records as $record) { unset($record->name); unset($record->shortname); unset($record->description); $record->defaultdata = addslashes($record->defaultdata); if (isset($record->syncwithmoodle)) { // make sure the crlm_field table hasn't been upgraded yet switch ($record->syncwithmoodle) { case 2: // sync from Moodle // create "moodle_profile" owner if (!record_exists('crlm_field_owner', 'fieldid', $record->id, 'plugin', 'moodle_profile')) { $owner = new stdClass(); $owner->fieldid = $record->id; $owner->plugin = 'moodle_profile'; $owner->exclude = true; $result = $result && insert_record('crlm_field_owner', $owner); } // create "manual" owner if (!record_exists('crlm_field_owner', 'fieldid', $record->id, 'plugin', 'manual')) { $owner = new stdClass(); $owner->fieldid = $record->id; $owner->plugin = 'manual'; $owner->exclude = false; $owner->params = array('edit_capability' => 'disabled'); if (!$record->visible) { $owner->params['view_capability'] = 'moodle/user:viewhiddendetails'; } $owner->params = serialize($owner->params); $result = $result && insert_record('crlm_field_owner', $owner); } $record->datatype = 'text'; break; case 1: // sync to Moodle // create "moodle_profile" owner if (!record_exists('crlm_field_owner', 'fieldid', $record->id, 'plugin', 'moodle_profile')) { $owner = new stdClass(); $owner->fieldid = $record->id; $owner->plugin = 'moodle_profile'; $owner->exclude = false; $result = $result && insert_record('crlm_field_owner', $owner); } // NOTE: fall through // NOTE: fall through default: // no sync or invalid user // create "manual" owner $controltype = $record->datatype; $record->datatype = 'text'; if (!record_exists('crlm_field_owner', 'fieldid', $record->id, 'plugin', 'manual')) { $owner = new stdClass(); $owner->fieldid = $record->id; $owner->plugin = 'manual'; $owner->exclude = false; $owner->params = array('control' => $controltype, 'required' => $record->required); if ($record->locked) { $owner->params['edit_capability'] = 'moodle/user:update'; } if (!$record->visible) { $owner->params['view_capability'] = 'moodle/user:viewhiddendetails'; } if (!empty($record->params)) { $owner->params += unserialize($record->params); } switch ($controltype) { case 'checkbox': // legacy checkboxes are all boolean $record->datatype = 'bool'; $data_recs = get_records('crlm_field_data_text', 'fieldid', $record->id); foreach ($data_recs as $data_rec) { delete_records('crlm_field_data_text', 'id', $data_rec->id); unset($data_rec->id); insert_record('crlm_field_data_int', $data_rec); } break; case 'menu': // menu items should be short text $record->datatype = 'char'; $data_recs = get_records('crlm_field_data_text', 'fieldid', $record->id); foreach ($data_recs as $data_rec) { delete_records('crlm_field_data_text', 'id', $data_rec->id); unset($data_rec->id); insert_record('crlm_field_data_char', $data_rec); } case 'text': $owner->params['columns'] = $owner->params['size']; unset($owner->params['size']); break; } $owner->params = addslashes(serialize($owner->params)); $result = $result && insert_record('crlm_field_owner', $owner); } break; } $record->params = ''; $result = $result && update_record('crlm_field', $record); if (!empty($record->defaultdata)) { if (!record_exists_select('crlm_field_data_text', "fieldid = {$record->id} AND contextid IS NULL")) { $defaultdata = new stdClass(); $defaultdata->fieldid = $record->id; $defaultdata->data = $record->defaultdata; $result = $result && insert_record('crlm_field_data_text', $defaultdata); } } } } } $table = new XMLDBTable('crlm_field'); /// Define field required to be dropped from crlm_field $field = new XMLDBField('required'); /// Launch drop field required $result = $result && drop_field($table, $field); /// Define field locked to be dropped from crlm_field $field = new XMLDBField('locked'); /// Launch drop field locked $result = $result && drop_field($table, $field); /// Define field visible to be dropped from crlm_field $field = new XMLDBField('visible'); /// Launch drop field visible $result = $result && drop_field($table, $field); /// Define field defaultdata to be dropped from crlm_field $field = new XMLDBField('defaultdata'); /// Launch drop field defaultdata $result = $result && drop_field($table, $field); /// Define field syncwithmoodle to be dropped from crlm_field $field = new XMLDBField('syncwithmoodle'); /// Launch drop field syncwithmoodle $result = $result && drop_field($table, $field); /// Define field multivalued to be added to crlm_field $field = new XMLDBField('multivalued'); $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, '0', 'sortorder'); /// Launch add field multivalued $result = $result && add_field($table, $field); } if ($result && $oldversion < 2010063007) { // install.xml accidentally had the char table use an integer data field /// Changing type of field data on table crlm_field_data_char to char $table = new XMLDBTable('crlm_field_data_char'); $field = new XMLDBField('data'); $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null, 'fieldid'); /// Launch change of type for field data $result = $result && change_field_type($table, $field); } if ($result && $oldversion < 2010063008) { $table = new XMLDBTable('crlm_cluster_curriculum'); $field = new XMLDBField('autoenrol'); $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'curriculumid'); $result = $result && add_field($table, $field); $table = new XMLDBTable('crlm_cluster_track'); $field = new XMLDBField('autoenrol'); $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'trackid'); $result = $result && add_field($table, $field); /// Define field parent to be added to crlm_cluster $table = new XMLDBTable('crlm_cluster'); $field = new XMLDBField('parent'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'display'); /// Launch add field parent $result = $result && add_field($table, $field); /// Define field depth to be added to crlm_cluster $field = new XMLDBField('depth'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'parent'); /// Launch add field depth $result = $result && add_field($table, $field); } if ($result && $oldversion < 2010063013) { /* * Curriculum */ $table = new XMLDBTable('crlm_curriculum'); //name field $index = new XMLDBIndex('name_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('name')); if (!index_exists($table, $index)) { $result = $result && add_index($table, $index); } /* * Course */ $table = new XMLDBTable('crlm_course'); //name field $index = new XMLDBIndex('name_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('name')); if (!index_exists($table, $index)) { $result = $result && add_index($table, $index); } //credits field $index = new XMLDBIndex('credits_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('credits')); if (!index_exists($table, $index)) { $result = $result && add_index($table, $index); } /* * Class */ $table = new XMLDBTable('crlm_class'); //idnumber field $index = new XMLDBIndex('idnumber_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('idnumber')); if (!index_exists($table, $index)) { $result = $result && add_index($table, $index); } //enddate field $index = new XMLDBIndex('enddate_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('enddate')); if (!index_exists($table, $index)) { $result = $result && add_index($table, $index); } /* * Class enrolment */ $table = new XMLDBTable('crlm_class_enrolment'); //completetime field $index = new XMLDBIndex('completetime_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('completetime')); if (!index_exists($table, $index)) { $result = $result && add_index($table, $index); } //completestatusid field $index = new XMLDBIndex('completestatusid_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('completestatusid')); if (!index_exists($table, $index)) { $result = $result && add_index($table, $index); } /* * CM user */ $table = new XMLDBTable('crlm_user'); //lastname field $index = new XMLDBIndex('lastname_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('lastname')); if (!index_exists($table, $index)) { $result = $result && add_index($table, $index); } //firstname field $index = new XMLDBIndex('firstname_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('firstname')); if (!index_exists($table, $index)) { $result = $result && add_index($table, $index); } } if ($result && $oldversion < 2010063015) { /// Define field autocreated to be added to crlm_class_moodle $table = new XMLDBTable('crlm_class_moodle'); $field = new XMLDBField('autocreated'); $field->setAttributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, null, null, '-1', 'timemodified'); /// Launch add field autocreated $result = $result && add_field($table, $field); } if ($result && $oldversion < 2010111300) { $table = new XMLDBTable('crlm_curriculum_assignment'); $field = new XMLDBField('timeexpired'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'timecompleted'); // Launch add field multivalued $result = $result && add_field($table, $field); } if ($result && $oldversion < 2011050200) { /// Define index startdate_ix (not unique) to be added to crlm_class $table = new XMLDBTable('crlm_class'); $index = new XMLDBIndex('startdate_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('startdate')); $result = $result && add_index($table, $index); /// Define index enrolmenttime_ix (not unique) to be added to crlm_class_enrolment $table = new XMLDBTable('crlm_class_enrolment'); $index = new XMLDBIndex('enrolmenttime_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('enrolmenttime')); $result = $result && add_index($table, $index); /// Define index locked_ix (not unique) to be added to crlm_class_graded $table = new XMLDBTable('crlm_class_graded'); $index = new XMLDBIndex('locked_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('locked')); $result = $result && add_index($table, $index); /// Define index timegraded_ix (not unique) to be added to crlm_class_graded $table = new XMLDBTable('crlm_class_graded'); $index = new XMLDBIndex('timegraded_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('timegraded')); $result = $result && add_index($table, $index); /// Define index classid_ix (not unique) to be added to crlm_class_moodle $table = new XMLDBTable('crlm_class_moodle'); $index = new XMLDBIndex('classid_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('classid')); $result = $result && add_index($table, $index); /// Define index curriculumid_ix (not unique) to be added to crlm_cluster_curriculum $table = new XMLDBTable('crlm_cluster_curriculum'); $index = new XMLDBIndex('curriculumid_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('curriculumid')); $result = $result && add_index($table, $index); /// Define index fieldid_ix (not unique) to be added to crlm_cluster_profile $table = new XMLDBTable('crlm_cluster_profile'); $index = new XMLDBIndex('fieldid_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('fieldid')); $result = $result && add_index($table, $index); /// Define index trackid_ix (not unique) to be added to crlm_cluster_track $table = new XMLDBTable('crlm_cluster_track'); $index = new XMLDBIndex('trackid_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('trackid')); $result = $result && add_index($table, $index); /// Define index idnumber_ix (not unique) to be added to crlm_course_completion $table = new XMLDBTable('crlm_course_completion'); $index = new XMLDBIndex('idnumber_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('idnumber')); $result = $result && add_index($table, $index); /// Define index sortorder_ix (not unique) to be added to crlm_field $table = new XMLDBTable('crlm_field'); $index = new XMLDBIndex('sortorder_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('sortorder')); $result = $result && add_index($table, $index); /// Define index username_ix (not unique) to be added to crlm_user $table = new XMLDBTable('crlm_user'); $index = new XMLDBIndex('username_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('username')); $result = $result && add_index($table, $index); /// Define index inactive_ix (not unique) to be added to crlm_user $table = new XMLDBTable('crlm_user'); $index = new XMLDBIndex('inactive_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('inactive')); $result = $result && add_index($table, $index); /// Define index userid_ix (not unique) to be added to crlm_user_track $table = new XMLDBTable('crlm_user_track'); $index = new XMLDBIndex('userid_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('userid')); $result = $result && add_index($table, $index); /// Define index trackid_ix (not unique) to be added to crlm_user_track $table = new XMLDBTable('crlm_user_track'); $index = new XMLDBIndex('trackid_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('trackid')); $result = $result && add_index($table, $index); /// Define index classid_ix (not unique) to be added to crlm_wait_list $table = new XMLDBTable('crlm_wait_list'); $index = new XMLDBIndex('classid_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('classid')); $result = $result && add_index($table, $index); /// Define index userid_ix (not unique) to be added to crlm_wait_list $table = new XMLDBTable('crlm_wait_list'); $index = new XMLDBIndex('userid_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('userid')); $result = $result && add_index($table, $index); } if ($result && $oldversion < 2011050201) { // make sure that hours are within 24 hours $sql = "UPDATE {$CFG->prefix}crlm_class\n SET starttimehour = MOD(starttimehour, 24),\n endtimehour = MOD(endtimehour, 24)"; $result = $result && execute_sql($sql); } if ($result && $oldversion < 2011050202) { /// Changing type of field credits on table crlm_class_enrolment to number $table = new XMLDBTable('crlm_class_enrolment'); $field = new XMLDBField('credits'); $field->setAttributes(XMLDB_TYPE_NUMBER, '10, 2', XMLDB_UNSIGNED, null, null, null, null, '0', 'grade'); /// Launch change of type for field credits $result = $result && change_field_type($table, $field); /// Changing type of field credits on table crlm_curriculum_assignment to number $table = new XMLDBTable('crlm_curriculum_assignment'); $field = new XMLDBField('credits'); $field->setAttributes(XMLDB_TYPE_NUMBER, '10, 2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'timeexpired'); /// Launch change of type for field credits $result = $result && change_field_type($table, $field); /// Changing type of field reqcredits on table crlm_curriculum to number $table = new XMLDBTable('crlm_curriculum'); $field = new XMLDBField('reqcredits'); $field->setAttributes(XMLDB_TYPE_NUMBER, '10, 2', XMLDB_UNSIGNED, null, null, null, null, null, 'description'); /// Launch change of type for field reqcredits $result = $result && change_field_type($table, $field); // update student class credits with decimal credits if ($CFG->dbfamily == 'postgres') { $sql = "UPDATE {$CFG->prefix}crlm_class_enrolment\n SET credits = CAST(c.credits AS numeric)\n FROM {$CFG->prefix}crlm_class_enrolment e, {$CFG->prefix}crlm_class cls, {$CFG->prefix}crlm_course c\n WHERE e.classid = cls.id\n AND cls.courseid = c.id\n AND e.credits = CAST(c.credits AS integer)"; } else { $sql = "UPDATE {$CFG->prefix}crlm_class_enrolment e, {$CFG->prefix}crlm_class cls, {$CFG->prefix}crlm_course c\n SET e.credits = c.credits\n WHERE e.classid = cls.id\n AND cls.courseid = c.id\n AND e.credits = CAST(c.credits AS unsigned)"; } $result = $result && execute_sql($sql); } if ($result && $oldversion < 2011050203) { //create a new column in the notification log table //to store the user who triggered the notification $table = new XMLDBTable('crlm_notification_log'); $field = new XMLDBField('fromuserid'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0, 'userid'); $field->comment = 'CM user id that triggered the notification.'; $result = $result && add_field($table, $field); //populate data, assuming that the user who received the notification is the one whose //criteria spawned it //NOTE: this fudges data and the side-effect implies that if someone had received a notification //for another user and satisfy the same criteria for the same instance for themself, they will not //receive a similar notification $sql = "UPDATE {$CFG->prefix}crlm_notification_log\n SET fromuserid = userid"; $result = $result && execute_sql($sql); if ($result) { /// Define field certificatecode to be added to crlm_curriculum_assignment $table = new XMLDBTable('crlm_curriculum_assignment'); $field = new XMLDBField('certificatecode'); $field->setAttributes(XMLDB_TYPE_CHAR, '40', null, null, null, null, null, null, 'locked'); /// Launch add field autocreated $result = $result && add_field($table, $field); /// Define index userid_ix (not unique) to be added to crlm_wait_list $index = new XMLDBIndex('certificatecode_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('certificatecode')); $result = $result && add_index($table, $index); } } if ($result && $oldversion < 2011050204) { $table = new XMLDBTable('crlm_notification_log'); $index = new XMLDBIndex('event_inst_fuser_ix'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('fromuserid', 'instance', 'event')); $result = add_index($table, $index); } if ($result && $oldversion < 2011050205) { // Update the ELIS class enrolment grade value and completion score grade values so they store float // (decimal) values $table = new XMLDBTable('crlm_class_enrolment'); $field = new XMLDBField('grade'); $field->setAttributes(XMLDB_TYPE_NUMBER, '10', null, XMLDB_NOTNULL, null, null, null, '0'); $field->setDecimals(5); $result = change_field_type($table, $field); $table = new XMLDBTable('crlm_class_graded'); $result = $result && change_field_type($table, $field); /* * Find all of the completion grades that are synchronised from Moodle grade items that are not locked and * where the ELIS completion score does not match the value in the Moodle gradebook and delete those * completion scores so they can be re-synchronised from Moodle with the correct float values stored. */ // Attempt to handle different DBs in the most efficient way possible if ($CFG->dbfamily == 'postgres') { $sql = "DELETE FROM {$CFG->prefix}crlm_class_graded\n WHERE id IN (\n SELECT ccg.id\n FROM mdl_crlm_user cu\n INNER JOIN {$CFG->prefix}crlm_class_enrolment cce ON cce.userid = cu.id\n INNER JOIN {$CFG->prefix}crlm_class_graded ccg ON (ccg.userid = cce.userid AND ccg.classid = cce.classid)\n INNER JOIN {$CFG->prefix}crlm_course_completion ccc ON ccc.id = ccg.completionid\n INNER JOIN {$CFG->prefix}crlm_class_moodle ccm ON ccm.classid = ccg.classid\n INNER JOIN {$CFG->prefix}user u ON u.idnumber = cu.idnumber\n INNER JOIN {$CFG->prefix}course c ON c.id = ccm.moodlecourseid\n INNER JOIN {$CFG->prefix}grade_items gi ON (gi.courseid = c.id AND gi.idnumber = ccc.idnumber)\n INNER JOIN {$CFG->prefix}grade_grades gg ON (gg.itemid = gi.id AND gg.userid = u.id)\n WHERE ccg.locked = 0\n AND ccc.idnumber != ''\n AND gi.itemtype != 'course'\n AND ccg.grade != gg.finalgrade\n AND gg.finalgrade IS NOT NULL\n )"; $result = $result && execute_sql($sql); } else { if ($CFG->dbfamily == 'mysql') { $sql = "DELETE ccg\n FROM mdl_crlm_user cu\n INNER JOIN {$CFG->prefix}crlm_class_enrolment cce ON cce.userid = cu.id\n INNER JOIN {$CFG->prefix}crlm_class_graded ccg ON (ccg.userid = cce.userid AND ccg.classid = cce.classid)\n INNER JOIN {$CFG->prefix}crlm_course_completion ccc ON ccc.id = ccg.completionid\n INNER JOIN {$CFG->prefix}crlm_class_moodle ccm ON ccm.classid = ccg.classid\n INNER JOIN {$CFG->prefix}user u ON u.idnumber = cu.idnumber\n INNER JOIN {$CFG->prefix}course c ON c.id = ccm.moodlecourseid\n INNER JOIN {$CFG->prefix}grade_items gi ON (gi.courseid = c.id AND gi.idnumber = ccc.idnumber)\n INNER JOIN {$CFG->prefix}grade_grades gg ON (gg.itemid = gi.id AND gg.userid = u.id)\n WHERE ccg.locked = 0\n AND ccc.idnumber != ''\n AND gi.itemtype != 'course'\n AND ccg.grade != gg.finalgrade\n AND gg.finalgrade IS NOT NULL"; $result = $result && execute_sql($sql); } else { $sql = "SELECT ccg.id, ccg.grade\n FROM mdl_crlm_user cu\n INNER JOIN {$CFG->prefix}crlm_class_enrolment cce ON cce.userid = cu.id\n INNER JOIN {$CFG->prefix}crlm_class_graded ccg ON (ccg.userid = cce.userid AND ccg.classid = cce.classid)\n INNER JOIN {$CFG->prefix}crlm_course_completion ccc ON ccc.id = ccg.completionid\n INNER JOIN {$CFG->prefix}crlm_class_moodle ccm ON ccm.classid = ccg.classid\n INNER JOIN {$CFG->prefix}user u ON u.idnumber = cu.idnumber\n INNER JOIN {$CFG->prefix}course c ON c.id = ccm.moodlecourseid\n INNER JOIN {$CFG->prefix}grade_items gi ON (gi.courseid = c.id AND gi.idnumber = ccc.idnumber)\n INNER JOIN {$CFG->prefix}grade_grades gg ON (gg.itemid = gi.id AND gg.userid = u.id)\n WHERE ccg.locked = 0\n AND ccc.idnumber != ''\n AND gi.itemtype != 'course'\n AND ccg.grade != gg.finalgrade\n AND gg.finalgrade IS NOT NULL"; if ($rs = get_recordset_sql($sql)) { while ($cg = rs_fetch_next_record($rs)) { $result = $result && delete_records('crlm_class_graded', 'id', $cg->id); } rs_close($rs); } } } // Force a re-synchronization of ELIS class grade data require_once $CFG->dirroot . '/curriculum/lib/lib.php'; cm_synchronize_moodle_class_grades(); } if ($result && $oldversion < 2011050206) { /// Define table crlm_field_data to be dropped $table = new XMLDBTable('crlm_field_map'); if (table_exists($table)) { /// Launch drop table for crlm_field_data $result = drop_table($table); } } if ($result && $oldversion < 2011050207) { // Delete duplicate class completion element grades $xmldbtable = new XMLDBTable('crlm_class_graded_temp'); if (table_exists($xmldbtable)) { drop_table($xmldbtable); } // Create a temporary table $result = $result && execute_sql("CREATE TABLE {$CFG->prefix}crlm_class_graded_temp LIKE {$CFG->prefix}crlm_class_graded"); // Store the unique values in the temporary table $sql = "INSERT INTO {$CFG->prefix}crlm_class_graded_temp\n SELECT MAX(id) AS id, classid, userid, completionid, grade, locked, timegraded, timemodified\n FROM {$CFG->prefix}crlm_class_graded\n GROUP BY classid, userid, completionid, locked"; $result = $result && execute_sql($sql); // Detect if there are still duplicates in the temporary table $sql = "SELECT COUNT(*) AS count, classid, userid, completionid, grade, locked, timegraded, timemodified\n FROM {$CFG->prefix}crlm_class_graded_temp\n GROUP BY classid, userid, completionid\n ORDER BY count DESC, classid ASC, userid ASC, completionid ASC"; if ($result && ($dupcount = get_record_sql($sql, true))) { if ($dupcount->count > 1) { if ($rs = get_recordset_sql($sql)) { while ($result && ($dupe = rs_fetch_next_record($rs))) { if ($dupe->count <= 1) { continue; } $classid = $dupe->classid; $userid = $dupe->userid; $goodid = 0; // The ID of the record we will keep // Look for the earliest locked grade record for this user and keep that (if any are locked) $sql2 = "SELECT id, grade, locked, timegraded\n FROM mdl_crlm_class_graded\n WHERE classid = {$classid}\n AND userid = {$userid}\n ORDER BY timegraded ASC"; if ($rs2 = get_recordset_sql($sql2)) { while ($rec = rs_fetch_next_record($rs2)) { // Store the last record ID just in case we need it for cleanup $lastid = $rec->id; // Don't bother looking at remaining records if we have found a record to keep if (!empty($goodid)) { continue; } if ($rec->locked = 1) { $goodid = $rec->id; } } rs_close($rs2); // We need to make sure we have a record ID to keep, if we found no "complete" and locked // records, let's just keep the last record we saw if (empty($goodid)) { $goodid = $lastid; } $select = 'classid = ' . $classid . ' AND userid = ' . $userid . ' AND id != ' . $goodid; } if (!empty($select)) { $result = $result && delete_records_select('crlm_class_graded_temp', $select); } } } } } // Drop the real table $result = $result && execute_sql("DROP TABLE {$CFG->prefix}crlm_class_graded"); // Replace the real table with the temporary table that now only contains unique values. $result = $result && execute_sql("ALTER TABLE {$CFG->prefix}crlm_class_graded_temp RENAME TO {$CFG->prefix}crlm_class_graded"); } return $result; }