예제 #1
0
파일: lib.php 프로젝트: jamesmcq/elis
/**
 * Get all of the data from Moodle and update the curriculum system.
 * This should do the following:
 *      - Get all Moodle courses connected with classes.
 *      - Get all users in each Moodle course.
 *      - Get grade records from the class's course and completion elements.
 *      - For each user:
 *          - Check if they have an enrolment record in CM, and add if not.
 *          - Update grade information in the enrollment and grade tables in CM.
 *
 * @param int $muserid  optional user to update, default(0) updates all users
 */
function pm_update_student_progress($muserid = 0)
{
    global $CFG;
    require_once $CFG->dirroot . '/grade/lib.php';
    require_once $CFG->dirroot . '/grade/querylib.php';
    /// Get all grades in all relevant courses for all relevant users.
    require_once elispm::lib('data/classmoodlecourse.class.php');
    require_once elispm::lib('data/student.class.php');
    require_once elispm::lib('data/pmclass.class.php');
    require_once elispm::lib('data/course.class.php');
    /// Start with the Moodle classes...
    if ($muserid == 0) {
        if (in_cron()) {
            mtrace("Synchronizing Moodle class grades<br />\n");
        }
    }
    $sync = new \local_elisprogram\moodle\synchronize();
    $sync->synchronize_moodle_class_grades($muserid);
    flush();
    // sleep(1);
    /// Now we need to check all of the student and grade records again, since data may have come from sources
    /// other than Moodle.
    if ($muserid == 0) {
        //running for all users
        if (in_cron()) {
            mtrace("Updating all class grade completions.<br />\n");
        }
        pm_update_enrolment_status();
    } else {
        //attempting to run for a particular user
        $pmuserid = pm_get_crlmuserid($muserid);
        if ($pmuserid != false) {
            //user has a matching PM user
            pm_update_enrolment_status($pmuserid);
        }
    }
    return true;
}
예제 #2
0
 /**
  * Function to handle class not completed events.
  *
  * @param   student  $student  The class enrolment / student object who is "not completed"
  * @uses    $CFG
  * @uses    $DB
  * @return  boolean            TRUE is successful, otherwise FALSE
  */
 public static function class_notcompleted_handler($student)
 {
     global $CFG, $DB;
     require_once elispm::lib('notifications.php');
     /// Does the user receive a notification?
     $sendtouser = elis::$config->local_elisprogram->notify_classnotcompleted_user;
     $sendtorole = elis::$config->local_elisprogram->notify_classnotcompleted_role;
     $sendtosupervisor = elis::$config->local_elisprogram->notify_classnotcompleted_supervisor;
     /// If nobody receives a notification, we're done.
     if (!$sendtouser && !$sendtorole && !$sendtosupervisor) {
         return true;
     }
     if (!empty($student->moodlecourseid)) {
         if (!($context = context_course::instance($student->moodlecourseid))) {
             if (in_cron()) {
                 mtrace(get_string('invalidcontext'));
             } else {
                 debugging(get_string('invalidcontext'));
             }
             return true;
         }
     } else {
         $context = context_system::instance();
     }
     $message = new notification();
     /// Set up the text of the message
     $text = empty(elis::$config->local_elisprogram->notify_classnotcompleted_message) ? get_string('notifyclassnotcompletedmessagedef', self::LANG_FILE) : elis::$config->local_elisprogram->notify_classnotcompleted_message;
     $search = array('%%userenrolname%%', '%%classname%%', '%%coursename%%');
     $user = new user($student->userid);
     if (!$user) {
         if (in_cron()) {
             mtrace(get_string('nouser', 'local_elisprogram'));
         } else {
             debugging(get_string('nouser', 'local_elisprogram'));
         }
         return true;
     }
     $user->load();
     // Get course info
     $pmcourse = $DB->get_record(course::TABLE, array('id' => $student->courseid));
     $pmclass = $DB->get_record(pmclass::TABLE, array('id' => $student->classid));
     $replace = array($user->moodle_fullname(), $pmclass->idnumber, $pmcourse->name);
     $text = str_replace($search, $replace, $text);
     $eventlog = new Object();
     $eventlog->event = 'class_notcompleted';
     $eventlog->instance = $student->classid;
     $eventlog->fromuserid = $user->id;
     if ($sendtouser) {
         $message->send_notification($text, $user, null, $eventlog);
     }
     $users = array();
     if ($sendtorole) {
         /// Get all users with the notify_classnotcomplete capability.
         if ($roleusers = get_users_by_capability($context, 'local/elisprogram:notify_classnotcomplete')) {
             $users = $users + $roleusers;
         }
     }
     if ($sendtosupervisor) {
         /// Get parent-context users.
         if ($supervisors = pm_get_users_by_capability('user', $user->id, 'local/elisprogram:notify_classnotcomplete')) {
             $users = $users + $supervisors;
         }
     }
     // Send notifications to any users who need to receive them.
     foreach ($users as $touser) {
         $message->send_notification($text, $touser, $user, $eventlog);
     }
     return true;
 }
예제 #3
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));
     }
 }
예제 #4
0
 public function send_notification($message = '', $userto = null, $userfrom = null, $logevent = false)
 {
     global $DB, $USER;
     /// Handle parameters:
     if (!empty($userto)) {
         $this->userto = $userto;
     } else {
         if (empty($this->userto)) {
             if (in_cron()) {
                 mtrace(get_string('message_nodestinationuser', 'local_elisprogram'));
             } else {
                 print_error('message_nodestinationuser', 'local_elisprogram');
             }
             return false;
         }
     }
     if (!empty($userfrom)) {
         $this->userfrom = $userfrom;
     } else {
         if (empty($this->userfrom)) {
             $this->userfrom = $USER;
         }
     }
     if ($message != '') {
         $this->fullmessage = $message;
     }
     /// Check for the user object type. If a PM User was sent in, need to get the Moodle object.
     //todo: convert this code to use "is_a"
     $topmuserid = false;
     if (get_class($this->userto) == 'user') {
         $topmuserid = $this->userto->id;
         if (!($this->userto = $this->userto->get_moodleuser())) {
             // TODO log here.
             return false;
         }
     }
     if (empty($this->userto)) {
         // TODO log here.
         return false;
     }
     if (get_class($this->userfrom) == 'user') {
         //            if (!($this->userfrom = cm_get_moodleuser($this->userfrom->id))) {
         if (!($this->userfrom = $this->userfrom->get_moodleuser())) {
             if (in_cron()) {
                 mtrace(get_string('nomoodleuser', 'local_elisprogram'));
             } else {
                 debugging(get_string('nomoodleuser', 'local_elisprogram'));
             }
         }
     }
     if (empty($this->userfrom)) {
         // ELIS-3632: prevent DB errors downstream
         $this->userfrom = $USER;
         // TBD
     }
     /// Handle unset variables:
     $this->name = $this->name == '' ? $this->defname : $this->name;
     $this->subject = $this->subject == '' ? $this->defsubject : $this->subject;
     //this call performs the core work involved in notifying users
     pm_notify_send_handler(clone $this);
     /// Insert a notification log if we have data for it.
     if ($logevent !== false) {
         if (!empty($logevent->event)) {
             $newlog = new Object();
             $newlog->event = $logevent->event;
             if (isset($logevent->userid)) {
                 $newlog->userid = $logevent->userid;
             } else {
                 if ($topmuserid === false) {
                     $newlog->userid = pm_get_crlmuserid($this->userto->id);
                 } else {
                     $newlog->userid = $topmuserid;
                 }
             }
             //if the log entry specifies which user triggered the event,
             //store that info
             //NOTE: Do not use $userfrom because that is the message sender
             //but not necessarily the user whose criteria triggered the event
             if (isset($logevent->fromuserid)) {
                 $newlog->fromuserid = $logevent->fromuserid;
             }
             if (isset($logevent->instance)) {
                 $newlog->instance = $logevent->instance;
             }
             if (isset($logevent->data)) {
                 $newlog->data = $logevent->data;
             }
             if (isset($logevent->timecreated)) {
                 $newlog->timecreated = $logevent->timecreated;
             } else {
                 $newlog->timecreated = time();
             }
             $DB->insert_record('local_elisprogram_notifylog', $newlog);
         }
     }
 }
예제 #5
0
 /**
  * Function to handle course recurrence events.
  *
  * @param   user      $user  CM user object representing the user in the course
  *
  * @return  boolean          TRUE is successful, otherwise FALSE
  */
 public static function course_recurrence_handler($user)
 {
     global $DB;
     require_once elispm::lib('notifications.php');
     /// Does the user receive a notification?
     $sendtouser = elis::$config->local_elisprogram->notify_courserecurrence_user;
     $sendtorole = elis::$config->local_elisprogram->notify_courserecurrence_role;
     $sendtosupervisor = elis::$config->local_elisprogram->notify_courserecurrence_supervisor;
     /// If nobody receives a notification, we're done.
     if (!$sendtouser && !$sendtorole && !$sendtosupervisor) {
         return true;
     }
     $context = context_system::instance();
     /// Make sure this is a valid user.
     $enroluser = new user($user->userid);
     if (!$enroluser) {
         if (in_cron()) {
             mtrace(get_string('nouser', 'local_elisprogram'));
         } else {
             print_error('nouser', 'local_elisprogram');
         }
         return true;
     }
     // Due to lazy loading, we need to pre-load this object
     $enroluser->load();
     if (empty($enroluser->id)) {
         if (in_cron()) {
             mtrace(get_string('nouser', 'local_elisprogram'));
         } else {
             print_error('nouser', 'local_elisprogram');
         }
         return true;
     }
     /// Set up the text of the message
     $message = new notification();
     $text = empty(elis::$config->local_elisprogram->notify_courserecurrence_message) ? get_string('notifycourserecurrencemessagedef', 'local_elisprogram') : elis::$config->local_elisprogram->notify_courserecurrence_message;
     $search = array('%%userenrolname%%', '%%coursename%%');
     $replace = array($enroluser->moodle_fullname(), $user->coursename);
     $text = str_replace($search, $replace, $text);
     $eventlog = new Object();
     $eventlog->event = 'course_recurrence';
     $eventlog->instance = $user->enrolmentid;
     $eventlog->fromuserid = $enroluser->id;
     if ($sendtouser) {
         $message->send_notification($text, $enroluser, null, $eventlog);
     }
     $users = array();
     if ($sendtorole) {
         /// Get all users with the notify_courserecurrence capability.
         if ($roleusers = get_users_by_capability($context, 'local/elisprogram:notify_courserecurrence')) {
             $users = $users + $roleusers;
         }
     }
     if ($sendtosupervisor) {
         /// Get parent-context users.
         if ($supervisors = pm_get_users_by_capability('user', $enroluser->id, 'local/elisprogram:notify_courserecurrence')) {
             $users = $users + $supervisors;
         }
     }
     foreach ($users as $u) {
         $message->send_notification($text, $u, $enroluser, $eventlog);
     }
     return true;
 }