/** * Triggered when 'course_completed' event is triggered. * * @param \core\event\course_completed $event */ public static function course_criteria_review(\core\event\course_completed $event) { global $DB, $CFG; if (!empty($CFG->enablebadges)) { require_once $CFG->dirroot . '/lib/badgeslib.php'; $eventdata = $event->get_record_snapshot('course_completions', $event->objectid); $userid = $event->relateduserid; $courseid = $event->courseid; // Need to take into account that course can be a part of course_completion and courseset_completion criteria. if ($rs = $DB->get_records('badge_criteria_param', array('name' => 'course_' . $courseid, 'value' => $courseid))) { foreach ($rs as $r) { $crit = $DB->get_record('badge_criteria', array('id' => $r->critid), 'badgeid, criteriatype', MUST_EXIST); $badge = new badge($crit->badgeid); if (!$badge->is_active() || $badge->is_issued($userid)) { continue; } if ($badge->criteria[$crit->criteriatype]->review($userid)) { $badge->criteria[$crit->criteriatype]->mark_complete($userid); if ($badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->review($userid)) { $badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->mark_complete($userid); $badge->issue($userid); } } } } } }
public function test_observe_course_completed() { $this->resetAfterTest(true); $dg = $this->getDataGenerator(); $lpg = $dg->get_plugin_generator('core_competency'); // Set-up users, framework, competencies and course competencies. $course = $dg->create_course(); $coursectx = context_course::instance($course->id); $u1 = $dg->create_user(); $f1 = $lpg->create_framework(); $c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); $c2 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); $c3 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); $c4 = $lpg->create_competency(array('competencyframeworkid' => $f1->get_id())); $cc1 = $lpg->create_course_competency(array('competencyid' => $c1->get_id(), 'courseid' => $course->id, 'ruleoutcome' => \core_competency\course_competency::OUTCOME_NONE)); $cc2 = $lpg->create_course_competency(array('competencyid' => $c2->get_id(), 'courseid' => $course->id, 'ruleoutcome' => \core_competency\course_competency::OUTCOME_EVIDENCE)); $cc3 = $lpg->create_course_competency(array('competencyid' => $c3->get_id(), 'courseid' => $course->id, 'ruleoutcome' => \core_competency\course_competency::OUTCOME_RECOMMEND)); $cc4 = $lpg->create_course_competency(array('competencyid' => $c4->get_id(), 'courseid' => $course->id, 'ruleoutcome' => \core_competency\course_competency::OUTCOME_COMPLETE)); $event = \core\event\course_completed::create(array('objectid' => 1, 'relateduserid' => $u1->id, 'context' => $coursectx, 'courseid' => $course->id, 'other' => array('relateduserid' => $u1->id))); $this->assertEquals(0, \core_competency\user_competency::count_records()); $this->assertEquals(0, \core_competency\evidence::count_records()); // Let's go! api::observe_course_completed($event); $this->assertEquals(3, \core_competency\user_competency::count_records()); $this->assertEquals(3, \core_competency\evidence::count_records()); // Outcome NONE did nothing. $this->assertFalse(\core_competency\user_competency::record_exists_select('userid = :uid AND competencyid = :cid', array('uid' => $u1->id, 'cid' => $c1->get_id()))); // Outcome evidence. $uc2 = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c2->get_id())); $ev2 = \core_competency\evidence::get_record(array('usercompetencyid' => $uc2->get_id())); $this->assertEquals(null, $uc2->get_grade()); $this->assertEquals(null, $uc2->get_proficiency()); $this->assertEquals(\core_competency\user_competency::STATUS_IDLE, $uc2->get_status()); $this->assertEquals('evidence_coursecompleted', $ev2->get_descidentifier()); $this->assertEquals('core_competency', $ev2->get_desccomponent()); $this->assertEquals($course->shortname, $ev2->get_desca()); $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev2->get_url()); $this->assertEquals(null, $ev2->get_grade()); $this->assertEquals($coursectx->id, $ev2->get_contextid()); $this->assertEquals(\core_competency\evidence::ACTION_LOG, $ev2->get_action()); $this->assertEquals(null, $ev2->get_actionuserid()); // Outcome recommend. $uc3 = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c3->get_id())); $ev3 = \core_competency\evidence::get_record(array('usercompetencyid' => $uc3->get_id())); $this->assertEquals(null, $uc3->get_grade()); $this->assertEquals(null, $uc3->get_proficiency()); $this->assertEquals(\core_competency\user_competency::STATUS_WAITING_FOR_REVIEW, $uc3->get_status()); $this->assertEquals('evidence_coursecompleted', $ev3->get_descidentifier()); $this->assertEquals('core_competency', $ev3->get_desccomponent()); $this->assertEquals($course->shortname, $ev3->get_desca()); $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev3->get_url()); $this->assertEquals(null, $ev3->get_grade()); $this->assertEquals($coursectx->id, $ev3->get_contextid()); $this->assertEquals(\core_competency\evidence::ACTION_LOG, $ev3->get_action()); $this->assertEquals(null, $ev3->get_actionuserid()); // Outcome complete. $uc4 = \core_competency\user_competency::get_record(array('userid' => $u1->id, 'competencyid' => $c4->get_id())); $ev4 = \core_competency\evidence::get_record(array('usercompetencyid' => $uc4->get_id())); $this->assertEquals(3, $uc4->get_grade()); $this->assertEquals(1, $uc4->get_proficiency()); $this->assertEquals(\core_competency\user_competency::STATUS_IDLE, $uc4->get_status()); $this->assertEquals('evidence_coursecompleted', $ev4->get_descidentifier()); $this->assertEquals('core_competency', $ev4->get_desccomponent()); $this->assertEquals($course->shortname, $ev4->get_desca()); $this->assertStringEndsWith('/report/completion/index.php?course=' . $course->id, $ev4->get_url()); $this->assertEquals(3, $ev4->get_grade()); $this->assertEquals($coursectx->id, $ev4->get_contextid()); $this->assertEquals(\core_competency\evidence::ACTION_COMPLETE, $ev4->get_action()); $this->assertEquals(null, $ev4->get_actionuserid()); }
/** * Observe when a course is marked as completed. * * Note that the user being logged in while this happens may be anyone. * Do not rely on capability checks here! * * @param \core\event\course_completed $event * @return void */ public static function observe_course_completed(\core\event\course_completed $event) { if (!static::is_enabled()) { return; } $sql = 'courseid = :courseid AND ruleoutcome != :nooutcome'; $params = array('courseid' => $event->courseid, 'nooutcome' => course_competency::OUTCOME_NONE); $coursecompetencies = course_competency::get_records_select($sql, $params); $course = get_course($event->courseid); $courseshortname = format_string($course->shortname, null, array('context' => $event->contextid)); foreach ($coursecompetencies as $coursecompetency) { $outcome = $coursecompetency->get_ruleoutcome(); $action = null; $recommend = false; $strdesc = 'evidence_coursecompleted'; if ($outcome == course_competency::OUTCOME_EVIDENCE) { $action = evidence::ACTION_LOG; } else { if ($outcome == course_competency::OUTCOME_RECOMMEND) { $action = evidence::ACTION_LOG; $recommend = true; } else { if ($outcome == course_competency::OUTCOME_COMPLETE) { $action = evidence::ACTION_COMPLETE; } else { throw new moodle_exception('Unexpected rule outcome: ' + $outcome); } } } static::add_evidence($event->relateduserid, $coursecompetency->get_competencyid(), $event->contextid, $action, $strdesc, 'core_competency', $courseshortname, $recommend, $event->get_url()); } }
/** * Mark this user complete in this course * * This generally happens when the required completion criteria * in the course are complete. * * @param integer $timecomplete Time completed (optional) * @return void */ public function mark_complete($timecomplete = null) { global $USER; // Never change a completion time. if ($this->timecompleted) { return; } // Use current time if nothing supplied. if (!$timecomplete) { $timecomplete = time(); } // Set time complete. $this->timecompleted = $timecomplete; // Save record. if ($result = $this->_save()) { $data = $this->get_record_data(); $event = \core\event\course_completed::create(array('objectid' => $data->id, 'userid' => $USER->id, 'context' => context_course::instance($data->course), 'courseid' => $data->course, 'other' => array('relateduserid' => $data->userid))); $event->add_record_snapshot('course_completions', $data); $event->trigger(); } return $result; }
/** * Mark this user complete in this course * * This generally happens when the required completion criteria * in the course are complete. * * @param integer $timecomplete Time completed (optional) * @return void */ public function mark_complete($timecomplete = null) { global $USER; // Never change a completion time. if ($this->timecompleted) { return; } // Use current time if nothing supplied. if (!$timecomplete) { $timecomplete = time(); } // Set time complete. $this->timecompleted = $timecomplete; // Save record. if ($result = $this->_save()) { $data = $this->get_record_data(); \core\event\course_completed::create_from_completion($data)->trigger(); } return $result; }