예제 #1
0
 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;
         }
     }
 }
예제 #2
0
 /**
  * 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);
 }
예제 #3
0
 /**
  * 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;
 }
예제 #4
0
 /**
  * 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;
 }
예제 #5
0
 /**
  * Check whether a student should be auto-enrolled in more class.
  *
  * This function gets called when a student completes a class, and checks
  * whether that class was a prerequisite for other courses in a track,
  * and whether the student should now be enrolled in the other classes.
  *
  * Strategy:
  * - find tracks that the student is in, and get their curricula
  * - find the course that the class is associated with
  * - see if the course is a prerequisite in any of the curricula
  * - if yes, see if there are any autoenrollable classes in the tracks that
  *   the student can be autoenrolled in
  */
 public static function check_autoenrol_after_course_completion($enrolment)
 {
     global $CURMAN;
     $userid = $enrolment->userid;
     $courseid = $enrolment->cmclass->courseid;
     // this query will give us all the classes that had course $courseid as
     // a prerequisite, that are autoenrollable in tracks that user $userid
     // is in
     $sql = "SELECT trkcls.*, trk.curid, cls.courseid\n                  FROM {$CURMAN->db->prefix_table('crlm_course_prerequisite')} prereq\n            INNER JOIN {$CURMAN->db->prefix_table('crlm_curriculum_course')} curcrs\n                       ON curcrs.id = prereq.curriculumcourseid\n            INNER JOIN {$CURMAN->db->prefix_table('crlm_class')} cls\n                       ON curcrs.courseid = cls.courseid\n            INNER JOIN {$CURMAN->db->prefix_table('crlm_track_class')} trkcls\n                       ON trkcls.classid = cls.id AND trkcls.autoenrol = 1\n            INNER JOIN {$CURMAN->db->prefix_table('crlm_track')} trk\n                       ON trk.id = trkcls.trackid AND trk.curid = curcrs.curriculumid\n            INNER JOIN {$CURMAN->db->prefix_table('crlm_user_track')} usrtrk\n                       ON usrtrk.trackid = trk.id\n                 WHERE prereq.courseid = {$courseid} AND usrtrk.userid = {$userid}";
     $recs = $CURMAN->db->get_records_sql($sql);
     // now we just need to loop through them, and enrol them
     $recs = $recs ? $recs : array();
     foreach ($recs as $trkcls) {
         $curcrs = new curriculumcourse();
         $curcrs->courseid = $trkcls->courseid;
         $curcrs->curriculumid = $trkcls->curid;
         if ($curcrs->prerequisites_satisfied($userid)) {
             // no unsatisfied prereqs -- enrol the student
             $newenrolment = new student();
             $newenrolment->userid = $userid;
             $newenrolment->classid = $trkcls->classid;
             $newenrolment->enrolmenttime = time();
             $newenrolment->add(array('waitlist' => 1));
         }
     }
     return true;
 }
예제 #6
0
 /**
  * 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));
     }
 }