Added service functions for grade/badge/completion progress
This commit is contained in:
parent
780765ff79
commit
7b95d06c4f
6 changed files with 180 additions and 11 deletions
|
@ -127,4 +127,15 @@ class badgeinfo {
|
||||||
return $badge;
|
return $badge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function count_issued(array $student_ids){
|
||||||
|
$issuecount = 0;
|
||||||
|
|
||||||
|
foreach($student_ids as $uid){
|
||||||
|
if($this->badge->is_issued($userid)){
|
||||||
|
$issuecount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $issuecount;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -39,8 +39,8 @@ class completionscanner
|
||||||
return self::$course_students[$courseid];
|
return self::$course_students[$courseid];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct($course,\completion_criteria $crit){
|
public function __construct(\completion_criteria $crit){
|
||||||
$this->course = $course;
|
$this->course = $crit->course;
|
||||||
$this->crit = $crit;
|
$this->crit = $crit;
|
||||||
|
|
||||||
// Find a related scanner if the type is an activity type
|
// Find a related scanner if the type is an activity type
|
||||||
|
|
|
@ -53,6 +53,7 @@ class corecompletioninfo {
|
||||||
|
|
||||||
public static function completion_item_editor_structure($value=VALUE_REQUIRED){
|
public static function completion_item_editor_structure($value=VALUE_REQUIRED){
|
||||||
return new \external_single_structure([
|
return new \external_single_structure([
|
||||||
|
"id" => new \external_value(PARAM_INT,'criteria id',VALUE_OPTIONAL),
|
||||||
"title" => new \external_value(PARAM_TEXT,'name of subitem',VALUE_OPTIONAL),
|
"title" => new \external_value(PARAM_TEXT,'name of subitem',VALUE_OPTIONAL),
|
||||||
"link" => new \external_value(PARAM_TEXT, 'optional link to more details',VALUE_OPTIONAL),
|
"link" => new \external_value(PARAM_TEXT, 'optional link to more details',VALUE_OPTIONAL),
|
||||||
"details" => new \external_single_structure([
|
"details" => new \external_single_structure([
|
||||||
|
@ -85,7 +86,7 @@ class corecompletioninfo {
|
||||||
|
|
||||||
public static function completion_item_user_structure($value=VALUE_REQUIRED){
|
public static function completion_item_user_structure($value=VALUE_REQUIRED){
|
||||||
return new \external_single_structure([
|
return new \external_single_structure([
|
||||||
"id" => new \external_value(PARAM_INT,'id of subitem',VALUE_OPTIONAL),
|
"id" => new \external_value(PARAM_INT,'id of completion',VALUE_OPTIONAL),
|
||||||
"title" => new \external_value(PARAM_TEXT,'name of subitem',VALUE_OPTIONAL),
|
"title" => new \external_value(PARAM_TEXT,'name of subitem',VALUE_OPTIONAL),
|
||||||
"details" => new \external_single_structure([
|
"details" => new \external_single_structure([
|
||||||
"type" => new \external_value(PARAM_RAW, 'type',VALUE_OPTIONAL),
|
"type" => new \external_value(PARAM_RAW, 'type',VALUE_OPTIONAL),
|
||||||
|
|
|
@ -3,10 +3,15 @@ namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
|
||||||
use \local_treestudyplan\courseinfo;
|
use \local_treestudyplan\courseinfo;
|
||||||
|
use \local_treestudyplan\associationservice;
|
||||||
use \local_treestudyplan\local\helpers\webservicehelper;
|
use \local_treestudyplan\local\helpers\webservicehelper;
|
||||||
|
use \local_treestudyplan\completionscanner;
|
||||||
|
use \local_treestudyplan\gradingscanner;
|
||||||
|
|
||||||
class courseservice extends \external_api
|
class courseservice extends \external_api
|
||||||
{
|
{
|
||||||
|
const CAP_EDIT = "local/treestudyplan:editstudyplan";
|
||||||
|
const CAP_VIEW = "local/treestudyplan:viewuserreports";
|
||||||
|
|
||||||
/************************
|
/************************
|
||||||
* *
|
* *
|
||||||
|
@ -50,7 +55,7 @@ class courseservice extends \external_api
|
||||||
$root = \core_course_category::get($root_id);
|
$root = \core_course_category::get($root_id);
|
||||||
$context = $root->get_context();
|
$context = $root->get_context();
|
||||||
// Make sure the user has access to the context for editing purposes
|
// Make sure the user has access to the context for editing purposes
|
||||||
webservicehelper::require_capabilities("local/treestudyplan:editstudyplan",$context);
|
webservicehelper::require_capabilities(self::CAP_EDIT,$context);
|
||||||
|
|
||||||
// Determine top categories from provided context
|
// Determine top categories from provided context
|
||||||
|
|
||||||
|
@ -135,9 +140,9 @@ class courseservice extends \external_api
|
||||||
public static function list_accessible_categories($operation="edit")
|
public static function list_accessible_categories($operation="edit")
|
||||||
{
|
{
|
||||||
if($operation == "edit"){
|
if($operation == "edit"){
|
||||||
$capability = "local/treestudyplan:editstudyplan";
|
$capability = self::CAP_EDIT;
|
||||||
} else { // $operation == "view" || default
|
} else { // $operation == "view" || default
|
||||||
$capability = "local/treestudyplan:viewuserreports";
|
$capability = self::CAP_VIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cats = static::categories_by_capability($capability);
|
$cats = static::categories_by_capability($capability);
|
||||||
|
@ -208,9 +213,9 @@ class courseservice extends \external_api
|
||||||
{
|
{
|
||||||
global $DB;
|
global $DB;
|
||||||
if($operation == "edit"){
|
if($operation == "edit"){
|
||||||
$capability = "local/treestudyplan:editstudyplan";
|
$capability = self::CAP_EDIT;
|
||||||
} else { // $operation == "view" || default
|
} else { // $operation == "view" || default
|
||||||
$capability = "local/treestudyplan:viewuserreports";
|
$capability = self::CAP_VIEW;
|
||||||
}
|
}
|
||||||
$context_ids = [];
|
$context_ids = [];
|
||||||
$rs = $DB->get_recordset_sql("SELECT DISTINCT context_id, COUNT(*) as num FROM {local_treestudyplan}
|
$rs = $DB->get_recordset_sql("SELECT DISTINCT context_id, COUNT(*) as num FROM {local_treestudyplan}
|
||||||
|
@ -243,9 +248,9 @@ class courseservice extends \external_api
|
||||||
public static function list_accessible_categories_with_usage($operation='edit'){
|
public static function list_accessible_categories_with_usage($operation='edit'){
|
||||||
global $DB;
|
global $DB;
|
||||||
if($operation == "edit"){
|
if($operation == "edit"){
|
||||||
$capability = "local/treestudyplan:editstudyplan";
|
$capability = self::CAP_EDIT;
|
||||||
} else { // $operation == "view" || default
|
} else { // $operation == "view" || default
|
||||||
$capability = "local/treestudyplan:viewuserreports";
|
$capability = self::CAP_VIEW;
|
||||||
}
|
}
|
||||||
// retrieve context ids used
|
// retrieve context ids used
|
||||||
$context_ids = [];
|
$context_ids = [];
|
||||||
|
@ -269,6 +274,7 @@ class courseservice extends \external_api
|
||||||
}
|
}
|
||||||
$o = new \stdClass();
|
$o = new \stdClass();
|
||||||
$o->cat = $cat;
|
$o->cat = $cat;
|
||||||
|
$o->ctxid = $ctxid;
|
||||||
$o->count = $count;
|
$o->count = $count;
|
||||||
$list[] = $o;
|
$list[] = $o;
|
||||||
}
|
}
|
||||||
|
@ -276,4 +282,119 @@ class courseservice extends \external_api
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************
|
||||||
|
*
|
||||||
|
* Progress scanners for teacherview
|
||||||
|
*
|
||||||
|
**************************************/
|
||||||
|
|
||||||
|
public static function scan_grade_progress_parameters()
|
||||||
|
{
|
||||||
|
return new \external_function_parameters( [
|
||||||
|
"gradeitemid" => new \external_value(PARAM_INT, 'Grade item ID to scan progress for',VALUE_DEFAULT),
|
||||||
|
"studyplanid" => new \external_value(PARAM_INT, 'Study plan id to check progress in',VALUE_DEFAULT),
|
||||||
|
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function scan_grade_progress_returns()
|
||||||
|
{
|
||||||
|
return gradingscanner::structure(VALUE_REQUIRED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function scan_grade_progress($gradeitemid, $studyplanid)
|
||||||
|
{
|
||||||
|
global $DB;
|
||||||
|
// Verify access to the study plan
|
||||||
|
$o = studyplan::findById($studyplanid);
|
||||||
|
webservicehelper::require_capabilities(self::CAP_VIEW,$o->context());
|
||||||
|
|
||||||
|
// Retrieve grade item
|
||||||
|
$gi = \grade_item::fetch(["id" => $gradeitemid]);
|
||||||
|
|
||||||
|
// Validate course is linked to studyplan
|
||||||
|
$courseid = $gi->courseid;
|
||||||
|
if(!$o->course_linked($courseid)){
|
||||||
|
throw new \webservice_access_exception("Course {$courseid} linked to grade item {$gradeitemid} is not linked to studyplan {$o->id()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$scanner = new gradingscanner($gi);
|
||||||
|
return $scanner->model();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static function scan_completion_progress_parameters()
|
||||||
|
{
|
||||||
|
return new \external_function_parameters( [
|
||||||
|
"criteriaid" => new \external_value(PARAM_INT, 'CriteriaID to scan progress for',VALUE_DEFAULT),
|
||||||
|
"studyplanid" => new \external_value(PARAM_INT, 'Study plan id to check progress in',VALUE_DEFAULT),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function scan_completion_progress_returns()
|
||||||
|
{
|
||||||
|
return completionscanner::structure(VALUE_REQUIRED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function scan_completion_progress($criteriaid, $studyplanid)
|
||||||
|
{
|
||||||
|
global $DB;
|
||||||
|
// Verify access to the study plan
|
||||||
|
$o = studyplan::findById($studyplanid);
|
||||||
|
webservicehelper::require_capabilities(self::CAP_VIEW,$o->context());
|
||||||
|
|
||||||
|
$crit = \completion_criteria::fetch(["id" => $criteriaid]);
|
||||||
|
$courseid = $crit->course;
|
||||||
|
if(!$o->course_linked($courseid)){
|
||||||
|
throw new \webservice_access_exception("Course {$courseid} linked to criteria {$criteriaid} is not linked to studyplan {$o->id()}");
|
||||||
|
}
|
||||||
|
$scanner = new completionscanner($crit);
|
||||||
|
return $scanner->model();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function scan_badge_progress_parameters()
|
||||||
|
{
|
||||||
|
return new \external_function_parameters( [
|
||||||
|
"badgeid" => new \external_value(PARAM_INT, 'Badge to scan progress for',VALUE_DEFAULT),
|
||||||
|
"studyplanid" => new \external_value(PARAM_INT, 'Study plan id to limit progress search to (to determine which students to scan)',VALUE_DEFAULT),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function scan_badge_progress_returns()
|
||||||
|
{
|
||||||
|
return new \external_single_structure([
|
||||||
|
"total" => new \external_value(PARAM_INT, 'Total number of students scanned'),
|
||||||
|
"issued" => new \external_value(PARAM_INT, 'Number of issued badges'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function scan_badge_progress($badgeid,$studyplanid)
|
||||||
|
{
|
||||||
|
global $DB;
|
||||||
|
// Check access to the study plan
|
||||||
|
$o = studyplan::findById($studyplanid);
|
||||||
|
webservicehelper::require_capabilities(self::CAP_VIEW,$o->context());
|
||||||
|
|
||||||
|
// Validate that badge is linked to studyplan
|
||||||
|
if(!$o->badge_linked($badgeid)){
|
||||||
|
throw new \webservice_access_exception("Badge {$badgeid} is not linked to studyplan {$o->id()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get badge info
|
||||||
|
$badge = new \core_badges\badge($badgeid);
|
||||||
|
$badgeinfo = new badgeinfo($badge);
|
||||||
|
|
||||||
|
// get the connected users
|
||||||
|
$students = associationservice::all_associated($studyplanid);
|
||||||
|
// Just get the user ids
|
||||||
|
$studentids = array_map(function ($a){ return $a["id"];},$students);
|
||||||
|
|
||||||
|
return [
|
||||||
|
"total" => count($studentids),
|
||||||
|
"issued" => $badgeinfo->count_issued($studentids),
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -721,5 +721,41 @@ class studyplan {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See if the specified course id is linked in this studyplan
|
||||||
|
*/
|
||||||
|
public function course_linked($courseid){
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
$sql = "SELECT COUNT(i.id)
|
||||||
|
FROM {local_treestudyplan}
|
||||||
|
INNER JOIN {local_treestudyplan_line} l ON p.id = l.studyplan_id
|
||||||
|
INNER JOIN {local_treestudyplan_item} i ON l.id = i.line_id
|
||||||
|
WHERE p.id = :planid
|
||||||
|
AND i.course_id = :courseid";
|
||||||
|
$count = $DB->get_field_sql($sql,["courseid" => $courseid, "planid" => $this->id]);
|
||||||
|
|
||||||
|
return ($count > 0)?true:false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See if the specified course id is linked in this studyplan
|
||||||
|
*/
|
||||||
|
public function badge_linked($badgeid){
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
$sql = "SELECT COUNT(i.id)
|
||||||
|
FROM {local_treestudyplan}
|
||||||
|
INNER JOIN {local_treestudyplan_line} l ON p.id = l.studyplan_id
|
||||||
|
INNER JOIN {local_treestudyplan_item} i ON l.id = i.line_id
|
||||||
|
WHERE p.id = :planid
|
||||||
|
AND i.badge_id = :badgeid";
|
||||||
|
$count = $DB->get_field_sql($sql,["badgeid" => $badgeid, "planid" => $this->id]);
|
||||||
|
|
||||||
|
return ($count > 0)?true:false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
$plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494)
|
$plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494)
|
||||||
$plugin->version = 2023051700; // YYYYMMDDHH (year, month, day, iteration)
|
$plugin->version = 2023061600; // YYYYMMDDHH (year, month, day, iteration)
|
||||||
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11)
|
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11)
|
||||||
|
|
||||||
$plugin->dependencies = [
|
$plugin->dependencies = [
|
||||||
|
|
Loading…
Reference in a new issue