moodle_local_treestudyplan/classes/completionscanner.php

138 lines
5.4 KiB
PHP

<?php
namespace local_treestudyplan;
require_once($CFG->libdir.'/externallib.php');
use \grade_item;
class completionscanner
{
private static $mod_supported = [];
private static $course_students = [];
private $scanner = null;
private $course = null;
private $cm = null;
private $gi = null;
private $pending_cache = [];
public static function supported($mod){
if(!array_key_exists($mod,self::$mod_supported)){
self::$mod_supported[$mod] = class_exists("\local_treestudyplan\\local\\ungradedscanners\\{$mod}_scanner");
}
return self::$mod_supported[$mod];
}
public static function get_course_students($courseid){
global $CFG;
if(!array_key_exists($courseid,self::$course_students)){
$students = [];
$context = \context_course::instance($courseid);
foreach (explode(',', $CFG->gradebookroles) as $roleid) {
$roleid = trim($roleid);
$students = array_keys(get_role_users($roleid, $context, false, 'u.id', 'u.id ASC'));
}
self::$course_students[$courseid] = $students;
}
return self::$course_students[$courseid];
}
public function __construct(\completion_criteria $crit,$course){
$this->courseid = $course->id;
$this->course = $course;
$this->modinfo = get_fast_modinfo($course);
$this->crit = $crit;
$this->completioninfo = new \completion_info($course);
// Find a related scanner if the type is an activity type
if($crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY){
// First find the course module
$this->cm = $this->modinfo->get_cm($crit->moduleinstance);
$gi = grade_item::fetch(['itemtype' => 'mod', 'itemmodule' => $this->cm->modname, 'iteminstance' => $this->cm->instance, 'courseid' => $this->courseid]);
if($gi !== false)
{
// Grade none items should not be relevant
// Note that the grade status is probably only relevant if the item has not yet received a completion, but has been submitted
if(($gi->gradetype == GRADE_TYPE_VALUE || $gi->gradetype == GRADE_TYPE_SCALE))
{
// If it's a relevant grade type, initialize a scanner if possible
$this->gi = $gi;
if(self::supported($gi->itemmodule)) {
$scannerclass = "\local_treestudyplan\\local\ungradedscanners\\{$gi->itemmodule}_scanner";
$this->scanner = new $scannerclass($gi);
}
}
}
}
}
public function pending($userid){
if(!array_key_exists($userid, $this->pending_cache)){
if($this->scanner === null) {
$this->pending_cache[$userid] = false;
}
else {
$this->pending_cache[$userid] = $this->scanner->has_ungraded_submission($userid);;
}
}
return $this->pending_cache[$userid];
}
public static function structure($value=VALUE_OPTIONAL){
return new \external_single_structure([
"ungraded" => new \external_value(PARAM_INT, 'number of ungraded submissions'),
"completed" => new \external_value(PARAM_INT, 'number of completed students'),
"completed_pass" => new \external_value(PARAM_INT, 'number of completed-pass students'),
"completed_fail" => new \external_value(PARAM_INT, 'number of completed-fail students'),
"students" => new \external_value(PARAM_INT, 'number of students that should submit'),
],"details about gradable submissions",$value);
}
public function model(){
// get completion info
$students = self::get_course_students($this->courseid);
$completed = 0;
$ungraded = 0;
$completed_pass = 0;
$completed_fail = 0;
foreach($students as $userid){
if($this->pending($userid)){
// First check if the completion needs grading
$ungraded++;
} else {
$completion = $this->completioninfo->get_user_completion($userid,$this->crit);
if($this->crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY){
// If it's an activity completion, add all the relevant activities as sub-items
$completion_status = $this->completioninfo->get_grade_completion($this->cm,$userid);
if($completion_status == COMPLETION_COMPLETE_PASS){
$completed_pass++;
} else if ($completion_status == COMPLETION_COMPLETE_FAIL){
$completed_fail++;
} else if ($completion_status == COMPLETION_COMPLETE){
$completed++;
}
}
else{
if($completion->is_complete()){
$completed++;
}
}
}
}
return [
'ungraded' => $ungraded,
'completed' => $completed,
'completed_pass' => $completed_pass,
'completed_fail' => $completed_fail,
'students' => count($students),
];
}
}