138 lines
		
	
	
		
			No EOL
		
	
	
		
			5.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			No EOL
		
	
	
		
			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),
 | 
						|
        ];
 | 
						|
    }
 | 
						|
 | 
						|
} |