/**
  * Save a set of enrolments and LO grades to the database
  * @param array $enrolments Enrolment data to save
  * @param array $grades LO grade data to save
  */
 protected function save_enrolments($enrolments, $grades = array())
 {
     // Enrolments.
     foreach ($enrolments as $enrolment) {
         $student = new student($enrolment);
         $sink = $this->redirectMessages();
         $student->save();
     }
     // LO grades.
     foreach ($grades as $grade) {
         $studentgrade = new student_grade($grade);
         $studentgrade->save();
     }
 }
 function action_update()
 {
     global $CURMAN;
     $stuid = $this->required_param('association_id', PARAM_INT);
     $clsid = $this->required_param('id', PARAM_INT);
     $users = $this->required_param('users');
     $uid = key($users);
     $user = current($users);
     $sturecord = array();
     $sturecord['id'] = $stuid;
     $sturecord['classid'] = $clsid;
     $sturecord['userid'] = $uid;
     $startyear = $user['startyear'];
     $startmonth = $user['startmonth'];
     $startday = $user['startday'];
     $sturecord['enrolmenttime'] = mktime(0, 0, 0, $startmonth, $startday, $startyear);
     $endyear = $user['endyear'];
     $endmonth = $user['endmonth'];
     $endday = $user['endday'];
     $sturecord['completetime'] = mktime(0, 0, 0, $endmonth, $endday, $endyear);
     $sturecord['completestatusid'] = $user['completestatusid'];
     $sturecord['grade'] = $user['grade'];
     $sturecord['credits'] = $user['credits'];
     $sturecord['locked'] = !empty($user['locked']) ? 1 : 0;
     $stu = new student($sturecord);
     if ($stu->completestatusid == STUSTATUS_PASSED && $CURMAN->db->get_field(STUTABLE, 'completestatusid', 'id', $stuid) != STUSTATUS_PASSED) {
         $stu->complete();
     } else {
         if (($status = $stu->update()) !== true) {
             echo cm_error('Record not updated.  Reason: ' . $status->message);
         }
     }
     /// Check for grade records...
     $element = cm_get_param('element', array());
     $newelement = cm_get_param('newelement', array());
     $timegraded = cm_get_param('timegraded', array());
     $newtimegraded = cm_get_param('newtimegraded', array());
     $completionid = cm_get_param('completionid', array());
     $newcompletionid = cm_get_param('newcompletionid', array());
     $grade = cm_get_param('grade', array());
     $newgrade = cm_get_param('newgrade', array());
     $locked = cm_get_param('locked', array());
     $newlocked = cm_get_param('newlocked', array());
     foreach ($element as $gradeid => $element) {
         $graderec = array();
         $graderec['id'] = $gradeid;
         $graderec['userid'] = $uid;
         $graderec['classid'] = $clsid;
         $graderec['completionid'] = $element;
         $graderec['timegraded'] = mktime(0, 0, 0, $timegraded[$gradeid]['startmonth'], $timegraded[$gradeid]['startday'], $timegraded[$gradeid]['startyear']);
         $graderec['grade'] = $grade[$gradeid];
         $graderec['locked'] = isset($locked[$gradeid]) ? $locked[$gradeid] : '0';
         $sgrade = new student_grade($graderec);
         $sgrade->update();
     }
     foreach ($newelement as $elementid => $element) {
         $graderec = array();
         $graderec['userid'] = $uid;
         $graderec['classid'] = $clsid;
         $graderec['completionid'] = $element;
         $graderec['timegraded'] = mktime(0, 0, 0, $newtimegraded[$elementid]['startmonth'], $newtimegraded[$elementid]['startday'], $newtimegraded[$elementid]['startyear']);
         $graderec['grade'] = $newgrade[$elementid];
         $graderec['locked'] = isset($newlocked[$elementid]) ? $newlocked[$elementid] : '0';
         $sgrade = new student_grade($graderec);
         $sgrade->add();
     }
     $this->action_default();
 }
Beispiel #3
0
 /**
  * Test sync_completionelements method.
  *
  * @dataProvider dataprovider_sync_completionelements
  * @param array $gradeitem Array of parameters to create grade_item.
  * @param array $gradegrade Array of parameters to create grade_grade.
  * @param array $coursecompletion Array of parameters to create coursecompletion.
  * @param array $studentgrade Array of parameters to create student_grade.
  * @param int $timenow Current timestamp to enable testing with time.
  * @param array $expectedstudentgrade Array of parameters we expect to be set in the student_grade.
  */
 public function test_sync_completionelements($gradeitem, $gradegrade, $coursecompletion, $studentgrade, $timenow, $expectedstudentgrade)
 {
     global $DB;
     $sync = new \local_elisprogram\moodle\synchronize();
     // Test data setup.
     $crs = new \course(array('idnumber' => 'CRS1', 'name' => 'Course 1', 'syllabus' => ''));
     $crs->save();
     $cls = new \pmclass(array('courseid' => $crs->id, 'idnumber' => 'CLS1'));
     $cls->save();
     $usr = new \user(array('username' => 'test1', 'idnumber' => 'test2', 'firstname' => 'test', 'lastname' => 'user', 'email' => '*****@*****.**', 'country' => 'CA'));
     $usr->save();
     $musr = $this->getDataGenerator()->create_user();
     $gradeitem = new \grade_item($gradeitem, false);
     $gradeitem->insert();
     $gradegrade['itemid'] = $gradeitem->id;
     $gradegrade['userid'] = $musr->id;
     $gradegrade = new \grade_grade($gradegrade, false);
     $gradegrade->insert();
     $coursecompletion['courseid'] = $crs->id;
     $coursecompletion = new \coursecompletion($coursecompletion);
     $coursecompletion->save();
     if ($studentgrade !== false) {
         $studentgrade['classid'] = $cls->id;
         $studentgrade['userid'] = $usr->id;
         $studentgrade['completionid'] = $coursecompletion->id;
         $studentgrade = new \student_grade($studentgrade);
         $studentgrade->save();
         $studentgrade = new \student_grade($studentgrade->id);
         $studentgrade->load();
     }
     // Method parameter setup.
     $causer = (object) array('cmid' => $usr->id, 'pmclassid' => $cls->id);
     $gis = array($gradeitem->id => (object) array('id' => $gradeitem->id, 'grademax' => $gradeitem->grademax));
     $compelements = array($gradeitem->id => (object) array('id' => $coursecompletion->id, 'completion_grade' => $coursecompletion->completion_grade));
     $moodlegrades = array($gradeitem->id => $gradegrade);
     if ($studentgrade !== false) {
         $cmgrades = array($coursecompletion->id => $studentgrade->to_object());
     } else {
         $cmgrades = array();
     }
     $sync->sync_completionelements($causer, $gis, $compelements, $moodlegrades, $cmgrades, $timenow);
     $actualstudentgrade = false;
     if ($studentgrade !== false) {
         $actualstudentgrade = $DB->get_record(\student_grade::TABLE, array('id' => $studentgrade->id));
     } else {
         $actualstudentgrades = $DB->get_records(\student_grade::TABLE, array(), 'id DESC');
         if (!empty($actualstudentgrades)) {
             $actualstudentgrade = array_shift($actualstudentgrades);
         }
     }
     if ($actualstudentgrade !== false) {
         if ($expectedstudentgrade !== false) {
             $expectedstudentgrade['id'] = $actualstudentgrade->id;
             $expectedstudentgrade['classid'] = $cls->id;
             $expectedstudentgrade['userid'] = $usr->id;
             $expectedstudentgrade['completionid'] = $coursecompletion->id;
             // This is here for tests where we can't reliably predetermine timemodified (i.e. no-sync cases).
             if (!isset($expectedstudentgrade['timemodified'])) {
                 $expectedstudentgrade['timemodified'] = $actualstudentgrade->timemodified;
             }
             $expectedstudentgrade = (object) $expectedstudentgrade;
             $this->assertEquals($expectedstudentgrade, $actualstudentgrade);
         } else {
             $this->assertTrue(false, 'A student_grade was created when one was not expected.');
         }
     } else {
         // If $expectedstudentgrade is false we were expected no grade to be created. If not, we have a problem.
         if ($expectedstudentgrade !== false) {
             $this->assertTrue(false, 'No student_grade created when one was expected');
         } else {
             $this->assertTrue(true);
         }
     }
 }
Beispiel #4
0
 /**
  * Perform all necessary tasks to remove a student enrolment from the system.
  */
 function delete()
 {
     /// Remove any grade records for this enrolment.
     $result = student_grade::delete_for_user_and_class($this->userid, $this->classid);
     /// Unenrol them from the Moodle class.
     if ($moodlecourseid = moodle_get_course($this->classid)) {
         if (($mcourse = $this->_db->get_record('course', array('id' => $moodlecourseid))) && ($muser = $this->users->get_moodleuser())) {
             $sql = 'SELECT enrol.*
                       FROM {user_enrolments} enrolments
                       JOIN {enrol} enrol ON enrol.id = enrolments.enrolid
                      WHERE enrol.courseid = ?
                        AND enrolments.userid = ?';
             $enrolments = $this->_db->get_recordset_sql($sql, array($moodlecourseid, $muser->id));
             foreach ($enrolments as $enrolment) {
                 $plugin = enrol_get_plugin($enrolment->enrol);
                 $plugin->unenrol_user($enrolment, $muser->id);
             }
             unset($enrolments);
         }
     }
     parent::delete();
     if ($this->completestatusid == STUSTATUS_NOTCOMPLETE) {
         $pmclass = $this->pmclass;
         if (empty($pmclass->maxstudents) || $pmclass->maxstudents > static::count_enroled($pmclass->id)) {
             $wlst = waitlist::get_next($this->classid);
             if (!empty($wlst)) {
                 $wlst->enrol();
             }
         }
     }
     return $result;
 }
Beispiel #5
0
 public function delete()
 {
     global $CFG;
     $result = false;
     $muser = cm_get_moodleuserid($this->id);
     if (empty($muser) || !is_primary_admin($muser)) {
         $level = context_level_base::get_custom_context_level('user', 'block_curr_admin');
         $result = attendance::delete_for_user($this->id);
         $result = $result && curriculumstudent::delete_for_user($this->id);
         $result = $result && instructor::delete_for_user($this->id);
         $result = $result && student::delete_for_user($this->id);
         $result = $result && student_grade::delete_for_user($this->id);
         $result = $result && usertrack::delete_for_user($this->id);
         $result = $result && usercluster::delete_for_user($this->id);
         $result = $result && clusterassignment::delete_for_user($this->id);
         $result = $result && waitlist::delete_for_user($this->id);
         $result = $result && delete_context($level, $this->id);
         // Delete Moodle user.
         if ($muser = get_record('user', 'idnumber', $this->idnumber, 'mnethostid', $CFG->mnet_localhost_id, 'deleted', 0)) {
             $result = $result && delete_user($muser);
         }
         $result = $result && parent::delete();
     }
     return $result;
 }
Beispiel #6
0
 public function delete()
 {
     global $CFG;
     $muser = $this->get_moodleuser();
     if (empty($muser) || !is_primary_admin($muser->id)) {
         // delete associated data
         require_once elis::lib('data/data_filter.class.php');
         $filter = new field_filter('userid', $this->id);
         curriculumstudent::delete_records($filter, $this->_db);
         student::delete_records($filter, $this->_db);
         student_grade::delete_records($filter, $this->_db);
         waitlist::delete_records($filter, $this->_db);
         instructor::delete_records($filter, $this->_db);
         usertrack::delete_records($filter, $this->_db);
         clusterassignment::delete_records($filter, $this->_db);
         //delete association to Moodle user, if applicable
         require_once elispm::lib('data/usermoodle.class.php');
         $filter = new field_filter('cuserid', $this->id);
         usermoodle::delete_records($filter, $this->_db);
         // Delete Moodle user.
         if (!empty($muser)) {
             delete_user($muser);
         }
         parent::delete();
         $context = \local_elisprogram\context\user::instance($this->id);
         $context->delete();
     }
 }
 /**
  * Perform all necessary tasks to remove a student enrolment from the system.
  */
 function delete()
 {
     /// Remove any grade records for this enrolment.
     $result = student_grade::delete_for_user_and_class($this->userid, $this->classid);
     /// Unenrol them from the Moodle class.
     if (!empty($this->classid) && !empty($this->userid) && ($moodlecourseid = get_field('crlm_class_moodle', 'moodlecourseid', 'classid', $this->classid)) && ($muserid = cm_get_moodleuserid($this->userid))) {
         $context = get_context_instance(CONTEXT_COURSE, $moodlecourseid);
         if ($context && $context->id) {
             role_unassign(0, $muserid, 0, $context->id);
         }
     }
     $result = $result && $this->data_delete_record();
     if ($this->completestatusid == STUSTATUS_NOTCOMPLETE) {
         $cmclass = new cmclass($this->classid);
         if (empty($cmclass->maxstudents) || $cmclass->maxstudents > student::count_enroled($cmclass->id)) {
             $wlst = waitlist::get_next($this->classid);
             if (!empty($wlst)) {
                 $wlst->enrol();
             }
         }
     }
     return $result;
 }
 /**
  * Validate that LO grades are locked when they are updated and grade
  * is sufficient when run for a specific user
  */
 public function test_methodlockslearningobjectivegradesduringupdateforspecificuserid()
 {
     global $DB;
     $this->load_csv_data();
     // Create enrolment.
     $this->make_course_enrollable();
     enrol_try_internal_enrol(2, 100, 1);
     enrol_try_internal_enrol(2, 101, 1);
     // Create LO and Moodle grade.
     $itemid = $this->create_grade_item();
     $this->create_grade_grade($itemid, 100, 75, 100, 1);
     $this->create_grade_grade($itemid, 101, 75, 100, 1);
     $this->create_course_completion('manualitem', 50);
     // Enrol in PM class.
     $studentgrade = new \student_grade(array('userid' => 103, 'classid' => 100, 'completionid' => 1, 'grade' => 75, 'locked' => 0, 'timegraded' => 1));
     $studentgrade->save();
     $studentgrade = new \student_grade(array('userid' => 104, 'classid' => 100, 'completionid' => 1, 'grade' => 75, 'locked' => 0, 'timegraded' => 1));
     $studentgrade->save();
     // Validate setup.
     $this->assert_num_student_grades(2);
     $count = $DB->count_records(\student_grade::TABLE, array('locked' => 1));
     $this->assertEquals(0, $count);
     $this->assert_student_grade_exists(100, 103, 1, null, 0);
     // Update Moodle info.
     $DB->execute("UPDATE {grade_grades} SET finalgrade = 80, timemodified = 2");
     // Run and validate.
     $sync = new \local_elisprogram\moodle\synchronize();
     $sync->synchronize_moodle_class_grades(100);
     $this->assert_num_student_grades(2);
     $count = $DB->count_records(\student_grade::TABLE, array('locked' => 1));
     $this->assertEquals(1, $count);
     $this->assert_student_grade_exists(100, 103, 1, null, 1);
 }
Beispiel #9
0
 /**
  * Test that a record can be modified.
  */
 public function teststudentgradecanupdaterecord()
 {
     $this->load_csv_data();
     // Read a record.
     $src = new student_grade(1, null, array(), false, array());
     $src->grade = 70;
     $src->save();
     // Read it back.
     $retr = new student_grade(3, null, array(), false, array());
     foreach ($src as $key => $value) {
         if (strpos($key, elis_data_object::FIELD_PREFIX) !== false) {
             $key = substr($key, strlen(elis_data_object::FIELD_PREFIX));
             $this->assertEquals($src->{$key}, $retr->{$key});
         }
     }
 }
Beispiel #10
0
 function delete()
 {
     $status = true;
     if (!empty($this->id)) {
         instructor::delete_for_class($this->id);
         student::delete_for_class($this->id);
         trackassignmentclass::delete_for_class($this->id);
         classmoodlecourse::delete_for_class($this->id);
         student_grade::delete_for_class($this->id);
         attendance::delete_for_class($this->id);
         taginstance::delete_for_class($this->id);
         waitlist::delete_for_class($this->id);
         classmoodlecourse::delete_for_class($this->id);
         $level = context_level_base::get_custom_context_level('class', 'block_curr_admin');
         $result = delete_context($level, $this->id);
         $status = $this->data_delete_record();
     }
     return $status;
 }
 /**
  * Test enrolment functions using an invalid class ID.
  */
 public function test_enrolment_with_invalid_classid()
 {
     global $CFG, $DB;
     require_once $CFG->dirroot . '/local/elisprogram/lib/setup.php';
     require_once elispm::lib('lib.php');
     $this->load_csv_data();
     $enrolment = new stdClass();
     $enrolment->classid = 1000;
     // Invalid class ID.
     $enrolment->userid = 103;
     $enrolment->enrolmenttime = time();
     $enrolment->completetime = 0;
     $enrolment->endtime = 0;
     $enrolment->completestatusid = 0;
     $enrolment->grade = 0;
     $enrolment->credits = 0.0;
     $enrolment->locked = 0;
     // Directly insert the record to bypass 'student' class validation on the classid.
     $this->assertGreaterThan(0, $DB->insert_record(student::TABLE, $enrolment));
     // Attempt to update status before the required learning objective is satisfied.
     // ELIS-4955 -- This should ignore the bad data and proceed without error.
     pm_update_enrolment_status();
     // Validate that the enrolment is still in progress.
     $sturecord = new student(100);
     $this->assertEquals(STUSTATUS_NOTCOMPLETE, $sturecord->completestatusid);
     $this->assertEquals(0, $sturecord->locked);
     // Satisfy the required learning objective.
     $graderecord = new student_grade(1);
     $graderecord->grade = 80;
     $graderecord->save();
     // Attempt to update status now that the required learning objective is satisfied.
     pm_update_enrolment_status();
     // Validate that the enrolment is passed.
     $sturecord = new student(100);
     $this->assertEquals(STUSTATUS_PASSED, $sturecord->completestatusid);
     $this->assertEquals(1, $sturecord->locked);
 }
Beispiel #12
0
 /**
  * Perform an update for a single user/class pair.
  *
  * @param int $userid The user ID we're updating.
  * @param int $classid The class ID we're updating information for.
  * @param array $enroldata The updated enrolment data.
  * @param array $learningobjectives The updated learning objective data.
  */
 protected function do_update($userid, $classid, array $enroldata, array $learningobjectives)
 {
     global $DB;
     if (student::can_manage_assoc($userid, $classid) !== true) {
         throw new Exception('Unauthorized');
     }
     if (!isset($enroldata['id'])) {
         $associationid = $DB->get_field(student::TABLE, 'id', array('classid' => $classid, 'userid' => $userid));
         if (empty($associationid)) {
             return false;
         } else {
             $enroldata['id'] = $associationid;
         }
     }
     $enroldata['userid'] = $userid;
     $stu = new student($enroldata);
     if ($stu->completestatusid == STUSTATUS_PASSED && $DB->get_field(student::TABLE, 'completestatusid', array('id' => $stu->id)) != STUSTATUS_PASSED) {
         $stu->complete();
     } else {
         $status = $stu->save();
     }
     foreach ($learningobjectives as $id => $data) {
         $graderec = array('userid' => $userid, 'classid' => $classid, 'completionid' => $id);
         $existingrec = $DB->get_record(student_grade::TABLE, $graderec);
         if (!empty($existingrec)) {
             $graderec = (array) $existingrec;
         }
         $graderec['timegraded'] = $data['timegraded'];
         $graderec['grade'] = $data['grade'];
         $graderec['locked'] = $data['locked'];
         $sgrade = new student_grade($graderec);
         $sgrade->save();
     }
 }
 /**
  * Validate that the pm_update_enrolment_status method respects its userid parameter, i.e. it can run only for a specific user.
  * NOTE: this unit test does not test all cases because that should be specifically tested for $pmclass->update_enrolment_status
  *
  * @param array $enrolments A list of class enrolment records we are processing
  * @param array $classgraded A list of learning objective grades we are processing
  * @dataProvider dataprovider_updatedelegation
  */
 public function test_pmupdateenrolmentstatusrespectsuseridparameter($enrolments, $classgraded)
 {
     global $DB;
     // Necessary data.
     $this->load_csv_data();
     foreach ($enrolments as $key => $enrolment) {
         // Create student enrolment.
         $record = new student($enrolment);
         $record->save();
     }
     foreach ($classgraded as $lograde) {
         // Create learning objective grade.
         $record = new student_grade($lograde);
         $record->save();
     }
     // Pass the appropriate student.
     pm_update_enrolment_status(2);
     // We should have one passed student in the PM class instance, and that student should be the second user.
     $enrolments = $DB->get_records(student::TABLE, array('completestatusid' => STUSTATUS_PASSED));
     $this->assertEquals(1, count($enrolments));
     $enrolment = reset($enrolments);
     $this->assertEquals(100, $enrolment->classid);
     $this->assertEquals(2, $enrolment->userid);
     $this->assertEquals(100, $enrolment->grade);
 }
Beispiel #14
0
 function delete()
 {
     if (!empty($this->id)) {
         //clean make the delete cascade into association records
         $filter = new field_filter('classid', $this->id);
         instructor::delete_records($filter, $this->_db);
         student::delete_records($filter, $this->_db);
         trackassignment::delete_records($filter, $this->_db);
         classmoodlecourse::delete_records($filter, $this->_db);
         student_grade::delete_records($filter, $this->_db);
         waitlist::delete_records($filter, $this->_db);
         parent::delete();
         $context = \local_elisprogram\context\pmclass::instance($this->id);
         $context->delete();
     }
 }