Moodle code style fixes part 1
This commit is contained in:
parent
ab8a3c6f84
commit
1a3df05195
34
build.php
34
build.php
|
@ -1,13 +1,35 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
define('CLI_SCRIPT', true);
|
||||||
|
require_once("../../config.php");
|
||||||
$plugin = new stdClass;
|
$plugin = new stdClass;
|
||||||
include('version.php');
|
require_once('version.php');
|
||||||
|
|
||||||
$a = explode("_", $plugin->component, 2);
|
$a = explode("_", $plugin->component, 2);
|
||||||
$plugin->type = $a[0];
|
$plugin->type = $a[0];
|
||||||
$plugin->name = $a[1];
|
$plugin->name = $a[1];
|
||||||
|
|
||||||
$exclude_paths = [
|
$excludepaths = [
|
||||||
"build", // dir for build zip files
|
"build", // Dir for build zip files.
|
||||||
"build/*",
|
"build/*",
|
||||||
"build.*",
|
"build.*",
|
||||||
"vuemode.sh",
|
"vuemode.sh",
|
||||||
|
@ -19,16 +41,16 @@ $exclude_paths = [
|
||||||
"*.zip",
|
"*.zip",
|
||||||
];
|
];
|
||||||
|
|
||||||
// Determine some paths
|
// Determine some paths.
|
||||||
$wd = realpath(dirname(__FILE__));
|
$wd = realpath(dirname(__FILE__));
|
||||||
$parent = dirname($wd);
|
$parent = dirname($wd);
|
||||||
$plugindirname = basename($wd);
|
$plugindirname = basename($wd);
|
||||||
$builddir = $wd."/"."build";
|
$builddir = $wd."/"."build";
|
||||||
$zipname = $builddir."/"."{$plugin->name}-{$plugin->version}.zip";
|
$zipname = $builddir."/"."{$plugin->name}-{$plugin->version}.zip";
|
||||||
|
|
||||||
// create the exclude line
|
// Create the exclude line.
|
||||||
$exclude = "-x ";
|
$exclude = "-x ";
|
||||||
foreach($exclude_paths as $x){
|
foreach ($excludepaths as $x) {
|
||||||
$exclude .= "'{$plugindirname}/{$x}' ";
|
$exclude .= "'{$plugindirname}/{$x}' ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,32 @@
|
||||||
<?php
|
<?php
|
||||||
require_once("../../config.php");
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once("../../config.php");
|
||||||
|
|
||||||
require_once($CFG->libdir.'/adminlib.php');
|
require_once($CFG->libdir.'/adminlib.php');
|
||||||
admin_externalpage_setup("local_treestudyplan_gradeconfig");
|
admin_externalpage_setup("local_treestudyplan_gradeconfig");
|
||||||
|
|
||||||
$systemcontext = context_system::instance();
|
$systemcontext = context_system::instance();
|
||||||
// Check if user has capability to manage this
|
// Check if user has capability to manage this.
|
||||||
require_capability('local/treestudyplan:configure', $systemcontext);
|
require_capability('local/treestudyplan:configure', $systemcontext);
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,9 +50,8 @@ foreach($mappings as $cfg){
|
||||||
print $OUTPUT->header();
|
print $OUTPUT->header();
|
||||||
|
|
||||||
if ($_POST["action"] == "update") {
|
if ($_POST["action"] == "update") {
|
||||||
// First loop through the scales to see which need to be updated
|
// First loop through the scales to see which need to be updated.
|
||||||
foreach($scales as $scale)
|
foreach ($scales as $scale) {
|
||||||
{
|
|
||||||
if (array_key_exists($scale->id, $scale_cfgs)) {
|
if (array_key_exists($scale->id, $scale_cfgs)) {
|
||||||
$scalecfg = $scale_cfgs[$scale->id];
|
$scalecfg = $scale_cfgs[$scale->id];
|
||||||
|
|
||||||
|
@ -64,14 +83,14 @@ if($_POST["action"] == "update"){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($requireinsert) {
|
if ($requireinsert) {
|
||||||
// Insert into database and add to the list of scale configs
|
// Insert into database and add to the list of scale configs.
|
||||||
$id = $DB->insert_record(GRADECFG_TABLE, $scalecfg);
|
$id = $DB->insert_record(GRADECFG_TABLE, $scalecfg);
|
||||||
$scalecfg = $DB->get_record(GRADECFG_TABLE, ['id' => $id]);
|
$scalecfg = $DB->get_record(GRADECFG_TABLE, ['id' => $id]);
|
||||||
$scale_cfgs[$id] = $scalecfg;
|
$scale_cfgs[$id] = $scalecfg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Now, loop through the gradepoints to parse
|
// Now, loop through the gradepoints to parse .
|
||||||
$deletelist = [];
|
$deletelist = [];
|
||||||
foreach ($grade_cfgs as $gradecfg) {
|
foreach ($grade_cfgs as $gradecfg) {
|
||||||
$deletekey = "g_{$gradecfg->grade_points}_delete";
|
$deletekey = "g_{$gradecfg->grade_points}_delete";
|
||||||
|
@ -88,7 +107,7 @@ if($_POST["action"] == "update"){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$DB->update_record(GRADECFG_TABLE, $gradecfg);
|
$DB->update_record(GRADECFG_TABLE, $gradecfg);
|
||||||
// reload to ensure proper rounding is done
|
// reload to ensure proper rounding is done.
|
||||||
$grade_cfgs[$gradecfg->grade_points] = $DB->get_record(GRADECFG_TABLE, ['id' => $gradecfg->id]);
|
$grade_cfgs[$gradecfg->grade_points] = $DB->get_record(GRADECFG_TABLE, ['id' => $gradecfg->id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +117,7 @@ if($_POST["action"] == "update"){
|
||||||
}
|
}
|
||||||
unset($deletelist);
|
unset($deletelist);
|
||||||
|
|
||||||
// And add an optionally existing new gradepoint setting
|
// And add an optionally existing new gradepoint setting.
|
||||||
if (array_key_exists("g_new_gradepoints", $_POST) && !empty($_POST["g_new_gradepoints"]) && is_numeric($_POST["g_new_gradepoints"]) ) {
|
if (array_key_exists("g_new_gradepoints", $_POST) && !empty($_POST["g_new_gradepoints"]) && is_numeric($_POST["g_new_gradepoints"]) ) {
|
||||||
$gp = intval($_POST["g_new_gradepoints"]);
|
$gp = intval($_POST["g_new_gradepoints"]);
|
||||||
if (!array_key_exists($gp, $grade_cfgs)) {
|
if (!array_key_exists($gp, $grade_cfgs)) {
|
||||||
|
@ -112,9 +131,9 @@ if($_POST["action"] == "update"){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($requireinsert) {
|
if ($requireinsert) {
|
||||||
// Insert into database and add to the list of grade configs
|
// Insert into database and add to the list of grade configs.
|
||||||
$id = $DB->insert_record(GRADECFG_TABLE, $gradecfg);
|
$id = $DB->insert_record(GRADECFG_TABLE, $gradecfg);
|
||||||
// reload to ensure proper rounding is done
|
// reload to ensure proper rounding is done.
|
||||||
$gradecfg = $DB->get_record(GRADECFG_TABLE, ['id' => $id]);
|
$gradecfg = $DB->get_record(GRADECFG_TABLE, ['id' => $id]);
|
||||||
$grade_cfgs[$id] = $gradecfg;
|
$grade_cfgs[$id] = $gradecfg;
|
||||||
}
|
}
|
||||||
|
@ -127,8 +146,7 @@ if($_POST["action"] == "update"){
|
||||||
|
|
||||||
//process all available scales and load the current configuration for it.
|
//process all available scales and load the current configuration for it.
|
||||||
$data = [];
|
$data = [];
|
||||||
foreach($scales as $scale)
|
foreach ($scales as $scale) {
|
||||||
{
|
|
||||||
$scale->load_items();
|
$scale->load_items();
|
||||||
$scalecfg = null;
|
$scalecfg = null;
|
||||||
if (array_key_exists($scale->id, $scale_cfgs)) {
|
if (array_key_exists($scale->id, $scale_cfgs)) {
|
||||||
|
@ -147,7 +165,7 @@ foreach($scales as $scale)
|
||||||
|
|
||||||
$options_completed = html_writer::tag("option", get_string('select_scaleitem', 'local_treestudyplan'), $attrs_c);
|
$options_completed = html_writer::tag("option", get_string('select_scaleitem', 'local_treestudyplan'), $attrs_c);
|
||||||
$options_progress = html_writer::tag("option", get_string('select_scaleitem', 'local_treestudyplan'), $attrs_p);
|
$options_progress = html_writer::tag("option", get_string('select_scaleitem', 'local_treestudyplan'), $attrs_p);
|
||||||
$key = 1; // Start counting by one, as used in sum aggregations
|
$key = 1; // Start counting by one, as used in sum aggregations.
|
||||||
|
|
||||||
foreach ($scale->scale_items as $value) {
|
foreach ($scale->scale_items as $value) {
|
||||||
$attrs_c = ["value" => $key];
|
$attrs_c = ["value" => $key];
|
||||||
|
@ -168,7 +186,7 @@ foreach($scales as $scale)
|
||||||
|
|
||||||
$row = [];
|
$row = [];
|
||||||
$row[] = $scale->name;
|
$row[] = $scale->name;
|
||||||
//$row[] = html_writer::tag("select", $options_progress, ['name' => "s_{$scale->id}_min_progress",'autocomplete' => 'off']) ;
|
//$row[] = html_writer::tag("select", $options_progress, ['name' => "s_{$scale->id}_min_progress", 'autocomplete' => 'off']) ;.
|
||||||
$row[] = html_writer::tag("select", $options_completed, ['name' => "s_{$scale->id}_min_completed", 'autocomplete' => 'off']) ;
|
$row[] = html_writer::tag("select", $options_completed, ['name' => "s_{$scale->id}_min_completed", 'autocomplete' => 'off']) ;
|
||||||
$data[] = $row;
|
$data[] = $row;
|
||||||
}
|
}
|
||||||
|
@ -181,11 +199,11 @@ $table = new html_table();
|
||||||
$table->id = "";
|
$table->id = "";
|
||||||
$table->attributes['class'] = 'generaltable m-roomtable';
|
$table->attributes['class'] = 'generaltable m-roomtable';
|
||||||
$table->tablealign = 'center';
|
$table->tablealign = 'center';
|
||||||
$table->summary = '';//get_string('uploadtimetable_preview', 'local_chronotable');
|
$table->summary = '';//get_string('uploadtimetable_preview', 'local_chronotable');.
|
||||||
$table->head = [];
|
$table->head = [];
|
||||||
$table->data = $data;
|
$table->data = $data;
|
||||||
$table->head[] = get_string('scale');
|
$table->head[] = get_string('scale');
|
||||||
//$table->head[] = get_string('min_progress', 'local_treestudyplan');
|
//$table->head[] = get_string('min_progress', 'local_treestudyplan');.
|
||||||
$table->head[] = get_string('min_completed', 'local_treestudyplan');
|
$table->head[] = get_string('min_completed', 'local_treestudyplan');
|
||||||
|
|
||||||
print $OUTPUT->heading(get_string('cfg_grades_desc_head', 'local_treestudyplan'));
|
print $OUTPUT->heading(get_string('cfg_grades_desc_head', 'local_treestudyplan'));
|
||||||
|
@ -197,7 +215,7 @@ $data = [];
|
||||||
foreach ($grade_cfgs as $g) {
|
foreach ($grade_cfgs as $g) {
|
||||||
$row = [];
|
$row = [];
|
||||||
$row[] = $g->grade_points;
|
$row[] = $g->grade_points;
|
||||||
// $row[] = html_writer::tag("input", null, ['name' => "g_{$g->grade_points}_min_progress", 'value' => "{$g->min_progress}", 'type' => 'text', "class" => "float", 'autocomplete' => 'off']) ;
|
// $row[] = html_writer::tag("input", null, ['name' => "g_{$g->grade_points}_min_progress", 'value' => "{$g->min_progress}", 'type' => 'text', "class" => "float", 'autocomplete' => 'off']) ;.
|
||||||
$row[] = html_writer::tag("input", null, ['name' => "g_{$g->grade_points}_min_completed", 'value' => "{$g->min_completed}", 'type' => 'text', "class" => "float", 'autocomplete' => 'off']) ;
|
$row[] = html_writer::tag("input", null, ['name' => "g_{$g->grade_points}_min_completed", 'value' => "{$g->min_completed}", 'type' => 'text', "class" => "float", 'autocomplete' => 'off']) ;
|
||||||
$row[] = html_writer::tag("input", null, ['name' => "g_{$g->grade_points}_delete", 'type' => 'checkbox', ]) ;
|
$row[] = html_writer::tag("input", null, ['name' => "g_{$g->grade_points}_delete", 'type' => 'checkbox', ]) ;
|
||||||
$data[] = $row;
|
$data[] = $row;
|
||||||
|
@ -205,7 +223,7 @@ foreach($grade_cfgs as $g){
|
||||||
|
|
||||||
$row = [];
|
$row = [];
|
||||||
$row[] = html_writer::tag("input", null, ['name' => "g_new_gradepoints", 'value' => '', 'type' => 'number', 'min' => '0', 'pattern' => '/d+', 'step' => '1', 'autocomplete' => 'off']);
|
$row[] = html_writer::tag("input", null, ['name' => "g_new_gradepoints", 'value' => '', 'type' => 'number', 'min' => '0', 'pattern' => '/d+', 'step' => '1', 'autocomplete' => 'off']);
|
||||||
//$row[] = html_writer::tag("input", null, ['name' => "g_new_min_progress", 'value' => '', 'type' => 'text', "class" => "float", 'autocomplete' => 'off']) ;
|
//$row[] = html_writer::tag("input", null, ['name' => "g_new_min_progress", 'value' => '', 'type' => 'text', "class" => "float", 'autocomplete' => 'off']) ;.
|
||||||
$row[] = html_writer::tag("input", null, ['name' => "g_new_min_completed", 'value' => '', 'type' => 'text', "class" => "float", 'autocomplete' => 'off']) ;
|
$row[] = html_writer::tag("input", null, ['name' => "g_new_min_completed", 'value' => '', 'type' => 'text', "class" => "float", 'autocomplete' => 'off']) ;
|
||||||
|
|
||||||
$data[] = $row;
|
$data[] = $row;
|
||||||
|
@ -215,11 +233,11 @@ $table = new html_table();
|
||||||
$table->id = "";
|
$table->id = "";
|
||||||
$table->attributes['class'] = 'generaltable m-roomtable';
|
$table->attributes['class'] = 'generaltable m-roomtable';
|
||||||
$table->tablealign = 'center';
|
$table->tablealign = 'center';
|
||||||
$table->summary = '';//get_string('uploadtimetable_preview', 'local_chronotable');
|
$table->summary = '';//get_string('uploadtimetable_preview', 'local_chronotable');.
|
||||||
$table->head = [];
|
$table->head = [];
|
||||||
$table->data = $data;
|
$table->data = $data;
|
||||||
$table->head[] = get_string('grade_points', 'local_treestudyplan');
|
$table->head[] = get_string('grade_points', 'local_treestudyplan');
|
||||||
//$table->head[] = get_string('min_progress', 'local_treestudyplan');
|
//$table->head[] = get_string('min_progress', 'local_treestudyplan');.
|
||||||
$table->head[] = get_string('min_completed', 'local_treestudyplan');
|
$table->head[] = get_string('min_completed', 'local_treestudyplan');
|
||||||
$table->head[] = get_string('delete', );
|
$table->head[] = get_string('delete', );
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
@ -19,7 +40,7 @@ abstract class aggregator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function list() {
|
public static function list() {
|
||||||
// static list, since we'd need to implement a lot of static data for new aggregation methods anyway
|
// static list, since we'd need to implement a lot of static data for new aggregation methods anyway.
|
||||||
// and this is faster than any dynamic method.
|
// and this is faster than any dynamic method.
|
||||||
return [
|
return [
|
||||||
"core", # use moodle core completion
|
"core", # use moodle core completion
|
||||||
|
@ -59,19 +80,19 @@ abstract class aggregator {
|
||||||
|
|
||||||
public abstract function grade_completion(gradeinfo $gradeinfo, $userid);
|
public abstract function grade_completion(gradeinfo $gradeinfo, $userid);
|
||||||
|
|
||||||
// Aggregation method makes use of "required grades" in a course/module
|
// Aggregation method makes use of "required grades" in a course/module.
|
||||||
public abstract function useRequiredGrades();
|
public abstract function useRequiredGrades();
|
||||||
// Aggregation method makes use of
|
// Aggregation method makes use of .
|
||||||
public abstract function useItemConditions();
|
public abstract function useItemConditions();
|
||||||
|
|
||||||
// Whether the aggregation method uses core_completion, or treestudyplan custom completion
|
// Whether the aggregation method uses core_completion, or treestudyplan custom completion.
|
||||||
public function usecorecompletioninfo() {
|
public function usecorecompletioninfo() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parameter editing functions - override in child class to implement parameter config for aggregation
|
// Parameter editing functions - override in child class to implement parameter config for aggregation.
|
||||||
|
|
||||||
// Return the current configuration string
|
// Return the current configuration string.
|
||||||
public function config_string() {
|
public function config_string() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -104,7 +125,7 @@ abstract class aggregator {
|
||||||
|
|
||||||
$list = [];
|
$list = [];
|
||||||
foreach (self::list() as $agid) {
|
foreach (self::list() as $agid) {
|
||||||
$a = self::create($agid,""); // create new one with empty config string
|
$a = self::create($agid, ""); // create new one with empty config string.
|
||||||
$list[] = [
|
$list[] = [
|
||||||
'id' => $agid,
|
'id' => $agid,
|
||||||
'name' => get_string("{$agid}_aggregator_title", "local_treestudyplan"),
|
'name' => get_string("{$agid}_aggregator_title", "local_treestudyplan"),
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
|
|
||||||
use local_treestudyplan\local\helpers\webservicehelper;
|
use local_treestudyplan\local\helpers\webservicehelper;
|
||||||
|
@ -90,12 +111,12 @@ class associationservice extends \external_api
|
||||||
return new \external_multiple_structure(self::cohort_structure());
|
return new \external_multiple_structure(self::cohort_structure());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual functions
|
// Actual functions.
|
||||||
public static function list_cohort($like='', $exclude_id=null, $context_id=1)
|
public static function list_cohort($like='', $exclude_id=null, $context_id=1)
|
||||||
{
|
{
|
||||||
global $CFG, $DB;
|
global $CFG, $DB;
|
||||||
|
|
||||||
// Only allow this if the user has the right to edit in this context
|
// Only allow this if the user has the right to edit in this context.
|
||||||
$context = webservicehelper::find_context($context_id);
|
$context = webservicehelper::find_context($context_id);
|
||||||
webservicehelper::require_capabilities(self::CAP_EDIT, $context);
|
webservicehelper::require_capabilities(self::CAP_EDIT, $context);
|
||||||
|
|
||||||
|
@ -109,8 +130,8 @@ class associationservice extends \external_api
|
||||||
$sql .= " AND (j.studyplan_id IS NULL OR j.studyplan_id != :exclude_id)";
|
$sql .= " AND (j.studyplan_id IS NULL OR j.studyplan_id != :exclude_id)";
|
||||||
$params['exclude_id'] = $exclude_id;
|
$params['exclude_id'] = $exclude_id;
|
||||||
}
|
}
|
||||||
if($context_id > 1){ // system context returns all cohorts, including system cohorts
|
if ($context_id > 1) { // system context returns all cohorts, including system cohorts.
|
||||||
// otherwise,
|
// otherwise, .
|
||||||
$sql .= " AND contextid = :context_id";
|
$sql .= " AND contextid = :context_id";
|
||||||
$params['context_id'] = $context_id;
|
$params['context_id'] = $context_id;
|
||||||
}
|
}
|
||||||
|
@ -138,12 +159,12 @@ class associationservice extends \external_api
|
||||||
return new \external_multiple_structure(self::user_structure());
|
return new \external_multiple_structure(self::user_structure());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual functions
|
// Actual functions.
|
||||||
public static function find_user($like, $exclude_id=null, $context_id=1)
|
public static function find_user($like, $exclude_id=null, $context_id=1)
|
||||||
{
|
{
|
||||||
global $CFG, $DB;
|
global $CFG, $DB;
|
||||||
|
|
||||||
// Only allow this if the user has the right to edit in this context (using system rights would make things more confusing)
|
// Only allow this if the user has the right to edit in this context (using system rights would make things more confusing).
|
||||||
$context = webservicehelper::find_context($context_id);
|
$context = webservicehelper::find_context($context_id);
|
||||||
webservicehelper::require_capabilities(self::CAP_EDIT, $context);
|
webservicehelper::require_capabilities(self::CAP_EDIT, $context);
|
||||||
|
|
||||||
|
@ -186,7 +207,7 @@ class associationservice extends \external_api
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual functions
|
// Actual functions.
|
||||||
public static function connect_cohort($studyplan_id, $cohort_id)
|
public static function connect_cohort($studyplan_id, $cohort_id)
|
||||||
{
|
{
|
||||||
global $CFG, $DB;
|
global $CFG, $DB;
|
||||||
|
@ -194,8 +215,7 @@ class associationservice extends \external_api
|
||||||
$studyplan = studyplan::findById($studyplan_id);
|
$studyplan = studyplan::findById($studyplan_id);
|
||||||
webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context());
|
webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context());
|
||||||
|
|
||||||
if(!$DB->record_exists('local_treestudyplan_cohort', ['studyplan_id' => $studyplan_id, 'cohort_id' => $cohort_id]))
|
if (!$DB->record_exists('local_treestudyplan_cohort', ['studyplan_id' => $studyplan_id, 'cohort_id' => $cohort_id])) {
|
||||||
{
|
|
||||||
$id = $DB->insert_record('local_treestudyplan_cohort', [
|
$id = $DB->insert_record('local_treestudyplan_cohort', [
|
||||||
'studyplan_id' => $studyplan_id,
|
'studyplan_id' => $studyplan_id,
|
||||||
'cohort_id' => $cohort_id,
|
'cohort_id' => $cohort_id,
|
||||||
|
@ -226,7 +246,7 @@ class associationservice extends \external_api
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual functions
|
// Actual functions.
|
||||||
public static function disconnect_cohort($studyplan_id, $cohort_id)
|
public static function disconnect_cohort($studyplan_id, $cohort_id)
|
||||||
{
|
{
|
||||||
global $CFG, $DB;
|
global $CFG, $DB;
|
||||||
|
@ -234,8 +254,7 @@ class associationservice extends \external_api
|
||||||
$studyplan = studyplan::findById($studyplan_id);
|
$studyplan = studyplan::findById($studyplan_id);
|
||||||
webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context());
|
webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context());
|
||||||
|
|
||||||
if($DB->record_exists('local_treestudyplan_cohort', ['studyplan_id' => $studyplan_id, 'cohort_id' => $cohort_id]))
|
if ($DB->record_exists('local_treestudyplan_cohort', ['studyplan_id' => $studyplan_id, 'cohort_id' => $cohort_id])) {
|
||||||
{
|
|
||||||
$DB->delete_records('local_treestudyplan_cohort', [
|
$DB->delete_records('local_treestudyplan_cohort', [
|
||||||
'studyplan_id' => $studyplan_id,
|
'studyplan_id' => $studyplan_id,
|
||||||
'cohort_id' => $cohort_id,
|
'cohort_id' => $cohort_id,
|
||||||
|
@ -266,7 +285,7 @@ class associationservice extends \external_api
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual functions
|
// Actual functions.
|
||||||
public static function connect_user($studyplan_id, $user_id)
|
public static function connect_user($studyplan_id, $user_id)
|
||||||
{
|
{
|
||||||
global $CFG, $DB;
|
global $CFG, $DB;
|
||||||
|
@ -274,8 +293,7 @@ class associationservice extends \external_api
|
||||||
$studyplan = studyplan::findById($studyplan_id);
|
$studyplan = studyplan::findById($studyplan_id);
|
||||||
webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context());
|
webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context());
|
||||||
|
|
||||||
if(!$DB->record_exists('local_treestudyplan_user', ['studyplan_id' => $studyplan_id, 'user_id' => $user_id]))
|
if (!$DB->record_exists('local_treestudyplan_user', ['studyplan_id' => $studyplan_id, 'user_id' => $user_id])) {
|
||||||
{
|
|
||||||
$id = $DB->insert_record('local_treestudyplan_user', [
|
$id = $DB->insert_record('local_treestudyplan_user', [
|
||||||
'studyplan_id' => $studyplan_id,
|
'studyplan_id' => $studyplan_id,
|
||||||
'user_id' => $user_id,
|
'user_id' => $user_id,
|
||||||
|
@ -305,15 +323,14 @@ class associationservice extends \external_api
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual functions
|
// Actual functions.
|
||||||
public static function disconnect_user($studyplan_id, $user_id)
|
public static function disconnect_user($studyplan_id, $user_id)
|
||||||
{
|
{
|
||||||
global $CFG, $DB;
|
global $CFG, $DB;
|
||||||
$studyplan = studyplan::findById($studyplan_id);
|
$studyplan = studyplan::findById($studyplan_id);
|
||||||
webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context());
|
webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context());
|
||||||
|
|
||||||
if($DB->record_exists('local_treestudyplan_user', ['studyplan_id' => $studyplan_id, 'user_id' => $user_id]))
|
if ($DB->record_exists('local_treestudyplan_user', ['studyplan_id' => $studyplan_id, 'user_id' => $user_id])) {
|
||||||
{
|
|
||||||
$DB->delete_records('local_treestudyplan_user', [
|
$DB->delete_records('local_treestudyplan_user', [
|
||||||
'studyplan_id' => $studyplan_id,
|
'studyplan_id' => $studyplan_id,
|
||||||
'user_id' => $user_id,
|
'user_id' => $user_id,
|
||||||
|
@ -339,7 +356,7 @@ class associationservice extends \external_api
|
||||||
return new \external_multiple_structure(self::user_structure());
|
return new \external_multiple_structure(self::user_structure());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual functions
|
// Actual functions.
|
||||||
public static function associated_users($studyplan_id)
|
public static function associated_users($studyplan_id)
|
||||||
{
|
{
|
||||||
global $CFG, $DB;
|
global $CFG, $DB;
|
||||||
|
@ -351,8 +368,7 @@ class associationservice extends \external_api
|
||||||
$rs = $DB->get_recordset_sql($sql, ['studyplan_id' => $studyplan_id]);
|
$rs = $DB->get_recordset_sql($sql, ['studyplan_id' => $studyplan_id]);
|
||||||
|
|
||||||
$users = [];
|
$users = [];
|
||||||
foreach($rs as $u)
|
foreach ($rs as $u) {
|
||||||
{
|
|
||||||
$users[] = self::make_user_model($u);
|
$users[] = self::make_user_model($u);
|
||||||
}
|
}
|
||||||
$rs->close();
|
$rs->close();
|
||||||
|
@ -372,7 +388,7 @@ class associationservice extends \external_api
|
||||||
return new \external_multiple_structure(self::cohort_structure());
|
return new \external_multiple_structure(self::cohort_structure());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual functions
|
// Actual functions.
|
||||||
public static function associated_cohorts($studyplan_id)
|
public static function associated_cohorts($studyplan_id)
|
||||||
{
|
{
|
||||||
global $CFG, $DB;
|
global $CFG, $DB;
|
||||||
|
@ -383,8 +399,7 @@ class associationservice extends \external_api
|
||||||
$sql .= " WHERE j.studyplan_id = :studyplan_id";
|
$sql .= " WHERE j.studyplan_id = :studyplan_id";
|
||||||
$rs = $DB->get_recordset_sql($sql, ['studyplan_id' => $studyplan_id]);
|
$rs = $DB->get_recordset_sql($sql, ['studyplan_id' => $studyplan_id]);
|
||||||
$cohorts = [];
|
$cohorts = [];
|
||||||
foreach($rs as $c)
|
foreach ($rs as $c) {
|
||||||
{
|
|
||||||
$cohorts[] = self::make_cohort_model($c);
|
$cohorts[] = self::make_cohort_model($c);
|
||||||
}
|
}
|
||||||
$rs->close();
|
$rs->close();
|
||||||
|
@ -404,7 +419,7 @@ class associationservice extends \external_api
|
||||||
return new \external_multiple_structure(self::user_structure());
|
return new \external_multiple_structure(self::user_structure());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual functions
|
// Actual functions.
|
||||||
public static function all_associated($studyplan_id)
|
public static function all_associated($studyplan_id)
|
||||||
{
|
{
|
||||||
global $CFG, $DB;
|
global $CFG, $DB;
|
||||||
|
@ -414,8 +429,8 @@ class associationservice extends \external_api
|
||||||
|
|
||||||
|
|
||||||
$users = [];
|
$users = [];
|
||||||
// SQL JOIN script selecting all users that have a cohort linked to this studyplan
|
// SQL JOIN script selecting all users that have a cohort linked to this studyplan .
|
||||||
// or are directly linked
|
// or are directly linked.
|
||||||
$sql = "SELECT DISTINCT u.id, u.username, u.firstname, u.lastname, u.idnumber, u.email
|
$sql = "SELECT DISTINCT u.id, u.username, u.firstname, u.lastname, u.idnumber, u.email
|
||||||
FROM {user} u
|
FROM {user} u
|
||||||
LEFT JOIN {cohort_members} cm ON u.id = cm.userid
|
LEFT JOIN {cohort_members} cm ON u.id = cm.userid
|
||||||
|
@ -426,8 +441,7 @@ class associationservice extends \external_api
|
||||||
ORDER BY u.lastname, u.firstname";
|
ORDER BY u.lastname, u.firstname";
|
||||||
$rs = $DB->get_recordset_sql($sql);
|
$rs = $DB->get_recordset_sql($sql);
|
||||||
|
|
||||||
foreach($rs as $u)
|
foreach ($rs as $u) {
|
||||||
{
|
|
||||||
$users[] = self::make_user_model($u);
|
$users[] = self::make_user_model($u);
|
||||||
}
|
}
|
||||||
$rs->close();
|
$rs->close();
|
||||||
|
@ -466,7 +480,7 @@ class associationservice extends \external_api
|
||||||
return success::structure();
|
return success::structure();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actual functions
|
// Actual functions.
|
||||||
public static function cascade_cohortsync($studyplan_id)
|
public static function cascade_cohortsync($studyplan_id)
|
||||||
{
|
{
|
||||||
$studyplan = studyplan::findById($studyplan_id);
|
$studyplan = studyplan::findById($studyplan_id);
|
||||||
|
@ -479,7 +493,7 @@ class associationservice extends \external_api
|
||||||
$userenroller = new cascadeusersync($studyplan);
|
$userenroller = new cascadeusersync($studyplan);
|
||||||
$userenroller->sync();
|
$userenroller->sync();
|
||||||
}
|
}
|
||||||
$studyplan->clear_csync_changed(); // Clear the csync required flag
|
$studyplan->clear_csync_changed(); // Clear the csync required flag.
|
||||||
|
|
||||||
return success::success()->model();
|
return success::success()->model();
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,30 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
|
||||||
class badgeinfo {
|
class badgeinfo {
|
||||||
private $badge; // Holds database record
|
private $badge; // Holds database record.
|
||||||
|
|
||||||
private const STATUSINFO = [
|
private const STATUSINFO = [
|
||||||
BADGE_STATUS_INACTIVE => 'inactive',
|
BADGE_STATUS_INACTIVE => 'inactive',
|
||||||
|
@ -17,7 +38,7 @@ class badgeinfo {
|
||||||
BADGE_STATUS_ACTIVE => 0,
|
BADGE_STATUS_ACTIVE => 0,
|
||||||
BADGE_STATUS_INACTIVE_LOCKED => 1,
|
BADGE_STATUS_INACTIVE_LOCKED => 1,
|
||||||
BADGE_STATUS_ACTIVE_LOCKED => 1,
|
BADGE_STATUS_ACTIVE_LOCKED => 1,
|
||||||
BADGE_STATUS_ARCHIVED => 1, // We don't want to edit archived badges anyway....
|
BADGE_STATUS_ARCHIVED => 1, // We don't want to edit archived badges anyway.... .
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct(\core_badges\badge $badge) {
|
public function __construct(\core_badges\badge $badge) {
|
||||||
|
@ -55,8 +76,7 @@ class badgeinfo {
|
||||||
], "Badge info", $value);
|
], "Badge info", $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function editor_model(array $studentlist=null)
|
public function editor_model(array $studentlist=null) {
|
||||||
{
|
|
||||||
$context = ($this->badge->type == BADGE_TYPE_SITE) ? \context_system::instance() : \context_course::instance($this->badge->courseid);
|
$context = ($this->badge->type == BADGE_TYPE_SITE) ? \context_system::instance() : \context_course::instance($this->badge->courseid);
|
||||||
// If the user is viewing another user's badge and doesn't have the right capability return only part of the data.
|
// If the user is viewing another user's badge and doesn't have the right capability return only part of the data.
|
||||||
|
|
||||||
|
@ -75,7 +95,7 @@ class badgeinfo {
|
||||||
'imageurl' => \moodle_url::make_pluginfile_url($context->id, 'badges', 'badgeimage', $this->badge->id, '/', 'f1')->out(false),
|
'imageurl' => \moodle_url::make_pluginfile_url($context->id, 'badges', 'badgeimage', $this->badge->id, '/', 'f1')->out(false),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Add badge issue stats if a studentlist is attached to the request
|
// Add badge issue stats if a studentlist is attached to the request.
|
||||||
if (!empty($studentlist) && is_array($studentlist)) {
|
if (!empty($studentlist) && is_array($studentlist)) {
|
||||||
$model['studentcount'] = count($studentlist);
|
$model['studentcount'] = count($studentlist);
|
||||||
$model['issuedcount'] = $this->count_issued($studentlist);
|
$model['issuedcount'] = $this->count_issued($studentlist);
|
||||||
|
@ -84,8 +104,7 @@ class badgeinfo {
|
||||||
return $model;
|
return $model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function user_structure($value=VALUE_REQUIRED)
|
public static function user_structure($value=VALUE_REQUIRED) {
|
||||||
{
|
|
||||||
return new \external_single_structure([
|
return new \external_single_structure([
|
||||||
"id" => new \external_value(PARAM_INT, 'id of badge'),
|
"id" => new \external_value(PARAM_INT, 'id of badge'),
|
||||||
"infolink" => new \external_value(PARAM_TEXT, 'badge issue information link', VALUE_OPTIONAL),
|
"infolink" => new \external_value(PARAM_TEXT, 'badge issue information link', VALUE_OPTIONAL),
|
||||||
|
@ -101,8 +120,7 @@ class badgeinfo {
|
||||||
], "Badge info", $value);
|
], "Badge info", $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function user_model($userid)
|
public function user_model($userid) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
$context = ($this->badge->type == BADGE_TYPE_SITE) ? \context_system::instance() : \context_course::instance($this->badge->courseid);
|
$context = ($this->badge->type == BADGE_TYPE_SITE) ? \context_system::instance() : \context_course::instance($this->badge->courseid);
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
|
||||||
|
@ -25,7 +46,7 @@ class cascadecohortsync {
|
||||||
}
|
}
|
||||||
|
|
||||||
static function uploadenrolmentmethods_get_group($courseid, $groupname) {
|
static function uploadenrolmentmethods_get_group($courseid, $groupname) {
|
||||||
// Function shamelessly copied from tool/uploadenrolmentmethods/locallib.php
|
// Function shamelessly copied from tool/uploadenrolmentmethods/locallib.php.
|
||||||
global $DB, $CFG;
|
global $DB, $CFG;
|
||||||
|
|
||||||
require_once($CFG->dirroot.'/group/lib.php');
|
require_once($CFG->dirroot.'/group/lib.php');
|
||||||
|
@ -57,19 +78,19 @@ class cascadecohortsync {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$enrol = \enrol_get_plugin(self::METHOD);
|
$enrol = \enrol_get_plugin(self::METHOD);
|
||||||
// Find the courses that need to be synced to the associated cohorts
|
// Find the courses that need to be synced to the associated cohorts.
|
||||||
$courseids = $this->studyplan->get_linked_course_ids();
|
$courseids = $this->studyplan->get_linked_course_ids();
|
||||||
// And find the cohorts that are linked to this studyplan.
|
// And find the cohorts that are linked to this studyplan.
|
||||||
$cohortids = $this->studyplan->get_linked_cohort_ids();
|
$cohortids = $this->studyplan->get_linked_cohort_ids();
|
||||||
|
|
||||||
// Next, for each course that is linked:
|
// Next, for each course that is linked:.
|
||||||
foreach ($courseids as $courseid) {
|
foreach ($courseids as $courseid) {
|
||||||
$course = \get_course($courseid);
|
$course = \get_course($courseid);
|
||||||
//\mtrace("Processing Course {$courseid} {$course->shortname}");
|
//\mtrace("Processing Course {$courseid} {$course->shortname}");.
|
||||||
// first create any nonexistent links
|
// first create any nonexistent links.
|
||||||
foreach ($cohortids as $cohortid) {
|
foreach ($cohortids as $cohortid) {
|
||||||
$cohort = $DB->get_record('cohort', ['id'=>$cohortid]);
|
$cohort = $DB->get_record('cohort', ['id'=>$cohortid]);
|
||||||
//\mtrace("Processing cohort {$cohortid} {$cohort->shortname}");
|
//\mtrace("Processing cohort {$cohortid} {$cohort->shortname}");.
|
||||||
|
|
||||||
$instanceparams = [
|
$instanceparams = [
|
||||||
'courseid' => $courseid,
|
'courseid' => $courseid,
|
||||||
|
@ -84,20 +105,20 @@ class cascadecohortsync {
|
||||||
'roleid' => get_config("local_treestudyplan", "csync_roleid"),
|
'roleid' => get_config("local_treestudyplan", "csync_roleid"),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Create group:
|
// Create group: .
|
||||||
|
|
||||||
// 1: check if a link exists
|
// 1: check if a link exists.
|
||||||
// If not, make it (maybe use some of the custom text to list the studyplans involved)
|
// If not, make it (maybe use some of the custom text to list the studyplans involved).
|
||||||
if ($instance = $DB->get_record('enrol', $instanceparams)) {
|
if ($instance = $DB->get_record('enrol', $instanceparams)) {
|
||||||
//\mtrace("Instance exists");
|
//\mtrace("Instance exists");.
|
||||||
// it already exists
|
// it already exists.
|
||||||
// check if this studyplan is already referenced in customtext4 in json format
|
// check if this studyplan is already referenced in customtext4 in json format.
|
||||||
|
|
||||||
//TODO: Check this code - Maybe add option to not remember manually added stuff
|
//TODO: Check this code - Maybe add option to not remember manually added stuff .
|
||||||
$plans = json_decode($instance->customtext4);
|
$plans = json_decode($instance->customtext4);
|
||||||
if ($plans == false || !is_array(($plans))) {
|
if ($plans == false || !is_array(($plans))) {
|
||||||
// If the data was not an array (null or garbled), count it as manually added
|
// If the data was not an array (null or garbled), count it as manually added.
|
||||||
// This will prevent it's deletion upon
|
// This will prevent it's deletion upon.
|
||||||
if (get_config("local_treestudyplan", "csync_remember_manual_csync")) {
|
if (get_config("local_treestudyplan", "csync_remember_manual_csync")) {
|
||||||
$plans = ["manual"];
|
$plans = ["manual"];
|
||||||
} else {
|
} else {
|
||||||
|
@ -105,61 +126,61 @@ class cascadecohortsync {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!in_array($this->studyplanid , $plans)) {
|
if (!in_array($this->studyplanid , $plans)) {
|
||||||
// if not, add it to the reference
|
// if not, add it to the reference.
|
||||||
//\mtrace("Adding this plan to the list");
|
//\mtrace("Adding this plan to the list");.
|
||||||
$plans[] = (int)($this->studyplanid);
|
$plans[] = (int)($this->studyplanid);
|
||||||
$enrol->update_instance($instance, (object)["customtext4"=>json_encode($plans)]);
|
$enrol->update_instance($instance, (object)["customtext4"=>json_encode($plans)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//\mtrace("New instance should be made");
|
//\mtrace("New instance should be made");.
|
||||||
// If method members should be added to a group, create it or get its ID.
|
// If method members should be added to a group, create it or get its ID.
|
||||||
|
|
||||||
if (get_config("local_treestudyplan", "csync_creategroup")) {
|
if (get_config("local_treestudyplan", "csync_creategroup")) {
|
||||||
// Make or get new new cohort group - but only on creating of instances
|
// Make or get new new cohort group - but only on creating of instances.
|
||||||
$groupname = $cohort->name." ".strtolower(\get_string('defaultgroupname', 'core_group'));
|
$groupname = $cohort->name." ".strtolower(\get_string('defaultgroupname', 'core_group'));
|
||||||
//\mtrace("Adding group {$groupname} for this method");
|
//\mtrace("Adding group {$groupname} for this method");.
|
||||||
// and make sure the
|
// and make sure the .
|
||||||
$instancenewparams['customint2'] = self::uploadenrolmentmethods_get_group($courseid, $groupname);
|
$instancenewparams['customint2'] = self::uploadenrolmentmethods_get_group($courseid, $groupname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($instanceid = $enrol->add_instance($course, $instancenewparams)) {
|
if ($instanceid = $enrol->add_instance($course, $instancenewparams)) {
|
||||||
// also record the (as of yet only) studyplans id requiring this association
|
// also record the (as of yet only) studyplans id requiring this association.
|
||||||
// in the customtext4 field in json format
|
// in the customtext4 field in json format.
|
||||||
//\mtrace("Instance ({$instanceid} created. Updateing instance with studyplan id");
|
//\mtrace("Instance ({$instanceid} created. Updateing instance with studyplan id");.
|
||||||
$instance = $DB->get_record('enrol', array('id' => $instanceid));
|
$instance = $DB->get_record('enrol', array('id' => $instanceid));
|
||||||
$enrol->update_instance($instance, (object)["customtext4"=>json_encode([(int)($this->studyplanid)])]);
|
$enrol->update_instance($instance, (object)["customtext4"=>json_encode([(int)($this->studyplanid)])]);
|
||||||
|
|
||||||
//\mtrace("Synchronize the enrolment");
|
//\mtrace("Synchronize the enrolment");.
|
||||||
// Successfully added a valid new instance, so now instantiate it.
|
// Successfully added a valid new instance, so now instantiate it.
|
||||||
// First synchronise the enrolment.
|
// First synchronise the enrolment.
|
||||||
$cohorttrace = new \null_progress_trace();
|
$cohorttrace = new \null_progress_trace();
|
||||||
$result = enrol_cohort_sync($cohorttrace, $cohortid);
|
$result = enrol_cohort_sync($cohorttrace, $cohortid);
|
||||||
if ($result > 0) {
|
if ($result > 0) {
|
||||||
//\mtrace("Error during 'enrol_cohort_sync': code {$result}");
|
//\mtrace("Error during 'enrol_cohort_sync': code {$result}");.
|
||||||
}
|
}
|
||||||
$cohorttrace->finished();
|
$cohorttrace->finished();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Instance not added for some reason, so report an error somewhere
|
// Instance not added for some reason, so report an error somewhere.
|
||||||
// (or not)
|
// (or not).
|
||||||
//\mtrace("Error - instance not added for some reason");
|
//\mtrace("Error - instance not added for some reason");.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 2: Check if there are cohort links for this studyplan in this course that should be removed
|
// 2: Check if there are cohort links for this studyplan in this course that should be removed.
|
||||||
// A: Check if there are cohort links that are no longer related to this studyplan
|
// A: Check if there are cohort links that are no longer related to this studyplan.
|
||||||
// B: Check if these links are valid through another studyplan...
|
// B: Check if these links are valid through another studyplan...
|
||||||
// If no one uses the link anymore, deactivate it...
|
// If no one uses the link anymore, deactivate it...
|
||||||
// INFO: This does not remove the sync from courses that are unlinked from a studplan. But maybe we do not want that anyway
|
// INFO: This does not remove the sync from courses that are unlinked from a studplan. But maybe we do not want that anyway.
|
||||||
// since it is generally a good idea to keep student access to courses available
|
// since it is generally a good idea to keep student access to courses available .
|
||||||
|
|
||||||
if (get_config("local_treestudyplan", "csync_autoremove")) {
|
if (get_config("local_treestudyplan", "csync_autoremove")) {
|
||||||
// Only try the autoremove if the option is enabled
|
// Only try the autoremove if the option is enabled.
|
||||||
//\mtrace("Autoremove scan for course {$courseid} {$course->shortname}");
|
//\mtrace("Autoremove scan for course {$courseid} {$course->shortname}");.
|
||||||
// find all cohort syncs for this course
|
// find all cohort syncs for this course.
|
||||||
$searchparams = [
|
$searchparams = [
|
||||||
'courseid' => $courseid,
|
'courseid' => $courseid,
|
||||||
'enrol' => self::METHOD,
|
'enrol' => self::METHOD,
|
||||||
|
@ -168,27 +189,27 @@ class cascadecohortsync {
|
||||||
|
|
||||||
$records = $DB->get_records("enrol", $searchparams);
|
$records = $DB->get_records("enrol", $searchparams);
|
||||||
foreach ($records as $instance) {
|
foreach ($records as $instance) {
|
||||||
if(!empty($instance->customtext4)){ // only check the records that have studyplan information in the customtext4 field
|
if (!empty($instance->customtext4)) { // only check the records that have studyplan information in the customtext4 field.
|
||||||
// first check if the cohort is not one of the cohort id's we have associated
|
// first check if the cohort is not one of the cohort id's we have associated.
|
||||||
if (!in_array($instance->customint1, $cohortids)) {
|
if (!in_array($instance->customint1, $cohortids)) {
|
||||||
//\mtrace("Found cohort sync instance that is not currently liked to the studyplan: {$instance->id}");
|
//\mtrace("Found cohort sync instance that is not currently liked to the studyplan: {$instance->id}");.
|
||||||
// So it may or may not need to be removed
|
// So it may or may not need to be removed.
|
||||||
$plans = json_decode($instance->customtext4);
|
$plans = json_decode($instance->customtext4);
|
||||||
if ($plans !== null && is_array($plans)) {
|
if ($plans !== null && is_array($plans)) {
|
||||||
//if a valid array is not returned, better leave it be, we don't want to mess with it
|
//if a valid array is not returned, better leave it be, we don't want to mess with it.
|
||||||
// otherwise, check if we should remove it
|
// otherwise, check if we should remove it.
|
||||||
if (in_array($this->studyplanid, $plans)) {
|
if (in_array($this->studyplanid, $plans)) {
|
||||||
//\mtrace("Found this studyplan in the id list - removing from list");
|
//\mtrace("Found this studyplan in the id list - removing from list");.
|
||||||
//if this plan was referenced before
|
//if this plan was referenced before.
|
||||||
// first remove the link
|
// first remove the link.
|
||||||
$fplans = self::array_remove_value($plans, $this->studyplanid);
|
$fplans = self::array_remove_value($plans, $this->studyplanid);
|
||||||
if (count($fplans) == 0) {
|
if (count($fplans) == 0) {
|
||||||
// delete the sync if there are no studyplan references left
|
// delete the sync if there are no studyplan references left.
|
||||||
//\mtrace("No references are left, removing instance");
|
//\mtrace("No references are left, removing instance");.
|
||||||
$enrol->delete_instance($instance);
|
$enrol->delete_instance($instance);
|
||||||
} else {
|
} else {
|
||||||
// otherwise just update the references so this studyplan is no longer linked
|
// otherwise just update the references so this studyplan is no longer linked.
|
||||||
//\mtrace("Still references left in the list, updating list...");
|
//\mtrace("Still references left in the list, updating list...");.
|
||||||
$enrol->update_instance($instance, (object)["customtext4"=>json_encode($fplans)]);
|
$enrol->update_instance($instance, (object)["customtext4"=>json_encode($fplans)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,6 +219,6 @@ class cascadecohortsync {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//\mtrace("Cascading complete");
|
//\mtrace("Cascading complete");.
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
|
||||||
|
@ -25,26 +46,26 @@ class cascadeusersync {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$enrol = \enrol_get_plugin(self::METHOD);
|
$enrol = \enrol_get_plugin(self::METHOD);
|
||||||
// Find the courses that need to be synced to the associated cohorts
|
// Find the courses that need to be synced to the associated cohorts.
|
||||||
$courseids = $this->studyplan->get_linked_course_ids();
|
$courseids = $this->studyplan->get_linked_course_ids();
|
||||||
// And find the users that are linked to this studyplan.
|
// And find the users that are linked to this studyplan.
|
||||||
$userids = $this->studyplan->get_linked_user_ids();
|
$userids = $this->studyplan->get_linked_user_ids();
|
||||||
// Get the roleid to use for synchronizations
|
// Get the roleid to use for synchronizations.
|
||||||
$roleid = get_config("local_treestudyplan", "csync_roleid");
|
$roleid = get_config("local_treestudyplan", "csync_roleid");
|
||||||
|
|
||||||
// Next, for each course that is linked:
|
// Next, for each course that is linked:.
|
||||||
foreach ($courseids as $courseid) {
|
foreach ($courseids as $courseid) {
|
||||||
$course = \get_course($courseid);
|
$course = \get_course($courseid);
|
||||||
if (count($userids) > 0) {
|
if (count($userids) > 0) {
|
||||||
// Get the manual enrol instance for this course
|
// Get the manual enrol instance for this course.
|
||||||
$instanceparams = ['courseid' => $courseid, 'enrol' => 'manual'];
|
$instanceparams = ['courseid' => $courseid, 'enrol' => 'manual'];
|
||||||
if (!($instance = $DB->get_record('enrol', $instanceparams))) {
|
if (!($instance = $DB->get_record('enrol', $instanceparams))) {
|
||||||
if ($instanceid = $enrol->add_default_instance($course)) {
|
if ($instanceid = $enrol->add_default_instance($course)) {
|
||||||
$instance = $DB->get_record('enrol', array('id' => $instanceid));
|
$instance = $DB->get_record('enrol', array('id' => $instanceid));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Instance not added for some reason, so report an error somewhere
|
// Instance not added for some reason, so report an error somewhere.
|
||||||
// (or not)
|
// (or not).
|
||||||
$instance = null;
|
$instance = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +78,7 @@ class cascadeusersync {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// We do not do any autoremoval for user syncs, to avoid students losing access to the course data
|
// We do not do any autoremoval for user syncs, to avoid students losing access to the course data.
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
@ -37,13 +57,13 @@ class completion {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function count_states(array $states) {
|
public static function count_states(array $states) {
|
||||||
// initialize result array
|
// initialize result array.
|
||||||
$statecount = [];
|
$statecount = [];
|
||||||
foreach (array_keys(self::LABELS) as $key) {
|
foreach (array_keys(self::LABELS) as $key) {
|
||||||
$statecount[$key] = 0;
|
$statecount[$key] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// process all states in array and increment relevant counter for each one
|
// process all states in array and increment relevant counter for each one.
|
||||||
foreach ($states as $c) {
|
foreach ($states as $c) {
|
||||||
if (array_key_exists($c, $statecount)) {
|
if (array_key_exists($c, $statecount)) {
|
||||||
$statecount[$c] += 1;
|
$statecount[$c] += 1;
|
||||||
|
|
|
@ -1,4 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
@ -44,18 +64,16 @@ class completionscanner
|
||||||
|
|
||||||
$this->completioninfo = new \completion_info($course);
|
$this->completioninfo = new \completion_info($course);
|
||||||
|
|
||||||
// Find a related scanner if the type is an activity type
|
// Find a related scanner if the type is an activity type.
|
||||||
if ($crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
|
if ($crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
|
||||||
// First find the course module
|
// First find the course module.
|
||||||
$this->cm = $this->modinfo->get_cm($crit->moduleinstance);
|
$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]);
|
$gi = grade_item::fetch(['itemtype' => 'mod', 'itemmodule' => $this->cm->modname, 'iteminstance' => $this->cm->instance, 'courseid' => $this->courseid]);
|
||||||
if($gi !== false)
|
if ($gi !== false) {
|
||||||
{
|
// Grade none items should not be relevant.
|
||||||
// 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.
|
||||||
// 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(($gi->gradetype == GRADE_TYPE_VALUE || $gi->gradetype == GRADE_TYPE_SCALE))
|
// If it's a relevant grade type, initialize a scanner if possible.
|
||||||
{
|
|
||||||
// If it's a relevant grade type, initialize a scanner if possible
|
|
||||||
$this->gi = $gi;
|
$this->gi = $gi;
|
||||||
if (self::supported($gi->itemmodule)) {
|
if (self::supported($gi->itemmodule)) {
|
||||||
$scannerclass = "\local_treestudyplan\\local\ungradedscanners\\{$gi->itemmodule}_scanner";
|
$scannerclass = "\local_treestudyplan\\local\ungradedscanners\\{$gi->itemmodule}_scanner";
|
||||||
|
@ -91,7 +109,7 @@ class completionscanner
|
||||||
|
|
||||||
public function model() {
|
public function model() {
|
||||||
|
|
||||||
// get completion info
|
// get completion info.
|
||||||
$students = self::get_course_students($this->courseid);
|
$students = self::get_course_students($this->courseid);
|
||||||
$completed = 0;
|
$completed = 0;
|
||||||
$ungraded = 0;
|
$ungraded = 0;
|
||||||
|
@ -99,13 +117,13 @@ class completionscanner
|
||||||
$completed_fail = 0;
|
$completed_fail = 0;
|
||||||
foreach ($students as $userid) {
|
foreach ($students as $userid) {
|
||||||
if ($this->pending($userid)) {
|
if ($this->pending($userid)) {
|
||||||
// First check if the completion needs grading
|
// First check if the completion needs grading.
|
||||||
$ungraded++;
|
$ungraded++;
|
||||||
} else {
|
} else {
|
||||||
$completion = $this->completioninfo->get_user_completion($userid, $this->crit);
|
$completion = $this->completioninfo->get_user_completion($userid, $this->crit);
|
||||||
|
|
||||||
if ($this->crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
|
if ($this->crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
|
||||||
// If it's an activity completion, add all the relevant activities as sub-items
|
// If it's an activity completion, add all the relevant activities as sub-items.
|
||||||
$completion_status = $this->completioninfo->get_grade_completion($this->cm, $userid);
|
$completion_status = $this->completioninfo->get_grade_completion($this->cm, $userid);
|
||||||
|
|
||||||
if ($completion_status == COMPLETION_COMPLETE_PASS) {
|
if ($completion_status == COMPLETION_COMPLETE_PASS) {
|
||||||
|
|
|
@ -1,4 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
@ -29,7 +49,7 @@ class corecompletioninfo {
|
||||||
|
|
||||||
static public function completiontypes() {
|
static public function completiontypes() {
|
||||||
global $COMPLETION_CRITERIA_TYPES;
|
global $COMPLETION_CRITERIA_TYPES;
|
||||||
// Just return the keys of the global array COMPLETION_CRITERIA_TYPES, so we don't have to manually
|
// Just return the keys of the global array COMPLETION_CRITERIA_TYPES, so we don't have to manually.
|
||||||
// add any completion types....
|
// add any completion types....
|
||||||
return \array_keys($COMPLETION_CRITERIA_TYPES);
|
return \array_keys($COMPLETION_CRITERIA_TYPES);
|
||||||
}
|
}
|
||||||
|
@ -40,13 +60,13 @@ class corecompletioninfo {
|
||||||
*/
|
*/
|
||||||
static public function completion_handle($completion) {
|
static public function completion_handle($completion) {
|
||||||
if (empty(self::$COMPLETION_HANDLES)) {
|
if (empty(self::$COMPLETION_HANDLES)) {
|
||||||
// Cache the translation table, to avoid overhead
|
// Cache the translation table, to avoid overhead.
|
||||||
self::$COMPLETION_HANDLES = [
|
self::$COMPLETION_HANDLES = [
|
||||||
COMPLETION_INCOMPLETE => "incomplete",
|
COMPLETION_INCOMPLETE => "incomplete",
|
||||||
COMPLETION_COMPLETE => "complete",
|
COMPLETION_COMPLETE => "complete",
|
||||||
COMPLETION_COMPLETE_PASS => "complete-pass",
|
COMPLETION_COMPLETE_PASS => "complete-pass",
|
||||||
COMPLETION_COMPLETE_FAIL => "complete-fail",
|
COMPLETION_COMPLETE_FAIL => "complete-fail",
|
||||||
COMPLETION_COMPLETE_FAIL_HIDDEN => "complete-fail"]; // the front end won't differentiate between hidden or not
|
COMPLETION_COMPLETE_FAIL_HIDDEN => "complete-fail"]; // the front end won't differentiate between hidden or not.
|
||||||
}
|
}
|
||||||
return self::$COMPLETION_HANDLES[$completion] ?? "undefined";
|
return self::$COMPLETION_HANDLES[$completion] ?? "undefined";
|
||||||
}
|
}
|
||||||
|
@ -138,21 +158,20 @@ class corecompletioninfo {
|
||||||
global $DB, $CFG, $COMPLETION_CRITERIA_TYPES;
|
global $DB, $CFG, $COMPLETION_CRITERIA_TYPES;
|
||||||
|
|
||||||
$conditions = [];
|
$conditions = [];
|
||||||
$aggregation = "all"; // default
|
$aggregation = "all"; // default.
|
||||||
$info = [
|
$info = [
|
||||||
"conditions" => $conditions,
|
"conditions" => $conditions,
|
||||||
"aggregation" => self::aggregation_handle($this->completion->get_aggregation_method()),
|
"aggregation" => self::aggregation_handle($this->completion->get_aggregation_method()),
|
||||||
"enabled" => $this->completion->is_enabled()
|
"enabled" => $this->completion->is_enabled()
|
||||||
];
|
];
|
||||||
|
|
||||||
// Check if completion tracking is enabled for this course - otherwise, revert to defaults
|
// Check if completion tracking is enabled for this course - otherwise, revert to defaults .
|
||||||
if($this->completion->is_enabled())
|
if ($this->completion->is_enabled()) {
|
||||||
{
|
|
||||||
$aggregation = $this->completion->get_aggregation_method();
|
$aggregation = $this->completion->get_aggregation_method();
|
||||||
// Loop through all condition types to see if they are applicable
|
// Loop through all condition types to see if they are applicable.
|
||||||
foreach (self::completiontypes() as $type) {
|
foreach (self::completiontypes() as $type) {
|
||||||
$criterias = $this->completion->get_criteria($type); // Returns array of relevant criteria items
|
$criterias = $this->completion->get_criteria($type); // Returns array of relevant criteria items.
|
||||||
if(count($criterias) > 0 ) // Only take it into account if the criteria count is > 0
|
if (count($criterias) > 0 ) // Only take it into account if the criteria count is > 0.
|
||||||
{
|
{
|
||||||
$cinfo = [
|
$cinfo = [
|
||||||
"type" => $COMPLETION_CRITERIA_TYPES[$type],
|
"type" => $COMPLETION_CRITERIA_TYPES[$type],
|
||||||
|
@ -162,10 +181,10 @@ class corecompletioninfo {
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($criterias as $criteria) {
|
foreach ($criterias as $criteria) {
|
||||||
// Unfortunately, we cannot easily get the criteria details with get_details() without having a
|
// Unfortunately, we cannot easily get the criteria details with get_details() without having a .
|
||||||
// user completion object involved, so'we'll have to retrieve the details per completion type
|
// user completion object involved, so'we'll have to retrieve the details per completion type.
|
||||||
// See moodle/completion/criteria/completion_criteria_*.php::get_details() for the code that is
|
// See moodle/completion/criteria/completion_criteria_*.php::get_details() for the code that is.
|
||||||
// in the code below is based on
|
// in the code below is based on.
|
||||||
|
|
||||||
if ($type == COMPLETION_CRITERIA_TYPE_SELF) {
|
if ($type == COMPLETION_CRITERIA_TYPE_SELF) {
|
||||||
$details = [
|
$details = [
|
||||||
|
@ -195,8 +214,8 @@ class corecompletioninfo {
|
||||||
$cm = $this->modinfo->get_cm($criteria->moduleinstance);
|
$cm = $this->modinfo->get_cm($criteria->moduleinstance);
|
||||||
$details = [
|
$details = [
|
||||||
"type" => $criteria->get_title(),
|
"type" => $criteria->get_title(),
|
||||||
"criteria" => "", // Will be built in a moment by code copied from completion_criteria_activity.php
|
"criteria" => "", // Will be built in a moment by code copied from completion_criteria_activity.php.
|
||||||
"requirement" => "", // Will be built momentarily by code copied from completion_criteria_activity.php
|
"requirement" => "", // Will be built momentarily by code copied from completion_criteria_activity.php.
|
||||||
"status" => "",
|
"status" => "",
|
||||||
];
|
];
|
||||||
if ($cm->has_view()) {
|
if ($cm->has_view()) {
|
||||||
|
@ -204,7 +223,7 @@ class corecompletioninfo {
|
||||||
} else {
|
} else {
|
||||||
$details['criteria'] = $cm->get_formatted_name();
|
$details['criteria'] = $cm->get_formatted_name();
|
||||||
}
|
}
|
||||||
// Build requirements
|
// Build requirements.
|
||||||
$details['requirement'] = array();
|
$details['requirement'] = array();
|
||||||
|
|
||||||
if ($cm->completion == COMPLETION_TRACKING_MANUAL) {
|
if ($cm->completion == COMPLETION_TRACKING_MANUAL) {
|
||||||
|
@ -239,7 +258,7 @@ class corecompletioninfo {
|
||||||
$details = [
|
$details = [
|
||||||
"type" => get_string('coursegrade', 'completion'),
|
"type" => get_string('coursegrade', 'completion'),
|
||||||
"criteria" => get_string('graderequired', 'completion'),
|
"criteria" => get_string('graderequired', 'completion'),
|
||||||
// TODO: convert to selected representation (letter, percentage, etc)
|
// TODO: convert to selected representation (letter, percentage, etc).
|
||||||
"requirement" => get_string('graderequired', 'completion').": ".format_float($criteria->gradepass, 1),
|
"requirement" => get_string('graderequired', 'completion').": ".format_float($criteria->gradepass, 1),
|
||||||
"status" => "",
|
"status" => "",
|
||||||
];
|
];
|
||||||
|
@ -265,7 +284,7 @@ class corecompletioninfo {
|
||||||
"status" => "",
|
"status" => "",
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
// Moodle added a criteria type
|
// Moodle added a criteria type.
|
||||||
$details = [
|
$details = [
|
||||||
"type" => "",
|
"type" => "",
|
||||||
"criteria" => "",
|
"criteria" => "",
|
||||||
|
@ -307,7 +326,7 @@ class corecompletioninfo {
|
||||||
if ($typeaggregation == COMPLETION_AGGREGATION_ALL) {
|
if ($typeaggregation == COMPLETION_AGGREGATION_ALL) {
|
||||||
return $completed >= $count;
|
return $completed >= $count;
|
||||||
}
|
}
|
||||||
else { // COMPLETION_AGGREGATION_ANY
|
else { // COMPLETION_AGGREGATION_ANY.
|
||||||
return $completed > 1;
|
return $completed > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,13 +346,12 @@ class corecompletioninfo {
|
||||||
"tracked" => $this->completion->is_tracked_user($userid),
|
"tracked" => $this->completion->is_tracked_user($userid),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Check if completion tracking is enabled for this course - otherwise, revert to defaults
|
// Check if completion tracking is enabled for this course - otherwise, revert to defaults .
|
||||||
if($this->completion->is_enabled() && $this->completion->is_tracked_user($userid))
|
if ($this->completion->is_enabled() && $this->completion->is_tracked_user($userid)) {
|
||||||
{
|
|
||||||
$anypending = false;
|
$anypending = false;
|
||||||
// Loop through all conditions to see if they are applicable
|
// Loop through all conditions to see if they are applicable.
|
||||||
foreach (self::completiontypes() as $type) {
|
foreach (self::completiontypes() as $type) {
|
||||||
// Get the main completion for this type
|
// Get the main completion for this type.
|
||||||
$completions = $this->completion->get_completions($userid, $type);
|
$completions = $this->completion->get_completions($userid, $type);
|
||||||
if (count($completions) > 0) {
|
if (count($completions) > 0) {
|
||||||
$typeaggregation = $this->completion->get_aggregation_method($type);
|
$typeaggregation = $this->completion->get_aggregation_method($type);
|
||||||
|
@ -352,32 +370,32 @@ class corecompletioninfo {
|
||||||
$criteria = $completion->get_criteria();
|
$criteria = $completion->get_criteria();
|
||||||
|
|
||||||
if ($completion->is_complete()) {
|
if ($completion->is_complete()) {
|
||||||
$progress += 1; // Add a point to the progress counter
|
$progress += 1; // Add a point to the progress counter.
|
||||||
}
|
}
|
||||||
|
|
||||||
$iinfo = [
|
$iinfo = [
|
||||||
"id" => $criteria->id,
|
"id" => $criteria->id,
|
||||||
"title" => $criteria->get_title_detailed(),
|
"title" => $criteria->get_title_detailed(),
|
||||||
"details" => $criteria->get_details($completion),
|
"details" => $criteria->get_details($completion),
|
||||||
"completed" => $completion->is_complete(), // Make sure to override for activi
|
"completed" => $completion->is_complete(), // Make sure to override for activi.
|
||||||
"status" => self::completion_handle($completion->is_complete()?COMPLETION_COMPLETE:COMPLETION_INCOMPLETE),
|
"status" => self::completion_handle($completion->is_complete()?COMPLETION_COMPLETE:COMPLETION_INCOMPLETE),
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($type == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
|
if ($type == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
|
||||||
$cm = $this->modinfo->get_cm($criteria->moduleinstance);
|
$cm = $this->modinfo->get_cm($criteria->moduleinstance);
|
||||||
// If it's an activity completion, add all the relevant activities as sub-items
|
// If it's an activity completion, add all the relevant activities as sub-items.
|
||||||
$completion_status = $this->completion->get_grade_completion($cm, $userid);
|
$completion_status = $this->completion->get_grade_completion($cm, $userid);
|
||||||
$iinfo['status'] = self::completion_handle($completion_status);
|
$iinfo['status'] = self::completion_handle($completion_status);
|
||||||
// Re-evaluate the completed value, to make sure COMPLETE_FAIL doesn't creep in as completed
|
// Re-evaluate the completed value, to make sure COMPLETE_FAIL doesn't creep in as completed.
|
||||||
$iinfo['completed'] = in_array($completion_status, [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS]);
|
$iinfo['completed'] = in_array($completion_status, [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS]);
|
||||||
// Determine the grade (retrieve from grade item, not from completion)
|
// Determine the grade (retrieve from grade item, not from completion).
|
||||||
$grade = $this->get_grade($cm, $userid);
|
$grade = $this->get_grade($cm, $userid);
|
||||||
$iinfo['grade'] = $grade->grade;
|
$iinfo['grade'] = $grade->grade;
|
||||||
$iinfo['feedback'] = $grade->feedback;
|
$iinfo['feedback'] = $grade->feedback;
|
||||||
$iinfo['pending'] = $grade->pending;
|
$iinfo['pending'] = $grade->pending;
|
||||||
|
|
||||||
$anypending = $anypending || $grade->pending;
|
$anypending = $anypending || $grade->pending;
|
||||||
// Overwrite the status with progress if something has been graded, or is pending
|
// Overwrite the status with progress if something has been graded, or is pending.
|
||||||
if ($completion_status != COMPLETION_INCOMPLETE || $anypending) {
|
if ($completion_status != COMPLETION_INCOMPLETE || $anypending) {
|
||||||
if ($cinfo["status"] == "incomplete") {
|
if ($cinfo["status"] == "incomplete") {
|
||||||
$cinfo["status"] = "progress";
|
$cinfo["status"] = "progress";
|
||||||
|
@ -386,7 +404,7 @@ class corecompletioninfo {
|
||||||
|
|
||||||
}
|
}
|
||||||
else if ($type == COMPLETION_CRITERIA_TYPE_GRADE) {
|
else if ($type == COMPLETION_CRITERIA_TYPE_GRADE) {
|
||||||
// Make sure we provide the current course grade
|
// Make sure we provide the current course grade.
|
||||||
$iinfo['grade'] = floatval($iinfo['details']['status']);
|
$iinfo['grade'] = floatval($iinfo['details']['status']);
|
||||||
if ($iinfo["grade"] > 0) {
|
if ($iinfo["grade"] > 0) {
|
||||||
$iinfo["grade"] = format_float($iinfo["grade"], 1). "/".format_float(floatval($iinfo['details']['requirement']));
|
$iinfo["grade"] = format_float($iinfo["grade"], 1). "/".format_float(floatval($iinfo['details']['requirement']));
|
||||||
|
@ -396,19 +414,19 @@ class corecompletioninfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// finally add the item to the items list
|
// finally add the item to the items list.
|
||||||
$cinfo["items"][] = $iinfo;
|
$cinfo["items"][] = $iinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the count and progress stats based on the Type's aggregation style
|
// Set the count and progress stats based on the Type's aggregation style.
|
||||||
if ($typeaggregation == COMPLETION_AGGREGATION_ALL) {
|
if ($typeaggregation == COMPLETION_AGGREGATION_ALL) {
|
||||||
// Count and Progress amount to the sum of items
|
// Count and Progress amount to the sum of items.
|
||||||
$cinfo["count"] = count($cinfo["items"]);
|
$cinfo["count"] = count($cinfo["items"]);
|
||||||
$cinfo["progress"] = $progress;
|
$cinfo["progress"] = $progress;
|
||||||
}
|
}
|
||||||
else { //$typeaggregation == COMPLETION_AGGREGATION_ANY
|
else { //$typeaggregation == COMPLETION_AGGREGATION_ANY.
|
||||||
// Count and progress are either 1 or 0, since any of the items
|
// Count and progress are either 1 or 0, since any of the items.
|
||||||
// complete's the type
|
// complete's the type.
|
||||||
$cinfo["count"] = (count($cinfo["items"]) > 0)?1:0;
|
$cinfo["count"] = (count($cinfo["items"]) > 0)?1:0;
|
||||||
$cinfo["progress"] = ($progress>0)?1:0;
|
$cinfo["progress"] = ($progress>0)?1:0;
|
||||||
}
|
}
|
||||||
|
@ -427,32 +445,30 @@ class corecompletioninfo {
|
||||||
* @return stdClass|null object containing 'grade' and optional 'feedback' attribute
|
* @return stdClass|null object containing 'grade' and optional 'feedback' attribute
|
||||||
*/
|
*/
|
||||||
private function get_grade($cm, $userid) {
|
private function get_grade($cm, $userid) {
|
||||||
// TODO: Display grade in the way described in the course setup (with letters if needed)
|
// TODO: Display grade in the way described in the course setup (with letters if needed).
|
||||||
|
|
||||||
$gi= grade_item::fetch(['itemtype' => 'mod',
|
$gi= grade_item::fetch(['itemtype' => 'mod',
|
||||||
'itemmodule' => $cm->modname,
|
'itemmodule' => $cm->modname,
|
||||||
'iteminstance' => $cm->instance,
|
'iteminstance' => $cm->instance,
|
||||||
'courseid' => $this->course->id]); // Make sure we only get results relevant to this course
|
'courseid' => $this->course->id]); // Make sure we only get results relevant to this course.
|
||||||
|
|
||||||
if($gi)
|
if ($gi) {
|
||||||
{
|
// Only the following types of grade yield a result.
|
||||||
// Only the following types of grade yield a result
|
if (($gi->gradetype == GRADE_TYPE_VALUE || $gi->gradetype == GRADE_TYPE_SCALE)) {
|
||||||
if(($gi->gradetype == GRADE_TYPE_VALUE || $gi->gradetype == GRADE_TYPE_SCALE))
|
|
||||||
{
|
|
||||||
$scale = $gi->load_scale();
|
$scale = $gi->load_scale();
|
||||||
|
|
||||||
$grade = (object)$gi->get_final($userid); // Get the grade for the specified user
|
$grade = (object)$gi->get_final($userid); // Get the grade for the specified user.
|
||||||
$result = new \stdClass;
|
$result = new \stdClass;
|
||||||
// Check if the final grade is available and numeric (safety check)
|
// Check if the final grade is available and numeric (safety check).
|
||||||
if (!empty($grade) && !empty($grade->finalgrade) && is_numeric($grade->finalgrade)) {
|
if (!empty($grade) && !empty($grade->finalgrade) && is_numeric($grade->finalgrade)) {
|
||||||
// convert scale grades to corresponding scale name
|
// convert scale grades to corresponding scale name.
|
||||||
if (isset($scale)) {
|
if (isset($scale)) {
|
||||||
// get scale value
|
// get scale value.
|
||||||
$result->grade = $scale->get_nearest_item($grade->finalgrade);
|
$result->grade = $scale->get_nearest_item($grade->finalgrade);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// round final grade to 1 decimal point
|
// round final grade to 1 decimal point.
|
||||||
$result->grade = round($grade->finalgrade, 1);
|
$result->grade = round($grade->finalgrade, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +476,7 @@ class corecompletioninfo {
|
||||||
$result->pending = (new gradingscanner($gi))->pending($userid);
|
$result->pending = (new gradingscanner($gi))->pending($userid);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$result->grade = "-"; // Activity is gradable, but user did not receive a grade yet
|
$result->grade = "-"; // Activity is gradable, but user did not receive a grade yet.
|
||||||
$result->feedback = null;
|
$result->feedback = null;
|
||||||
$result->pending = false;
|
$result->pending = false;
|
||||||
}
|
}
|
||||||
|
@ -468,7 +484,7 @@ class corecompletioninfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null; // Activity cannot be graded (Shouldn't be happening, but still....)
|
return null; // Activity cannot be graded (Shouldn't be happening, but still....).
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -476,38 +492,36 @@ class corecompletioninfo {
|
||||||
* @return stdClass|null object containing 'grade' and optional 'feedback' attribute
|
* @return stdClass|null object containing 'grade' and optional 'feedback' attribute
|
||||||
*/
|
*/
|
||||||
private function get_course_grade($userid) {
|
private function get_course_grade($userid) {
|
||||||
// TODO: Display grade in the way described in the course setup (with letters if needed)
|
// TODO: Display grade in the way described in the course setup (with letters if needed).
|
||||||
$gi= grade_item::fetch(['itemtype' => 'course',
|
$gi= grade_item::fetch(['itemtype' => 'course',
|
||||||
'iteminstance' => $this->course->id,
|
'iteminstance' => $this->course->id,
|
||||||
'courseid' => $this->course->id]);
|
'courseid' => $this->course->id]);
|
||||||
|
|
||||||
if($gi)
|
if ($gi) {
|
||||||
{
|
// Only the following types of grade yield a result.
|
||||||
// Only the following types of grade yield a result
|
if (($gi->gradetype == GRADE_TYPE_VALUE || $gi->gradetype == GRADE_TYPE_SCALE)) {
|
||||||
if(($gi->gradetype == GRADE_TYPE_VALUE || $gi->gradetype == GRADE_TYPE_SCALE))
|
|
||||||
{
|
|
||||||
$scale = $gi->load_scale();
|
$scale = $gi->load_scale();
|
||||||
$grade = $gi->get_final($userid); // Get the grade for the specified user
|
$grade = $gi->get_final($userid); // Get the grade for the specified user.
|
||||||
// Check if the final grade is available and numeric (safety check)
|
// Check if the final grade is available and numeric (safety check).
|
||||||
if (!empty($grade) && !empty($grade->finalgrade) && is_numeric($grade->finalgrade)) {
|
if (!empty($grade) && !empty($grade->finalgrade) && is_numeric($grade->finalgrade)) {
|
||||||
// convert scale grades to corresponding scale name
|
// convert scale grades to corresponding scale name.
|
||||||
if (isset($scale)) {
|
if (isset($scale)) {
|
||||||
// get scale value
|
// get scale value.
|
||||||
return $scale->get_nearest_item($grade->finalgrade);
|
return $scale->get_nearest_item($grade->finalgrade);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// round final grade to 1 decimal point
|
// round final grade to 1 decimal point.
|
||||||
return round($grade->finalgrade, 1);
|
return round($grade->finalgrade, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return "-"; // User did not receive a grade yet for this course
|
return "-"; // User did not receive a grade yet for this course.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null; // Course cannot be graded (Shouldn't be happening, but still....)
|
return null; // Course cannot be graded (Shouldn't be happening, but still....).
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -534,18 +548,18 @@ class corecompletioninfo {
|
||||||
$count = count($completions);
|
$count = count($completions);
|
||||||
$completed = 0;
|
$completed = 0;
|
||||||
|
|
||||||
// Before we check how many modules have been completed see if the course has completed.
|
// Before we check how many modules have been completed see if the course has completed. .
|
||||||
if ($this->completion->is_course_complete($userid)) {
|
if ($this->completion->is_course_complete($userid)) {
|
||||||
$completed = $count;
|
$completed = $count;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// count all completions, but treat
|
// count all completions, but treat .
|
||||||
foreach ($completions as $completion) {
|
foreach ($completions as $completion) {
|
||||||
$crit = $completion->get_criteria();
|
$crit = $completion->get_criteria();
|
||||||
if ($crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
|
if ($crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
|
||||||
// get the cm data object
|
// get the cm data object.
|
||||||
$cm = $this->modinfo->get_cm($crit->moduleinstance);
|
$cm = $this->modinfo->get_cm($crit->moduleinstance);
|
||||||
// retrieve data for this object
|
// retrieve data for this object.
|
||||||
$data = $this->completion->get_data($cm, false, $userid);
|
$data = $this->completion->get_data($cm, false, $userid);
|
||||||
// Count complete, but failed as incomplete too...
|
// Count complete, but failed as incomplete too...
|
||||||
if (($data->completionstate == COMPLETION_INCOMPLETE) || ($data->completionstate == COMPLETION_COMPLETE_FAIL)) {
|
if (($data->completionstate == COMPLETION_INCOMPLETE) || ($data->completionstate == COMPLETION_COMPLETE_FAIL)) {
|
||||||
|
@ -591,12 +605,12 @@ class corecompletioninfo {
|
||||||
$aggregation = $this->completion->get_aggregation_method();
|
$aggregation = $this->completion->get_aggregation_method();
|
||||||
$critcount = [];
|
$critcount = [];
|
||||||
|
|
||||||
// Before we check how many modules have been completed see if the course has completed.
|
// Before we check how many modules have been completed see if the course has completed. .
|
||||||
// count all completions, but treat
|
// count all completions, but treat .
|
||||||
foreach ($completions as $completion) {
|
foreach ($completions as $completion) {
|
||||||
$crit = $completion->get_criteria();
|
$crit = $completion->get_criteria();
|
||||||
|
|
||||||
// Make a new object for the type if it's not already there
|
// Make a new object for the type if it's not already there.
|
||||||
$type = $crit->criteriatype;
|
$type = $crit->criteriatype;
|
||||||
if (!array_key_exists($type, $critcount)) {
|
if (!array_key_exists($type, $critcount)) {
|
||||||
$critcount[$type] = new \stdClass;
|
$critcount[$type] = new \stdClass;
|
||||||
|
@ -604,14 +618,14 @@ class corecompletioninfo {
|
||||||
$critcount[$type]->completed = 0;
|
$critcount[$type]->completed = 0;
|
||||||
$critcount[$type]->aggregation = $this->completion->get_aggregation_method($type);
|
$critcount[$type]->aggregation = $this->completion->get_aggregation_method($type);
|
||||||
}
|
}
|
||||||
// Get a reference to the counter object for this type
|
// Get a reference to the counter object for this type.
|
||||||
$typecount =& $critcount[$type];
|
$typecount =& $critcount[$type];
|
||||||
|
|
||||||
$typecount->count += 1;
|
$typecount->count += 1;
|
||||||
if ($crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
|
if ($crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
|
||||||
// get the cm data object
|
// get the cm data object.
|
||||||
$cm = $this->modinfo->get_cm($crit->moduleinstance);
|
$cm = $this->modinfo->get_cm($crit->moduleinstance);
|
||||||
// retrieve data for this object
|
// retrieve data for this object.
|
||||||
$data = $this->completion->get_data($cm, false, $userid);
|
$data = $this->completion->get_data($cm, false, $userid);
|
||||||
// Count complete, but failed as incomplete too...
|
// Count complete, but failed as incomplete too...
|
||||||
if (($data->completionstate == COMPLETION_INCOMPLETE) || ($data->completionstate == COMPLETION_COMPLETE_FAIL)) {
|
if (($data->completionstate == COMPLETION_INCOMPLETE) || ($data->completionstate == COMPLETION_COMPLETE_FAIL)) {
|
||||||
|
@ -627,15 +641,15 @@ class corecompletioninfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that we have all completions sorted by type, we can be smart about how to do the count
|
// Now that we have all completions sorted by type, we can be smart about how to do the count.
|
||||||
$count = 0;
|
$count = 0;
|
||||||
$completed = 0;
|
$completed = 0;
|
||||||
$completion_percentage = 0;
|
$completion_percentage = 0;
|
||||||
foreach ($critcount as $c) {
|
foreach ($critcount as $c) {
|
||||||
// Take only types that are actually present into account
|
// Take only types that are actually present into account.
|
||||||
if ($c->count > 0) {
|
if ($c->count > 0) {
|
||||||
// If the aggregation for the type is ANY, reduce the count to 1 for this type
|
// If the aggregation for the type is ANY, reduce the count to 1 for this type.
|
||||||
// And adjust the progress accordingly (check if any have been completed or not)
|
// And adjust the progress accordingly (check if any have been completed or not).
|
||||||
if ($c->aggregation == COMPLETION_AGGREGATION_ALL) {
|
if ($c->aggregation == COMPLETION_AGGREGATION_ALL) {
|
||||||
$ct = $c->count;
|
$ct = $c->count;
|
||||||
$cmpl = $c->completed;
|
$cmpl = $c->completed;
|
||||||
|
@ -644,8 +658,8 @@ class corecompletioninfo {
|
||||||
$ct = 1;
|
$ct = 1;
|
||||||
$cmpl = ($c->completed > 0)?1:0;
|
$cmpl = ($c->completed > 0)?1:0;
|
||||||
}
|
}
|
||||||
// if ANY completion for the types, count only the criteria type with the highest completion percentage -
|
// if ANY completion for the types, count only the criteria type with the highest completion percentage -.
|
||||||
// Overwrite data if current type is more complete
|
// Overwrite data if current type is more complete.
|
||||||
if ($aggregation == COMPLETION_AGGREGATION_ANY) {
|
if ($aggregation == COMPLETION_AGGREGATION_ANY) {
|
||||||
$pct = $cmpl/$ct;
|
$pct = $cmpl/$ct;
|
||||||
if ($pct > $completion_percentage) {
|
if ($pct > $completion_percentage) {
|
||||||
|
@ -654,11 +668,11 @@ class corecompletioninfo {
|
||||||
$completion_percentage = $pct;
|
$completion_percentage = $pct;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if ALL completion for the types, add the count for this type to that of the others
|
// if ALL completion for the types, add the count for this type to that of the others.
|
||||||
else {
|
else {
|
||||||
$count += $ct;
|
$count += $ct;
|
||||||
$completed += $cmpl;
|
$completed += $cmpl;
|
||||||
// Don't really care about recalculating completion percentage every round in this case
|
// Don't really care about recalculating completion percentage every round in this case.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
@ -29,7 +49,7 @@ class courseinfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function course() {
|
public function course() {
|
||||||
return $this->course; // php arrays are assigned by copy
|
return $this->course; // php arrays are assigned by copy.
|
||||||
}
|
}
|
||||||
|
|
||||||
public function course_context() {
|
public function course_context() {
|
||||||
|
@ -97,10 +117,8 @@ class courseinfo {
|
||||||
|
|
||||||
public static function coursetiming($course) {
|
public static function coursetiming($course) {
|
||||||
$now = time();
|
$now = time();
|
||||||
if($now > $course->startdate)
|
if ($now > $course->startdate) {
|
||||||
{
|
if ($course->enddate > 0 && $now > $course->enddate) {
|
||||||
if($course->enddate > 0 && $now > $course->enddate)
|
|
||||||
{
|
|
||||||
return "past";
|
return "past";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -137,7 +155,7 @@ class courseinfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Fallback to shortname when the specified display field fails, since shortname is never empty
|
// Fallback to shortname when the specified display field fails, since shortname is never empty.
|
||||||
return $this->course->shortname;
|
return $this->course->shortname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
@ -17,11 +37,11 @@ class coursemoduleinfo {
|
||||||
|
|
||||||
public function __construct($id) {
|
public function __construct($id) {
|
||||||
global $DB;
|
global $DB;
|
||||||
// Determine the icon for the associated activity
|
// Determine the icon for the associated activity.
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
$this->cm = $DB->get_record("course_modules", ["id" => $id]);
|
$this->cm = $DB->get_record("course_modules", ["id" => $id]);
|
||||||
$this->cm_info = \cm_info::create($this->cm);
|
$this->cm_info = \cm_info::create($this->cm);
|
||||||
// $this->db_record = $DB->get_record($this->cm_info->modname,["id" => $this->cm_info->instance]);
|
// $this->db_record = $DB->get_record($this->cm_info->modname, ["id" => $this->cm_info->instance]);.
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitle() {
|
public function getTitle() {
|
||||||
|
@ -30,7 +50,7 @@ class coursemoduleinfo {
|
||||||
|
|
||||||
public function setTitle($value) {
|
public function setTitle($value) {
|
||||||
$this->cm_info->set_name($value);
|
$this->cm_info->set_name($value);
|
||||||
// TODO: Actually save this after setting the cminfo
|
// TODO: Actually save this after setting the cminfo.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
|
||||||
|
@ -31,8 +52,7 @@ class courseservice extends \external_api
|
||||||
return new \external_multiple_structure(static::map_category_structure(false));
|
return new \external_multiple_structure(static::map_category_structure(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function map_category_structure($lazy=false,$value=VALUE_REQUIRED)
|
protected static function map_category_structure($lazy=false, $value=VALUE_REQUIRED) {
|
||||||
{
|
|
||||||
$s = [
|
$s = [
|
||||||
"id" => new \external_value(PARAM_INT, 'course category id'),
|
"id" => new \external_value(PARAM_INT, 'course category id'),
|
||||||
"context_id" => new \external_value(PARAM_INT, 'course category context id'),
|
"context_id" => new \external_value(PARAM_INT, 'course category context id'),
|
||||||
|
@ -54,16 +74,16 @@ 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(self::CAP_EDIT, $context);
|
webservicehelper::require_capabilities(self::CAP_EDIT, $context);
|
||||||
|
|
||||||
// Determine top categories from provided context
|
// Determine top categories from provided context.
|
||||||
|
|
||||||
if ($root->id == 0) {
|
if ($root->id == 0) {
|
||||||
// on the system level, determine the user's topmost allowed catecories
|
// on the system level, determine the user's topmost allowed catecories.
|
||||||
$user_top = \core_course_category::user_top();
|
$user_top = \core_course_category::user_top();
|
||||||
if ($user_top->id == 0) { // top category..
|
if ($user_top->id == 0) { // top category..
|
||||||
$children = $root->get_children(); // returns a list of çore_course_category, let it overwrite $children
|
$children = $root->get_children(); // returns a list of çore_course_category, let it overwrite $children.
|
||||||
} else {
|
} else {
|
||||||
$children = [$user_top];
|
$children = [$user_top];
|
||||||
}
|
}
|
||||||
|
@ -98,7 +118,7 @@ class courseservice extends \external_api
|
||||||
global $DB;
|
global $DB;
|
||||||
$catcontext = $cat->get_context();
|
$catcontext = $cat->get_context();
|
||||||
$ctx_info = new contextinfo($catcontext);
|
$ctx_info = new contextinfo($catcontext);
|
||||||
$children = $cat->get_children(); // only shows children visible to the current user
|
$children = $cat->get_children(); // only shows children visible to the current user.
|
||||||
$courses = $cat->get_courses();
|
$courses = $cat->get_courses();
|
||||||
$model = [
|
$model = [
|
||||||
"id" => $cat->id,
|
"id" => $cat->id,
|
||||||
|
@ -108,8 +128,7 @@ class courseservice extends \external_api
|
||||||
"hascourses" => !empty($courses),
|
"hascourses" => !empty($courses),
|
||||||
];
|
];
|
||||||
|
|
||||||
if(!$lazy)
|
if (!$lazy) {
|
||||||
{
|
|
||||||
$model["courses"] = [];
|
$model["courses"] = [];
|
||||||
foreach ($courses as $course) {
|
foreach ($courses as $course) {
|
||||||
$courseinfo = new courseinfo($course->id);
|
$courseinfo = new courseinfo($course->id);
|
||||||
|
@ -141,7 +160,7 @@ class courseservice extends \external_api
|
||||||
{
|
{
|
||||||
if ($operation == "edit") {
|
if ($operation == "edit") {
|
||||||
$capability = self::CAP_EDIT;
|
$capability = self::CAP_EDIT;
|
||||||
} else { // $operation == "view" || default
|
} else { // $operation == "view" || default.
|
||||||
$capability = self::CAP_VIEW;
|
$capability = self::CAP_VIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,9 +176,9 @@ class courseservice extends \external_api
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function categories_by_capability($capability, \core_course_category $parent=null) {
|
public static function categories_by_capability($capability, \core_course_category $parent=null) {
|
||||||
// List the categories in which the user has a specific capability
|
// List the categories in which the user has a specific capability.
|
||||||
$list = [];
|
$list = [];
|
||||||
// initialize parent if needed
|
// initialize parent if needed.
|
||||||
if ($parent == null) {
|
if ($parent == null) {
|
||||||
$parent = \core_course_category::user_top();
|
$parent = \core_course_category::user_top();
|
||||||
if (has_capability($capability, $parent->get_context())) {
|
if (has_capability($capability, $parent->get_context())) {
|
||||||
|
@ -169,11 +188,11 @@ class courseservice extends \external_api
|
||||||
|
|
||||||
$children = $parent->get_children();
|
$children = $parent->get_children();
|
||||||
foreach ($children as $child) {
|
foreach ($children as $child) {
|
||||||
// Check if we should add this category
|
// Check if we should add this category.
|
||||||
if (has_capability($capability, $child->get_context())) {
|
if (has_capability($capability, $child->get_context())) {
|
||||||
$list[] = $child;
|
$list[] = $child;
|
||||||
// For optimization purposes, we include all its children now, since they will have inherited the permission
|
// For optimization purposes, we include all its children now, since they will have inherited the permission.
|
||||||
// #PREMATURE_OPTIMIZATION ???
|
// #PREMATURE_OPTIMIZATION ???.
|
||||||
$list = array_merge($list, self::recursive_child_categories($child));
|
$list = array_merge($list, self::recursive_child_categories($child));
|
||||||
} else {
|
} else {
|
||||||
if ($child->get_children_count() > 0) {
|
if ($child->get_children_count() > 0) {
|
||||||
|
@ -214,7 +233,7 @@ class courseservice extends \external_api
|
||||||
global $DB;
|
global $DB;
|
||||||
if ($operation == "edit") {
|
if ($operation == "edit") {
|
||||||
$capability = self::CAP_EDIT;
|
$capability = self::CAP_EDIT;
|
||||||
} else { // $operation == "view" || default
|
} else { // $operation == "view" || default.
|
||||||
$capability = self::CAP_VIEW;
|
$capability = self::CAP_VIEW;
|
||||||
}
|
}
|
||||||
$context_ids = [];
|
$context_ids = [];
|
||||||
|
@ -226,8 +245,8 @@ class courseservice extends \external_api
|
||||||
$rs->close();
|
$rs->close();
|
||||||
|
|
||||||
|
|
||||||
// Now filter the categories that the user has acces to by the used context id's
|
// Now filter the categories that the user has acces to by the used context id's.
|
||||||
// (That should filter out irrelevant stuff)
|
// (That should filter out irrelevant stuff).
|
||||||
$cats = static::categories_by_capability($capability);
|
$cats = static::categories_by_capability($capability);
|
||||||
|
|
||||||
$list = [];
|
$list = [];
|
||||||
|
@ -249,10 +268,10 @@ class courseservice extends \external_api
|
||||||
global $DB;
|
global $DB;
|
||||||
if ($operation == "edit") {
|
if ($operation == "edit") {
|
||||||
$capability = self::CAP_EDIT;
|
$capability = self::CAP_EDIT;
|
||||||
} else { // $operation == "view" || default
|
} else { // $operation == "view" || default.
|
||||||
$capability = self::CAP_VIEW;
|
$capability = self::CAP_VIEW;
|
||||||
}
|
}
|
||||||
// retrieve context ids used
|
// retrieve context ids used.
|
||||||
$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}
|
||||||
GROUP BY context_id");
|
GROUP BY context_id");
|
||||||
|
@ -261,8 +280,8 @@ class courseservice extends \external_api
|
||||||
}
|
}
|
||||||
$rs->close();
|
$rs->close();
|
||||||
|
|
||||||
// Now filter the categories that the user has acces to by the used context id's
|
// Now filter the categories that the user has acces to by the used context id's.
|
||||||
// (That should filter out irrelevant stuff)
|
// (That should filter out irrelevant stuff).
|
||||||
$cats = static::categories_by_capability($capability);
|
$cats = static::categories_by_capability($capability);
|
||||||
|
|
||||||
$list = [];
|
$list = [];
|
||||||
|
@ -288,8 +307,7 @@ class courseservice extends \external_api
|
||||||
*
|
*
|
||||||
**************************************/
|
**************************************/
|
||||||
|
|
||||||
public static function scan_grade_progress_parameters()
|
public static function scan_grade_progress_parameters() {
|
||||||
{
|
|
||||||
return new \external_function_parameters( [
|
return new \external_function_parameters( [
|
||||||
"gradeitemid" => new \external_value(PARAM_INT, 'Grade item ID to scan progress for', VALUE_DEFAULT),
|
"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),
|
"studyplanid" => new \external_value(PARAM_INT, 'Study plan id to check progress in', VALUE_DEFAULT),
|
||||||
|
@ -297,22 +315,20 @@ class courseservice extends \external_api
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function scan_grade_progress_returns()
|
public static function scan_grade_progress_returns() {
|
||||||
{
|
|
||||||
return gradingscanner::structure(VALUE_REQUIRED);
|
return gradingscanner::structure(VALUE_REQUIRED);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function scan_grade_progress($gradeitemid, $studyplanid)
|
public static function scan_grade_progress($gradeitemid, $studyplanid) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
// Verify access to the study plan
|
// Verify access to the study plan.
|
||||||
$o = studyplan::findById($studyplanid);
|
$o = studyplan::findById($studyplanid);
|
||||||
webservicehelper::require_capabilities(self::CAP_VIEW, $o->context());
|
webservicehelper::require_capabilities(self::CAP_VIEW, $o->context());
|
||||||
|
|
||||||
// Retrieve grade item
|
// Retrieve grade item.
|
||||||
$gi = \grade_item::fetch(["id" => $gradeitemid]);
|
$gi = \grade_item::fetch(["id" => $gradeitemid]);
|
||||||
|
|
||||||
// Validate course is linked to studyplan
|
// Validate course is linked to studyplan.
|
||||||
$courseid = $gi->courseid;
|
$courseid = $gi->courseid;
|
||||||
if (!$o->course_linked($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()}");
|
throw new \webservice_access_exception("Course {$courseid} linked to grade item {$gradeitemid} is not linked to studyplan {$o->id()}");
|
||||||
|
@ -340,7 +356,7 @@ class courseservice extends \external_api
|
||||||
public static function scan_completion_progress($criteriaid, $studyplanid, $courseid)
|
public static function scan_completion_progress($criteriaid, $studyplanid, $courseid)
|
||||||
{
|
{
|
||||||
global $DB;
|
global $DB;
|
||||||
// Verify access to the study plan
|
// Verify access to the study plan.
|
||||||
$o = studyplan::findById($studyplanid);
|
$o = studyplan::findById($studyplanid);
|
||||||
webservicehelper::require_capabilities(self::CAP_VIEW, $o->context());
|
webservicehelper::require_capabilities(self::CAP_VIEW, $o->context());
|
||||||
|
|
||||||
|
@ -371,22 +387,22 @@ class courseservice extends \external_api
|
||||||
public static function scan_badge_progress($badgeid, $studyplanid)
|
public static function scan_badge_progress($badgeid, $studyplanid)
|
||||||
{
|
{
|
||||||
global $DB;
|
global $DB;
|
||||||
// Check access to the study plan
|
// Check access to the study plan.
|
||||||
$o = studyplan::findById($studyplanid);
|
$o = studyplan::findById($studyplanid);
|
||||||
webservicehelper::require_capabilities(self::CAP_VIEW, $o->context());
|
webservicehelper::require_capabilities(self::CAP_VIEW, $o->context());
|
||||||
|
|
||||||
// Validate that badge is linked to studyplan
|
// Validate that badge is linked to studyplan.
|
||||||
if (!$o->badge_linked($badgeid)) {
|
if (!$o->badge_linked($badgeid)) {
|
||||||
throw new \webservice_access_exception("Badge {$badgeid} is not linked to studyplan {$o->id()}");
|
throw new \webservice_access_exception("Badge {$badgeid} is not linked to studyplan {$o->id()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get badge info
|
// Get badge info.
|
||||||
$badge = new \core_badges\badge($badgeid);
|
$badge = new \core_badges\badge($badgeid);
|
||||||
$badgeinfo = new badgeinfo($badge);
|
$badgeinfo = new badgeinfo($badge);
|
||||||
|
|
||||||
// get the connected users
|
// get the connected users.
|
||||||
$students = associationservice::all_associated($studyplanid);
|
$students = associationservice::all_associated($studyplanid);
|
||||||
// Just get the user ids
|
// Just get the user ids.
|
||||||
$studentids = array_map(function ($a) { return $a["id"];}, $students);
|
$studentids = array_map(function ($a) { return $a["id"];}, $students);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -1,4 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
@ -77,8 +97,7 @@ class gradeinfo {
|
||||||
|
|
||||||
public static function getCourseContextById($id) {
|
public static function getCourseContextById($id) {
|
||||||
$gi = grade_item::fetch(["id" => $id]);
|
$gi = grade_item::fetch(["id" => $id]);
|
||||||
if(!$gi || course_module_instance_pending_deletion($gi->courseid, $gi->itemmodule, $gi->iteminstance))
|
if (!$gi || course_module_instance_pending_deletion($gi->courseid, $gi->itemmodule, $gi->iteminstance)) {
|
||||||
{
|
|
||||||
throw new \InvalidArgumentException ("Grade {$id} not found in database". print_r($gi, true));
|
throw new \InvalidArgumentException ("Grade {$id} not found in database". print_r($gi, true));
|
||||||
}
|
}
|
||||||
return \context_course::instance($gi->courseid);;
|
return \context_course::instance($gi->courseid);;
|
||||||
|
@ -89,18 +108,17 @@ class gradeinfo {
|
||||||
$this->studyitem = $studyitem;
|
$this->studyitem = $studyitem;
|
||||||
|
|
||||||
$gi = grade_item::fetch(["id" => $id]);
|
$gi = grade_item::fetch(["id" => $id]);
|
||||||
if(!$gi || course_module_instance_pending_deletion($gi->courseid, $gi->itemmodule, $gi->iteminstance))
|
if (!$gi || course_module_instance_pending_deletion($gi->courseid, $gi->itemmodule, $gi->iteminstance)) {
|
||||||
{
|
|
||||||
throw new \InvalidArgumentException ("Grade {$id} not found in database". print_r($gi, true));
|
throw new \InvalidArgumentException ("Grade {$id} not found in database". print_r($gi, true));
|
||||||
}
|
}
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
$this->gradeitem = $gi;
|
$this->gradeitem = $gi;
|
||||||
|
|
||||||
// Determine the icon for the associated activity
|
// Determine the icon for the associated activity.
|
||||||
$contentitem = static::get_contentitem($gi->itemmodule);
|
$contentitem = static::get_contentitem($gi->itemmodule);
|
||||||
$this->icon = empty($contentitem)?"":$contentitem->get_icon();
|
$this->icon = empty($contentitem)?"":$contentitem->get_icon();
|
||||||
|
|
||||||
// Determine a link to the associated activity
|
// Determine a link to the associated activity.
|
||||||
if ($gi->itemtype != "mod" || empty($gi->itemmodule) || empty($gi->iteminstance)) {
|
if ($gi->itemtype != "mod" || empty($gi->itemmodule) || empty($gi->iteminstance)) {
|
||||||
$this->link = "";
|
$this->link = "";
|
||||||
$this->cmid = 0;
|
$this->cmid = 0;
|
||||||
|
@ -110,8 +128,8 @@ class gradeinfo {
|
||||||
else {
|
else {
|
||||||
list($c, $cminfo) = get_course_and_cm_from_instance($gi->iteminstance, $gi->itemmodule);
|
list($c, $cminfo) = get_course_and_cm_from_instance($gi->iteminstance, $gi->itemmodule);
|
||||||
$this->cmid = $cminfo->id;
|
$this->cmid = $cminfo->id;
|
||||||
// sort by position in course
|
// sort by position in course.
|
||||||
//
|
// .
|
||||||
$this->section = $cminfo->sectionnum;
|
$this->section = $cminfo->sectionnum;
|
||||||
$ssequence = self::getSectionSequence($cminfo->section);
|
$ssequence = self::getSectionSequence($cminfo->section);
|
||||||
$this->sectionorder = array_search($cminfo->id, $ssequence);
|
$this->sectionorder = array_search($cminfo->id, $ssequence);
|
||||||
|
@ -144,7 +162,7 @@ class gradeinfo {
|
||||||
public function is_selected() {
|
public function is_selected() {
|
||||||
global $DB;
|
global $DB;
|
||||||
if ($this->studyitem) {
|
if ($this->studyitem) {
|
||||||
// Check if selected for this studyitem
|
// Check if selected for this studyitem.
|
||||||
$r = $DB->get_record('local_treestudyplan_gradeinc', ['studyitem_id' => $this->studyitem->id(), 'grade_item_id'=> $this->gradeitem->id]);
|
$r = $DB->get_record('local_treestudyplan_gradeinc', ['studyitem_id' => $this->studyitem->id(), 'grade_item_id'=> $this->gradeitem->id]);
|
||||||
if ($r && $r->include) {
|
if ($r && $r->include) {
|
||||||
return(true);
|
return(true);
|
||||||
|
@ -156,7 +174,7 @@ class gradeinfo {
|
||||||
public function is_required() {
|
public function is_required() {
|
||||||
global $DB;
|
global $DB;
|
||||||
if ($this->studyitem) {
|
if ($this->studyitem) {
|
||||||
// Check if selected for this studyitem
|
// Check if selected for this studyitem.
|
||||||
$r = $DB->get_record('local_treestudyplan_gradeinc', ['studyitem_id' => $this->studyitem->id(), 'grade_item_id'=> $this->gradeitem->id]);
|
$r = $DB->get_record('local_treestudyplan_gradeinc', ['studyitem_id' => $this->studyitem->id(), 'grade_item_id'=> $this->gradeitem->id]);
|
||||||
if ($r && $r->include && $r->required) {
|
if ($r && $r->include && $r->required) {
|
||||||
return(true);
|
return(true);
|
||||||
|
@ -224,7 +242,7 @@ class gradeinfo {
|
||||||
public function user_model($userid) {
|
public function user_model($userid) {
|
||||||
global $DB;
|
global $DB;
|
||||||
$grade = $this->gradeitem->get_final($userid);
|
$grade = $this->gradeitem->get_final($userid);
|
||||||
// convert scale grades to corresponding scale name
|
// convert scale grades to corresponding scale name.
|
||||||
if (!empty($grade)) {
|
if (!empty($grade)) {
|
||||||
if (!is_numeric($grade->finalgrade) && empty($grade->finalgrade)) {
|
if (!is_numeric($grade->finalgrade) && empty($grade->finalgrade)) {
|
||||||
$finalgrade = "-";
|
$finalgrade = "-";
|
||||||
|
@ -242,7 +260,7 @@ class gradeinfo {
|
||||||
$finalgrade = "-";
|
$finalgrade = "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
// retrieve the aggregator and determine completion
|
// retrieve the aggregator and determine completion.
|
||||||
if (!isset($this->studyitem)) {
|
if (!isset($this->studyitem)) {
|
||||||
throw new \UnexpectedValueException("Study item not set (null) for gradeinfo in report mode");
|
throw new \UnexpectedValueException("Study item not set (null) for gradeinfo in report mode");
|
||||||
}
|
}
|
||||||
|
@ -285,7 +303,7 @@ class gradeinfo {
|
||||||
$gi_type = $gi->itemmodule;
|
$gi_type = $gi->itemmodule;
|
||||||
|
|
||||||
if ($gi_name == $model["name"] && $gi_type == $model["type"]) {
|
if ($gi_name == $model["name"] && $gi_type == $model["type"]) {
|
||||||
// we have a match
|
// we have a match.
|
||||||
if (!isset($model["selected"])) { $model["selected"] = true;}
|
if (!isset($model["selected"])) { $model["selected"] = true;}
|
||||||
if (!isset($model["required"])) { $model["required"] = false;}
|
if (!isset($model["required"])) { $model["required"] = false;}
|
||||||
if ($model["selected"] || $model["required"]) {
|
if ($model["selected"] || $model["required"]) {
|
||||||
|
@ -302,19 +320,15 @@ class gradeinfo {
|
||||||
if (method_exists("\course_modinfo", "get_array_of_activities")) {
|
if (method_exists("\course_modinfo", "get_array_of_activities")) {
|
||||||
$activities = \course_modinfo::get_array_of_activities($course);
|
$activities = \course_modinfo::get_array_of_activities($course);
|
||||||
} else {
|
} else {
|
||||||
// Deprecated in Moodle 4.0+, but not yet available in Moodle 3.11
|
// Deprecated in Moodle 4.0+, but not yet available in Moodle 3.11.
|
||||||
$activities = get_array_of_activities($course->id);
|
$activities = get_array_of_activities($course->id);
|
||||||
}
|
}
|
||||||
foreach($activities as $act)
|
foreach ($activities as $act) {
|
||||||
{
|
if ($act->visible) {
|
||||||
if($act->visible)
|
|
||||||
{
|
|
||||||
$gradeitems= grade_item::fetch_all(['itemtype' => 'mod', 'itemmodule' => $act->mod, 'iteminstance' => $act->id, 'courseid' => $course->id]);
|
$gradeitems= grade_item::fetch_all(['itemtype' => 'mod', 'itemmodule' => $act->mod, 'iteminstance' => $act->id, 'courseid' => $course->id]);
|
||||||
if(!empty($gradeitems))
|
if (!empty($gradeitems)) {
|
||||||
{
|
|
||||||
foreach ($gradeitems as $gi) {
|
foreach ($gradeitems as $gi) {
|
||||||
if(($gi->gradetype == GRADE_TYPE_VALUE || $gi->gradetype == GRADE_TYPE_SCALE))
|
if (($gi->gradetype == GRADE_TYPE_VALUE || $gi->gradetype == GRADE_TYPE_SCALE)) {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
$gradable = new static($gi->id, $studyitem);
|
$gradable = new static($gi->id, $studyitem);
|
||||||
$list[] = $gradable;
|
$list[] = $gradable;
|
||||||
|
@ -333,8 +347,7 @@ class gradeinfo {
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function list_studyitem_gradables(studyitem $studyitem)
|
public static function list_studyitem_gradables(studyitem $studyitem) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
$table = 'local_treestudyplan_gradeinc';
|
$table = 'local_treestudyplan_gradeinc';
|
||||||
$list = [];
|
$list = [];
|
||||||
|
@ -347,8 +360,8 @@ class gradeinfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(\InvalidArgumentException $x) {
|
catch(\InvalidArgumentException $x) {
|
||||||
// on InvalidArgumentException, the grade_item id can no longer be found
|
// on InvalidArgumentException, the grade_item id can no longer be found.
|
||||||
// Remove the link to avoid database record hogging
|
// Remove the link to avoid database record hogging.
|
||||||
$DB->delete_records($table, ['id' => $r->id]);
|
$DB->delete_records($table, ['id' => $r->id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -365,7 +378,7 @@ class gradeinfo {
|
||||||
global $DB;
|
global $DB;
|
||||||
$table = 'local_treestudyplan_gradeinc';
|
$table = 'local_treestudyplan_gradeinc';
|
||||||
if ($include) {
|
if ($include) {
|
||||||
// make sure a record exits
|
// make sure a record exits.
|
||||||
$r = $DB->get_record($table, ['studyitem_id' => $item_id, 'grade_item_id' => $grade_id]);
|
$r = $DB->get_record($table, ['studyitem_id' => $item_id, 'grade_item_id' => $grade_id]);
|
||||||
if ($r) {
|
if ($r) {
|
||||||
$r->include = 1;
|
$r->include = 1;
|
||||||
|
@ -380,7 +393,7 @@ class gradeinfo {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// remove if it should not be included
|
// remove if it should not be included.
|
||||||
$r = $DB->get_record($table, ['studyitem_id' => $item_id, 'grade_item_id' => $grade_id]);
|
$r = $DB->get_record($table, ['studyitem_id' => $item_id, 'grade_item_id' => $grade_id]);
|
||||||
if ($r) {
|
if ($r) {
|
||||||
$DB->delete_records($table, ['id' => $r->id]);
|
$DB->delete_records($table, ['id' => $r->id]);
|
||||||
|
|
|
@ -1,13 +1,33 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
|
||||||
use \grade_item;
|
use \grade_item;
|
||||||
|
|
||||||
// $gi->courseid,
|
// $gi->courseid, .
|
||||||
// $gi->itemmodule,
|
// $gi->itemmodule, .
|
||||||
// $gi->iteminstance
|
// $gi->iteminstance.
|
||||||
class gradingscanner
|
class gradingscanner
|
||||||
{
|
{
|
||||||
private static $mod_supported = [];
|
private static $mod_supported = [];
|
||||||
|
@ -73,7 +93,7 @@ class gradingscanner
|
||||||
}
|
}
|
||||||
|
|
||||||
public function model() {
|
public function model() {
|
||||||
// Upda
|
// Upda.
|
||||||
$students = self::get_course_students($this->courseid);
|
$students = self::get_course_students($this->courseid);
|
||||||
$completed = 0;
|
$completed = 0;
|
||||||
$ungraded = 0;
|
$ungraded = 0;
|
||||||
|
@ -81,16 +101,16 @@ class gradingscanner
|
||||||
$completed_fail = 0;
|
$completed_fail = 0;
|
||||||
foreach ($students as $userid) {
|
foreach ($students as $userid) {
|
||||||
if ($this->pending($userid)) {
|
if ($this->pending($userid)) {
|
||||||
// First check if the completion needs grading
|
// First check if the completion needs grading.
|
||||||
$ungraded++;
|
$ungraded++;
|
||||||
} else {
|
} else {
|
||||||
$grade = $this->gi->get_final($userid);
|
$grade = $this->gi->get_final($userid);
|
||||||
if (!is_numeric($grade->finalgrade) && empty($grade->finalgrade)) {
|
if (!is_numeric($grade->finalgrade) && empty($grade->finalgrade)) {
|
||||||
//skip
|
//skip.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//compare grade to minimum grade
|
//compare grade to minimum grade.
|
||||||
if ($this->grade_passed($grade)) {
|
if ($this->grade_passed($grade)) {
|
||||||
$completed_pass++;
|
$completed_pass++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -110,18 +130,17 @@ class gradingscanner
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function copied from bistate aggregator to avoid reference mazes
|
// Function copied from bistate aggregator to avoid reference mazes.
|
||||||
private function grade_passed($grade) {
|
private function grade_passed($grade) {
|
||||||
global $DB;
|
global $DB;
|
||||||
$table = "local_treestudyplan_gradecfg";
|
$table = "local_treestudyplan_gradecfg";
|
||||||
// first determine if we have a grade_config for this scale or this maximum grade
|
// first determine if we have a grade_config for this scale or this maximum grade.
|
||||||
$finalgrade = $grade->finalgrade;
|
$finalgrade = $grade->finalgrade;
|
||||||
$scale = $this->gi->load_scale();
|
$scale = $this->gi->load_scale();
|
||||||
if ( isset($scale)) {
|
if ( isset($scale)) {
|
||||||
$gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]);
|
$gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]);
|
||||||
}
|
}
|
||||||
else if($this->gi->grademin == 0)
|
else if ($this->gi->grademin == 0) {
|
||||||
{
|
|
||||||
$gradecfg = $DB->get_record($table, ["grade_points"=>$this->gi->grademax]);
|
$gradecfg = $DB->get_record($table, ["grade_points"=>$this->gi->grademax]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -129,12 +148,11 @@ class gradingscanner
|
||||||
$gradecfg = null;
|
$gradecfg = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for point grades, a provided grade pass overrides the defaults in the gradeconfig
|
// for point grades, a provided grade pass overrides the defaults in the gradeconfig.
|
||||||
// for scales, the configuration in the gradeconfig is leading
|
// for scales, the configuration in the gradeconfig is leading.
|
||||||
|
|
||||||
if($gradecfg && (isset($scale) || $this->gi->gradepass == 0))
|
if ($gradecfg && (isset($scale) || $this->gi->gradepass == 0)) {
|
||||||
{
|
// if so, we need to know if the grade is .
|
||||||
// if so, we need to know if the grade is
|
|
||||||
if ($finalgrade >= $gradecfg->min_completed) {
|
if ($finalgrade >= $gradecfg->min_completed) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -142,8 +160,7 @@ class gradingscanner
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if($this->gi->gradepass > 0)
|
else if ($this->gi->gradepass > 0) {
|
||||||
{
|
|
||||||
$range = floatval($this->gi->grademax - $this->gi->grademin);
|
$range = floatval($this->gi->grademax - $this->gi->grademin);
|
||||||
// if no gradeconfig and gradepass is set, use that one to determine config.
|
// if no gradeconfig and gradepass is set, use that one to determine config.
|
||||||
if ($finalgrade >= $this->gi->gradepass) {
|
if ($finalgrade >= $this->gi->gradepass) {
|
||||||
|
@ -154,9 +171,9 @@ class gradingscanner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Blind assumptions if nothing is provided
|
// Blind assumptions if nothing is provided.
|
||||||
// over 55% of range is completed
|
// over 55% of range is completed.
|
||||||
// if range >= 3 and failed is enabled, assume that this means failed
|
// if range >= 3 and failed is enabled, assume that this means failed.
|
||||||
$g = floatval($finalgrade - $this->gi->grademin);
|
$g = floatval($finalgrade - $this->gi->grademin);
|
||||||
$range = floatval($this->gi->grademax - $this->gi->grademin);
|
$range = floatval($this->gi->grademax - $this->gi->grademin);
|
||||||
$score = $g / $range;
|
$score = $g / $range;
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace local_treestudyplan\local\aggregators;
|
namespace local_treestudyplan\local\aggregators;
|
||||||
|
|
||||||
|
@ -12,25 +33,24 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
public const DEPRECATED = false;
|
public const DEPRECATED = false;
|
||||||
private const DEFAULT_CONDITION = "50";
|
private const DEFAULT_CONDITION = "50";
|
||||||
|
|
||||||
private $thresh_excellent = 1.0; // Minimum fraction that must be completed to aggregate as excellent (usually 1.0)
|
private $thresh_excellent = 1.0; // Minimum fraction that must be completed to aggregate as excellent (usually 1.0).
|
||||||
private $thresh_good = 0.8; // Minimum fraction that must be completed to aggregate as good
|
private $thresh_good = 0.8; // Minimum fraction that must be completed to aggregate as good.
|
||||||
private $thresh_completed = 0.66; // Minimum fraction that must be completed to aggregate as completed
|
private $thresh_completed = 0.66; // Minimum fraction that must be completed to aggregate as completed.
|
||||||
private $use_failed = True; // Support failed completion yes/no
|
private $use_failed = True; // Support failed completion yes/no.
|
||||||
private $thresh_progress = 0.33; // Minimum fraction that must be failed to aggregate as failed instead of progress
|
private $thresh_progress = 0.33; // Minimum fraction that must be failed to aggregate as failed instead of progress.
|
||||||
private $accept_pending_as_submitted = False; // Also count ungraded but submitted
|
private $accept_pending_as_submitted = False; // Also count ungraded but submitted .
|
||||||
|
|
||||||
public function __construct($configstr) {
|
public function __construct($configstr) {
|
||||||
// allow public constructor for testing purposes
|
// allow public constructor for testing purposes.
|
||||||
$this->initialize($configstr);
|
$this->initialize($configstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function initialize($configstr) {
|
protected function initialize($configstr) {
|
||||||
// First initialize with the defaults
|
// First initialize with the defaults.
|
||||||
|
|
||||||
foreach (["thresh_excellent", "thresh_good", "thresh_completed", "thresh_progress", ] as $key) {
|
foreach (["thresh_excellent", "thresh_good", "thresh_completed", "thresh_progress", ] as $key) {
|
||||||
$val = intval(get_config('local_treestudyplan', "bistate_{$key}"));
|
$val = intval(get_config('local_treestudyplan', "bistate_{$key}"));
|
||||||
if($val >= 0 && $val <= 100)
|
if ($val >= 0 && $val <= 100) {
|
||||||
{
|
|
||||||
$this->$key = floatval($val)/100;
|
$this->$key = floatval($val)/100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,16 +58,15 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
$this->$key = boolval(get_config('local_treestudyplan', "bistate_{$key}"));
|
$this->$key = boolval(get_config('local_treestudyplan', "bistate_{$key}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, decode json
|
// Next, decode json.
|
||||||
$config = \json_decode($configstr, true);
|
$config = \json_decode($configstr, true);
|
||||||
|
|
||||||
if (is_array($config)) {
|
if (is_array($config)) {
|
||||||
// copy all valid config settings to this item
|
// copy all valid config settings to this item.
|
||||||
foreach (["thresh_excellent", "thresh_good", "thresh_completed", "thresh_progress", ] as $key) {
|
foreach (["thresh_excellent", "thresh_good", "thresh_completed", "thresh_progress", ] as $key) {
|
||||||
if (array_key_exists($key, $config)) {
|
if (array_key_exists($key, $config)) {
|
||||||
$val = $config[$key];
|
$val = $config[$key];
|
||||||
if($val >= 0 && $val <= 100)
|
if ($val >= 0 && $val <= 100) {
|
||||||
{
|
|
||||||
$this->$key = floatval($val)/100;
|
$this->$key = floatval($val)/100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +81,7 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return active configuration model
|
// Return active configuration model.
|
||||||
public function config_string() {
|
public function config_string() {
|
||||||
return json_encode([
|
return json_encode([
|
||||||
"thresh_excellent" => 100*$this->thresh_excellent,
|
"thresh_excellent" => 100*$this->thresh_excellent,
|
||||||
|
@ -81,16 +100,16 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
|
|
||||||
|
|
||||||
public function aggregate_binary_goals(array $completions, array $required = []) {
|
public function aggregate_binary_goals(array $completions, array $required = []) {
|
||||||
// function is public to allow access for the testing code
|
// function is public to allow access for the testing code.
|
||||||
|
|
||||||
// return te following conditions
|
// return te following conditions.
|
||||||
// Possible states:
|
// Possible states:.
|
||||||
// - completion::EXCELLENT - At least $thresh_excellent fraction of goals are complete and all required goals are met
|
// - completion::EXCELLENT - At least $thresh_excellent fraction of goals are complete and all required goals are met.
|
||||||
// - completion::GOOD - At least $thresh_good fraction of goals are complete and all required goals are met
|
// - completion::GOOD - At least $thresh_good fraction of goals are complete and all required goals are met.
|
||||||
// - completion::COMPLETED - At least $thresh_complete fraction of goals are completed and all required goals are met
|
// - completion::COMPLETED - At least $thresh_complete fraction of goals are completed and all required goals are met.
|
||||||
// - completion::FAILED - At least $thresh_progress fraction of goals is not failed
|
// - completion::FAILED - At least $thresh_progress fraction of goals is not failed.
|
||||||
// - completion::INCOMPLETE - No goals have been started
|
// - completion::INCOMPLETE - No goals have been started.
|
||||||
// - completion::PROGRESS - All other states
|
// - completion::PROGRESS - All other states.
|
||||||
|
|
||||||
|
|
||||||
$total = count($completions);
|
$total = count($completions);
|
||||||
|
@ -148,13 +167,13 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
foreach (gradeinfo::list_studyitem_gradables($studyitem) as $gi) {
|
foreach (gradeinfo::list_studyitem_gradables($studyitem) as $gi) {
|
||||||
$completions[] = $this->grade_completion($gi, $userid);
|
$completions[] = $this->grade_completion($gi, $userid);
|
||||||
if ($gi->is_required()) {
|
if ($gi->is_required()) {
|
||||||
// if it's a required grade
|
// if it's a required grade .
|
||||||
// also add it's index in the completion list to the list of required grades
|
// also add it's index in the completion list to the list of required grades .
|
||||||
$required[] = count($completions) - 1;
|
$required[] = count($completions) - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combine the aquired completions into one
|
// Combine the aquired completions into one.
|
||||||
$result = self::aggregate_binary_goals($completions, $required);
|
$result = self::aggregate_binary_goals($completions, $required);
|
||||||
if ($this->use_failed && $result == completion::PROGRESS && $coursefinished) {
|
if ($this->use_failed && $result == completion::PROGRESS && $coursefinished) {
|
||||||
return completion::FAILED;
|
return completion::FAILED;
|
||||||
|
@ -166,15 +185,15 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
|
|
||||||
public function aggregate_junction(array $completion, studyitem $studyitem = null, $userid = 0) {
|
public function aggregate_junction(array $completion, studyitem $studyitem = null, $userid = 0) {
|
||||||
// Aggregate multiple incoming states into one junction or finish.
|
// Aggregate multiple incoming states into one junction or finish.
|
||||||
// Possible states:
|
// Possible states:.
|
||||||
// - completion::EXCELLENT - All incoming states are excellent
|
// - completion::EXCELLENT - All incoming states are excellent.
|
||||||
// - completion::GOOD - All incoming states are at least good
|
// - completion::GOOD - All incoming states are at least good.
|
||||||
// - completion::COMPLETED - All incoming states are at least completed
|
// - completion::COMPLETED - All incoming states are at least completed.
|
||||||
// - completion::FAILED - All incoming states are failed
|
// - completion::FAILED - All incoming states are failed.
|
||||||
// - completion::INCOMPLETE - All incoming states are incomplete
|
// - completion::INCOMPLETE - All incoming states are incomplete.
|
||||||
// - completion::PROGRESS - All other states
|
// - completion::PROGRESS - All other states.
|
||||||
|
|
||||||
// First count all states
|
// First count all states.
|
||||||
$statecount = completion::count_states($completion);
|
$statecount = completion::count_states($completion);
|
||||||
$total = count($completion);
|
$total = count($completion);
|
||||||
|
|
||||||
|
@ -203,20 +222,19 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
$table = "local_treestudyplan_gradecfg";
|
$table = "local_treestudyplan_gradecfg";
|
||||||
$gradeitem = $gradeinfo->getGradeitem();
|
$gradeitem = $gradeinfo->getGradeitem();
|
||||||
$grade = $gradeitem->get_final($userid);
|
$grade = $gradeitem->get_final($userid);
|
||||||
$course = \get_course($gradeitem->courseid); // Fetch course from cache
|
$course = \get_course($gradeitem->courseid); // Fetch course from cache.
|
||||||
$coursefinished = ($course->enddate)?($course->enddate < time()):false;
|
$coursefinished = ($course->enddate)?($course->enddate < time()):false;
|
||||||
|
|
||||||
if (empty($grade)) {
|
if (empty($grade)) {
|
||||||
return completion::INCOMPLETE;
|
return completion::INCOMPLETE;
|
||||||
}
|
}
|
||||||
else if($grade->finalgrade === NULL)
|
else if ($grade->finalgrade === NULL) {
|
||||||
{
|
// on assignments, grade NULL means a submission has not yet been graded,.
|
||||||
// on assignments, grade NULL means a submission has not yet been graded,
|
// but on quizes this can also mean a quiz might have been started.
|
||||||
// but on quizes this can also mean a quiz might have been started
|
// Therefor, we treat a NULL result as a reason to check the relevant gradingscanner for presence of pending items.
|
||||||
// Therefor, we treat a NULL result as a reason to check the relevant gradingscanner for presence of pending items
|
|
||||||
|
|
||||||
// Since we want old results to be visible until a pending item was graded, we only use this state here.
|
// Since we want old results to be visible until a pending item was graded, we only use this state here.
|
||||||
// Pending items are otherwise expressly indicated by the "pendingsubmission" field in the user model
|
// Pending items are otherwise expressly indicated by the "pendingsubmission" field in the user model.
|
||||||
if ($gradeinfo->getGradingscanner()->pending($userid)) {
|
if ($gradeinfo->getGradingscanner()->pending($userid)) {
|
||||||
return completion::PENDING;
|
return completion::PENDING;
|
||||||
} else {
|
} else {
|
||||||
|
@ -225,14 +243,13 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$grade = $gradeitem->get_final($userid);
|
$grade = $gradeitem->get_final($userid);
|
||||||
// first determine if we have a grade_config for this scale or this maximum grade
|
// first determine if we have a grade_config for this scale or this maximum grade.
|
||||||
$finalgrade = $grade->finalgrade;
|
$finalgrade = $grade->finalgrade;
|
||||||
$scale = $gradeinfo->getScale();
|
$scale = $gradeinfo->getScale();
|
||||||
if ( isset($scale)) {
|
if ( isset($scale)) {
|
||||||
$gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]);
|
$gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]);
|
||||||
}
|
}
|
||||||
else if($gradeitem->grademin == 0)
|
else if ($gradeitem->grademin == 0) {
|
||||||
{
|
|
||||||
$gradecfg = $DB->get_record($table, ["grade_points"=>$gradeitem->grademax]);
|
$gradecfg = $DB->get_record($table, ["grade_points"=>$gradeitem->grademax]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -240,34 +257,30 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
$gradecfg = null;
|
$gradecfg = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for point grades, a provided grade pass overrides the defaults in the gradeconfig
|
// for point grades, a provided grade pass overrides the defaults in the gradeconfig.
|
||||||
// for scales, the configuration in the gradeconfig is leading
|
// for scales, the configuration in the gradeconfig is leading.
|
||||||
|
|
||||||
if($gradecfg && (isset($scale) || $gradeitem->gradepass == 0))
|
if ($gradecfg && (isset($scale) || $gradeitem->gradepass == 0)) {
|
||||||
{
|
// if so, we need to know if the grade is .
|
||||||
// if so, we need to know if the grade is
|
|
||||||
if ($finalgrade >= $gradecfg->min_completed) {
|
if ($finalgrade >= $gradecfg->min_completed) {
|
||||||
// return completed if completed
|
// return completed if completed.
|
||||||
return completion::COMPLETED;
|
return completion::COMPLETED;
|
||||||
}
|
}
|
||||||
else if($this->use_failed && $coursefinished)
|
else if ($this->use_failed && $coursefinished) {
|
||||||
{
|
// return failed if failed is enabled and the grade is less than the minimum grade for progress.
|
||||||
// return failed if failed is enabled and the grade is less than the minimum grade for progress
|
|
||||||
return completion::FAILED;
|
return completion::FAILED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return completion::PROGRESS;
|
return completion::PROGRESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if($gradeitem->gradepass > 0)
|
else if ($gradeitem->gradepass > 0) {
|
||||||
{
|
|
||||||
$range = floatval($gradeitem->grademax - $gradeitem->grademin);
|
$range = floatval($gradeitem->grademax - $gradeitem->grademin);
|
||||||
// if no gradeconfig and gradepass is set, use that one to determine config.
|
// if no gradeconfig and gradepass is set, use that one to determine config.
|
||||||
if ($finalgrade >= $gradeitem->gradepass) {
|
if ($finalgrade >= $gradeitem->gradepass) {
|
||||||
return completion::COMPLETED;
|
return completion::COMPLETED;
|
||||||
}
|
}
|
||||||
else if($this->use_failed && $coursefinished)
|
else if ($this->use_failed && $coursefinished) {
|
||||||
{
|
|
||||||
// return failed if failed is enabled and the grade is 1, while there are at leas 3 states.
|
// return failed if failed is enabled and the grade is 1, while there are at leas 3 states.
|
||||||
return completion::FAILED;
|
return completion::FAILED;
|
||||||
}
|
}
|
||||||
|
@ -276,9 +289,9 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Blind assumptions if nothing is provided
|
// Blind assumptions if nothing is provided.
|
||||||
// over 55% of range is completed
|
// over 55% of range is completed.
|
||||||
// if range >= 3 and failed is enabled, assume that this means failed
|
// if range >= 3 and failed is enabled, assume that this means failed.
|
||||||
$g = floatval($finalgrade - $gradeitem->grademin);
|
$g = floatval($finalgrade - $gradeitem->grademin);
|
||||||
$range = floatval($gradeitem->grademax - $gradeitem->grademin);
|
$range = floatval($gradeitem->grademax - $gradeitem->grademin);
|
||||||
$score = $g / $range;
|
$score = $g / $range;
|
||||||
|
@ -286,8 +299,7 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
if ($score > 0.55) {
|
if ($score > 0.55) {
|
||||||
return completion::COMPLETED;
|
return completion::COMPLETED;
|
||||||
}
|
}
|
||||||
else if($this->use_failed && $coursefinished)
|
else if ($this->use_failed && $coursefinished) {
|
||||||
{
|
|
||||||
// return failed if failed is enabled and the grade is 1, while there are at leas 3 states.
|
// return failed if failed is enabled and the grade is 1, while there are at leas 3 states.
|
||||||
return completion::FAILED;
|
return completion::FAILED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace local_treestudyplan\local\aggregators;
|
namespace local_treestudyplan\local\aggregators;
|
||||||
|
|
||||||
|
@ -11,24 +32,24 @@ use \local_treestudyplan\debug;
|
||||||
|
|
||||||
class core_aggregator extends \local_treestudyplan\aggregator {
|
class core_aggregator extends \local_treestudyplan\aggregator {
|
||||||
public const DEPRECATED = false;
|
public const DEPRECATED = false;
|
||||||
private $accept_pending_as_submitted = False; // Also count ungraded but submitted
|
private $accept_pending_as_submitted = False; // Also count ungraded but submitted .
|
||||||
|
|
||||||
public function __construct($configstr) {
|
public function __construct($configstr) {
|
||||||
// allow public constructor for testing purposes
|
// allow public constructor for testing purposes.
|
||||||
$this->initialize($configstr);
|
$this->initialize($configstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function initialize($configstr) {
|
protected function initialize($configstr) {
|
||||||
// First initialize with the defaults
|
// First initialize with the defaults.
|
||||||
foreach (["accept_pending_as_submitted"] as $key) {
|
foreach (["accept_pending_as_submitted"] as $key) {
|
||||||
$this->$key = boolval(get_config('local_treestudyplan', "bistate_{$key}"));
|
$this->$key = boolval(get_config('local_treestudyplan', "bistate_{$key}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, decode json
|
// Next, decode json.
|
||||||
$config = \json_decode($configstr, true);
|
$config = \json_decode($configstr, true);
|
||||||
|
|
||||||
if (is_array($config)) {
|
if (is_array($config)) {
|
||||||
// copy all valid config settings to this item
|
// copy all valid config settings to this item.
|
||||||
foreach (["accept_pending_as_submitted"] as $key) {
|
foreach (["accept_pending_as_submitted"] as $key) {
|
||||||
if (array_key_exists($key, $config)) {
|
if (array_key_exists($key, $config)) {
|
||||||
$this->$key = boolval($config[$key]);
|
$this->$key = boolval($config[$key]);
|
||||||
|
@ -39,7 +60,7 @@ class core_aggregator extends \local_treestudyplan\aggregator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return active configuration model
|
// Return active configuration model.
|
||||||
public function config_string() {
|
public function config_string() {
|
||||||
return json_encode([
|
return json_encode([
|
||||||
"accept_pending_as_submitted" => $this->accept_pending_as_submitted,
|
"accept_pending_as_submitted" => $this->accept_pending_as_submitted,
|
||||||
|
@ -69,36 +90,36 @@ class core_aggregator extends \local_treestudyplan\aggregator {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public function aggregate_course(courseinfo $courseinfo, studyitem $studyitem, $userid) {
|
public function aggregate_course(courseinfo $courseinfo, studyitem $studyitem, $userid) {
|
||||||
// Retrieve the core completion info from the core
|
// Retrieve the core completion info from the core.
|
||||||
$course = $courseinfo->course();
|
$course = $courseinfo->course();
|
||||||
$completion = new \completion_info($course);
|
$completion = new \completion_info($course);
|
||||||
|
|
||||||
if ($completion->is_enabled() && $completion->is_tracked_user($userid)) {
|
if ($completion->is_enabled() && $completion->is_tracked_user($userid)) {
|
||||||
if ($completion->is_course_complete($userid)) {
|
if ($completion->is_course_complete($userid)) {
|
||||||
// Now, the trick is to determine what constitutes excellent and good completion....
|
// Now, the trick is to determine what constitutes excellent and good completion....
|
||||||
// TODO: Determine excellent and maybe good completion
|
// TODO: Determine excellent and maybe good completion.
|
||||||
// Option: Use course end grade to determine that...
|
// Option: Use course end grade to determine that...
|
||||||
// Probably needs a config value in the aggregator....
|
// Probably needs a config value in the aggregator....
|
||||||
|
|
||||||
|
|
||||||
return completion::COMPLETED;
|
return completion::COMPLETED;
|
||||||
} else {
|
} else {
|
||||||
// Check if the course is over or not, if it is over, display failed
|
// Check if the course is over or not, if it is over, display failed.
|
||||||
// Else, return PROGRESS
|
// Else, return PROGRESS.
|
||||||
|
|
||||||
// Retrieve timing through courseinfo
|
// Retrieve timing through courseinfo .
|
||||||
$timing = courseinfo::coursetiming($course);
|
$timing = courseinfo::coursetiming($course);
|
||||||
|
|
||||||
// Not met and time is passed, means FAILED
|
// Not met and time is passed, means FAILED.
|
||||||
if ($timing == "past") {
|
if ($timing == "past") {
|
||||||
return completion::FAILED;
|
return completion::FAILED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Check if any of the requirements are being met?
|
// Check if any of the requirements are being met?.
|
||||||
$completions = $completion->get_completions($userid);
|
$completions = $completion->get_completions($userid);
|
||||||
foreach ($completions as $c) {
|
foreach ($completions as $c) {
|
||||||
if ($c->is_complete()) {
|
if ($c->is_complete()) {
|
||||||
// If so, return progress
|
// If so, return progress.
|
||||||
return completion::PROGRESS;
|
return completion::PROGRESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,15 +134,15 @@ class core_aggregator extends \local_treestudyplan\aggregator {
|
||||||
|
|
||||||
public function aggregate_junction(array $completion, studyitem $studyitem = null, $userid = 0) {
|
public function aggregate_junction(array $completion, studyitem $studyitem = null, $userid = 0) {
|
||||||
// Aggregate multiple incoming states into one junction or finish.
|
// Aggregate multiple incoming states into one junction or finish.
|
||||||
// Possible states:
|
// Possible states:.
|
||||||
// - completion::EXCELLENT - All incoming states are excellent
|
// - completion::EXCELLENT - All incoming states are excellent.
|
||||||
// - completion::GOOD - All incoming states are at least good
|
// - completion::GOOD - All incoming states are at least good.
|
||||||
// - completion::COMPLETED - All incoming states are at least completed
|
// - completion::COMPLETED - All incoming states are at least completed.
|
||||||
// - completion::FAILED - All incoming states are failed
|
// - completion::FAILED - All incoming states are failed.
|
||||||
// - completion::INCOMPLETE - All incoming states are incomplete
|
// - completion::INCOMPLETE - All incoming states are incomplete.
|
||||||
// - completion::PROGRESS - All other states
|
// - completion::PROGRESS - All other states.
|
||||||
|
|
||||||
// First count all states
|
// First count all states.
|
||||||
$statecount = completion::count_states($completion);
|
$statecount = completion::count_states($completion);
|
||||||
$total = count($completion);
|
$total = count($completion);
|
||||||
|
|
||||||
|
@ -146,7 +167,7 @@ class core_aggregator extends \local_treestudyplan\aggregator {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// CORE COMPLETION DOESN'T REALLY USE THE FUNCTIONS BELOW
|
// CORE COMPLETION DOESN'T REALLY USE THE FUNCTIONS BELOW.
|
||||||
// AGGREGATORS ARE GOING TO BE DEPRECATED ANYWAY... but used in legacy parts of this plugin.
|
// AGGREGATORS ARE GOING TO BE DEPRECATED ANYWAY... but used in legacy parts of this plugin.
|
||||||
|
|
||||||
public function grade_completion(gradeinfo $gradeinfo, $userid) {
|
public function grade_completion(gradeinfo $gradeinfo, $userid) {
|
||||||
|
@ -158,14 +179,13 @@ class core_aggregator extends \local_treestudyplan\aggregator {
|
||||||
if (empty($grade)) {
|
if (empty($grade)) {
|
||||||
return completion::INCOMPLETE;
|
return completion::INCOMPLETE;
|
||||||
}
|
}
|
||||||
else if($grade->finalgrade === NULL)
|
else if ($grade->finalgrade === NULL) {
|
||||||
{
|
// on assignments, grade NULL means a submission has not yet been graded,.
|
||||||
// on assignments, grade NULL means a submission has not yet been graded,
|
// but on quizes this can also mean a quiz might have been started.
|
||||||
// but on quizes this can also mean a quiz might have been started
|
// Therefor, we treat a NULL result as a reason to check the relevant gradingscanner for presence of pending items.
|
||||||
// Therefor, we treat a NULL result as a reason to check the relevant gradingscanner for presence of pending items
|
|
||||||
|
|
||||||
// Since we want old results to be visible until a pending item was graded, we only use this state here.
|
// Since we want old results to be visible until a pending item was graded, we only use this state here.
|
||||||
// Pending items are otherwise expressly indicated by the "pendingsubmission" field in the user model
|
// Pending items are otherwise expressly indicated by the "pendingsubmission" field in the user model.
|
||||||
if ($gradeinfo->getGradingscanner()->pending($userid)) {
|
if ($gradeinfo->getGradingscanner()->pending($userid)) {
|
||||||
return completion::PENDING;
|
return completion::PENDING;
|
||||||
} else {
|
} else {
|
||||||
|
@ -174,14 +194,13 @@ class core_aggregator extends \local_treestudyplan\aggregator {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$grade = $gradeitem->get_final($userid);
|
$grade = $gradeitem->get_final($userid);
|
||||||
// first determine if we have a grade_config for this scale or this maximum grade
|
// first determine if we have a grade_config for this scale or this maximum grade.
|
||||||
$finalgrade = $grade->finalgrade;
|
$finalgrade = $grade->finalgrade;
|
||||||
$scale = $gradeinfo->getScale();
|
$scale = $gradeinfo->getScale();
|
||||||
if ( isset($scale)) {
|
if ( isset($scale)) {
|
||||||
$gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]);
|
$gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]);
|
||||||
}
|
}
|
||||||
else if($gradeitem->grademin == 0)
|
else if ($gradeitem->grademin == 0) {
|
||||||
{
|
|
||||||
$gradecfg = $DB->get_record($table, ["grade_points"=>$gradeitem->grademax]);
|
$gradecfg = $DB->get_record($table, ["grade_points"=>$gradeitem->grademax]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -189,34 +208,30 @@ class core_aggregator extends \local_treestudyplan\aggregator {
|
||||||
$gradecfg = null;
|
$gradecfg = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for point grades, a provided grade pass overrides the defaults in the gradeconfig
|
// for point grades, a provided grade pass overrides the defaults in the gradeconfig.
|
||||||
// for scales, the configuration in the gradeconfig is leading
|
// for scales, the configuration in the gradeconfig is leading.
|
||||||
|
|
||||||
if($gradecfg && (isset($scale) || $gradeitem->gradepass == 0))
|
if ($gradecfg && (isset($scale) || $gradeitem->gradepass == 0)) {
|
||||||
{
|
// if so, we need to know if the grade is .
|
||||||
// if so, we need to know if the grade is
|
|
||||||
if ($finalgrade >= $gradecfg->min_completed) {
|
if ($finalgrade >= $gradecfg->min_completed) {
|
||||||
// return completed if completed
|
// return completed if completed.
|
||||||
return completion::COMPLETED;
|
return completion::COMPLETED;
|
||||||
}
|
}
|
||||||
else if($this->use_failed && $finalgrade < $gradecfg->min_progress)
|
else if ($this->use_failed && $finalgrade < $gradecfg->min_progress) {
|
||||||
{
|
// return failed if failed is enabled and the grade is less than the minimum grade for progress.
|
||||||
// return failed if failed is enabled and the grade is less than the minimum grade for progress
|
|
||||||
return completion::FAILED;
|
return completion::FAILED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return completion::PROGRESS;
|
return completion::PROGRESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if($gradeitem->gradepass > 0)
|
else if ($gradeitem->gradepass > 0) {
|
||||||
{
|
|
||||||
$range = floatval($gradeitem->grademax - $gradeitem->grademin);
|
$range = floatval($gradeitem->grademax - $gradeitem->grademin);
|
||||||
// if no gradeconfig and gradepass is set, use that one to determine config.
|
// if no gradeconfig and gradepass is set, use that one to determine config.
|
||||||
if ($finalgrade >= $gradeitem->gradepass) {
|
if ($finalgrade >= $gradeitem->gradepass) {
|
||||||
return completion::COMPLETED;
|
return completion::COMPLETED;
|
||||||
}
|
}
|
||||||
else if($this->use_failed && $gradeitem->gradepass >= 3 && $range >= 3 && $finalgrade == 1)
|
else if ($this->use_failed && $gradeitem->gradepass >= 3 && $range >= 3 && $finalgrade == 1) {
|
||||||
{
|
|
||||||
// return failed if failed is enabled and the grade is 1, while there are at leas 3 states.
|
// return failed if failed is enabled and the grade is 1, while there are at leas 3 states.
|
||||||
return completion::FAILED;
|
return completion::FAILED;
|
||||||
}
|
}
|
||||||
|
@ -225,9 +240,9 @@ class core_aggregator extends \local_treestudyplan\aggregator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Blind assumptions if nothing is provided
|
// Blind assumptions if nothing is provided.
|
||||||
// over 55% of range is completed
|
// over 55% of range is completed.
|
||||||
// if range >= 3 and failed is enabled, assume that this means failed
|
// if range >= 3 and failed is enabled, assume that this means failed.
|
||||||
$g = floatval($finalgrade - $gradeitem->grademin);
|
$g = floatval($finalgrade - $gradeitem->grademin);
|
||||||
$range = floatval($gradeitem->grademax - $gradeitem->grademin);
|
$range = floatval($gradeitem->grademax - $gradeitem->grademin);
|
||||||
$score = $g / $range;
|
$score = $g / $range;
|
||||||
|
@ -235,8 +250,7 @@ class core_aggregator extends \local_treestudyplan\aggregator {
|
||||||
if ($score > 0.55) {
|
if ($score > 0.55) {
|
||||||
return completion::COMPLETED;
|
return completion::COMPLETED;
|
||||||
}
|
}
|
||||||
else if($this->use_failed && $range >= 3 && $finalgrade == 1)
|
else if ($this->use_failed && $range >= 3 && $finalgrade == 1) {
|
||||||
{
|
|
||||||
// return failed if failed is enabled and the grade is 1, while there are at leas 3 states.
|
// return failed if failed is enabled and the grade is 1, while there are at leas 3 states.
|
||||||
return completion::FAILED;
|
return completion::FAILED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace local_treestudyplan\local\aggregators;
|
namespace local_treestudyplan\local\aggregators;
|
||||||
|
|
||||||
|
@ -18,15 +39,14 @@ class tristate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
|
|
||||||
protected function aggregate_completion(array $a, $condition = "50") {
|
protected function aggregate_completion(array $a, $condition = "50") {
|
||||||
if (in_array($condition, ['ALL', '67', '50', 'ANY'])) {
|
if (in_array($condition, ['ALL', '67', '50', 'ANY'])) {
|
||||||
// condition is one of the valid conditions
|
// condition is one of the valid conditions.
|
||||||
$c_completed = 0;
|
$c_completed = 0;
|
||||||
$c_excellent = 0;
|
$c_excellent = 0;
|
||||||
$c_progress = 0;
|
$c_progress = 0;
|
||||||
$c_pending = 0;
|
$c_pending = 0;
|
||||||
$count = sizeof($a);
|
$count = sizeof($a);
|
||||||
|
|
||||||
if($count > 0)
|
if ($count > 0) {
|
||||||
{
|
|
||||||
|
|
||||||
foreach ($a as $c) {
|
foreach ($a as $c) {
|
||||||
$c_progress += ($c>=completion::PROGRESS)?1:0;
|
$c_progress += ($c>=completion::PROGRESS)?1:0;
|
||||||
|
@ -47,8 +67,8 @@ class tristate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
} else if ($c_completed >= $required) {
|
} else if ($c_completed >= $required) {
|
||||||
return completion::COMPLETED;
|
return completion::COMPLETED;
|
||||||
} else {
|
} else {
|
||||||
// Return PROGRESS if one or more completions are COMPLETED or EXCELLENT, but the aggregation margin is not met
|
// Return PROGRESS if one or more completions are COMPLETED or EXCELLENT, but the aggregation margin is not met.
|
||||||
// state PROGRESS will not carry on if aggregations are chained
|
// state PROGRESS will not carry on if aggregations are chained.
|
||||||
if ($c_progress > 0) {
|
if ($c_progress > 0) {
|
||||||
return completion::PROGRESS;
|
return completion::PROGRESS;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +86,7 @@ class tristate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// indeterminable, return null
|
// indeterminable, return null.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +106,7 @@ class tristate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
|
|
||||||
public function aggregate_junction(array $completion, studyitem $studyitem, $userid) {
|
public function aggregate_junction(array $completion, studyitem $studyitem, $userid) {
|
||||||
$completed = self::aggregate_completion($completion, $studyitem->conditions());
|
$completed = self::aggregate_completion($completion, $studyitem->conditions());
|
||||||
// if null result (conditions are unknown/null) - default to ALL
|
// if null result (conditions are unknown/null) - default to ALL.
|
||||||
return isset($completed)?$completed:(self::aggregate_completion($completion, 'ALL'));
|
return isset($completed)?$completed:(self::aggregate_completion($completion, 'ALL'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,14 +118,13 @@ class tristate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
if (empty($grade)) {
|
if (empty($grade)) {
|
||||||
return completion::INCOMPLETE;
|
return completion::INCOMPLETE;
|
||||||
}
|
}
|
||||||
else if($grade->finalgrade === NULL)
|
else if ($grade->finalgrade === NULL) {
|
||||||
{
|
// on assignments, grade NULL means a submission has not yet been graded,.
|
||||||
// on assignments, grade NULL means a submission has not yet been graded,
|
// but on quizes this can also mean a quiz might have been started.
|
||||||
// but on quizes this can also mean a quiz might have been started
|
// Therefor, we treat a NULL result as a reason to check the relevant gradingscanner for presence of pending items.
|
||||||
// Therefor, we treat a NULL result as a reason to check the relevant gradingscanner for presence of pending items
|
|
||||||
|
|
||||||
// Since we want old results to be visible until a pending item was graded, we only use this state here.
|
// Since we want old results to be visible until a pending item was graded, we only use this state here.
|
||||||
// Pending items are otherwise expressly indicated by the "pendingsubmission" field in the user model
|
// Pending items are otherwise expressly indicated by the "pendingsubmission" field in the user model.
|
||||||
if ($gradeinfo->getGradingscanner()->pending($userid)) {
|
if ($gradeinfo->getGradingscanner()->pending($userid)) {
|
||||||
return completion::PENDING;
|
return completion::PENDING;
|
||||||
} else {
|
} else {
|
||||||
|
@ -117,11 +136,10 @@ class tristate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
$finalgrade = $grade->finalgrade;
|
$finalgrade = $grade->finalgrade;
|
||||||
$scale = $gradeinfo->getScale();
|
$scale = $gradeinfo->getScale();
|
||||||
|
|
||||||
if($gradeitem->gradepass > 0)
|
if ($gradeitem->gradepass > 0) {
|
||||||
{
|
// Base completion off of gradepass (if set).
|
||||||
// Base completion off of gradepass (if set)
|
|
||||||
if ($gradeitem->grademax > $gradeitem->gradepass && $finalgrade >= $gradeitem->grademax) {
|
if ($gradeitem->grademax > $gradeitem->gradepass && $finalgrade >= $gradeitem->grademax) {
|
||||||
// If gradepass is configured
|
// If gradepass is configured .
|
||||||
return completion::EXCELLENT;
|
return completion::EXCELLENT;
|
||||||
}
|
}
|
||||||
else if ($finalgrade >= $gradeitem->gradepass) {
|
else if ($finalgrade >= $gradeitem->gradepass) {
|
||||||
|
@ -132,9 +150,9 @@ class tristate_aggregator extends \local_treestudyplan\aggregator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Blind assumptions:
|
// Blind assumptions:.
|
||||||
// over 55% of range is completed
|
// over 55% of range is completed.
|
||||||
// over 85% of range is excellent
|
// over 85% of range is excellent.
|
||||||
$g = floatval($finalgrade - $gradeitem->grademin);
|
$g = floatval($finalgrade - $gradeitem->grademin);
|
||||||
$range = floatval($gradeitem->grademax - $gradeitem->grademin);
|
$range = floatval($gradeitem->grademax - $gradeitem->grademin);
|
||||||
$score = $g / $range;
|
$score = $g / $range;
|
||||||
|
|
|
@ -1,4 +1,26 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace local_treestudyplan\local;
|
namespace local_treestudyplan\local;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
@ -66,10 +88,10 @@ class gradegenerator {
|
||||||
|
|
||||||
private function generatedfeedback() {
|
private function generatedfeedback() {
|
||||||
if (file_exists("/usr/games/fortune")) {
|
if (file_exists("/usr/games/fortune")) {
|
||||||
// get a fortune if it is available
|
// get a fortune if it is available.
|
||||||
return shell_exec("/usr/games/fortune -n 160 -e disclaimer literature science pratchett wisdom education");
|
return shell_exec("/usr/games/fortune -n 160 -e disclaimer literature science pratchett wisdom education");
|
||||||
} else {
|
} else {
|
||||||
// get a random loremipsum string
|
// get a random loremipsum string.
|
||||||
return self::$loremipsum[rand(0, count(self::$loremipsum)-1)];
|
return self::$loremipsum[rand(0, count(self::$loremipsum)-1)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,15 +123,14 @@ class gradegenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Below is mostly just for reference in the json file
|
// Below is mostly just for reference in the json file.
|
||||||
public function addUserNameInfo(string $student, $firstname, $lastname) {
|
public function addUserNameInfo(string $student, $firstname, $lastname) {
|
||||||
$this->addstudent($student);
|
$this->addstudent($student);
|
||||||
$this->table[$student]["firstname"] = $firstname;
|
$this->table[$student]["firstname"] = $firstname;
|
||||||
$this->table[$student]["lastname"] = $lastname;
|
$this->table[$student]["lastname"] = $lastname;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateraw($student,$skill, $count )
|
public function generateraw($student, $skill, $count ) {
|
||||||
{
|
|
||||||
$this->addskill($student, $skill);
|
$this->addskill($student, $skill);
|
||||||
$int = $this->table[$student]["skills"][$skill]["intelligence"];
|
$int = $this->table[$student]["skills"][$skill]["intelligence"];
|
||||||
$end = $this->table[$student]["skills"][$skill]["endurance"];
|
$end = $this->table[$student]["skills"][$skill]["endurance"];
|
||||||
|
@ -121,24 +142,24 @@ class gradegenerator {
|
||||||
if ($gaveup) {
|
if ($gaveup) {
|
||||||
$r->done = !$gaveup;
|
$r->done = !$gaveup;
|
||||||
} else {
|
} else {
|
||||||
$r->done = (rand(0, $end) > 20); // Determine if the assignment was done
|
$r->done = (rand(0, $end) > 20); // Determine if the assignment was done.
|
||||||
}
|
}
|
||||||
if ($r->done) {
|
if ($r->done) {
|
||||||
$score = rand(0, $int) ;
|
$score = rand(0, $int) ;
|
||||||
$r->result = ($score > 20); // determine if the assignment was successful
|
$r->result = ($score > 20); // determine if the assignment was successful.
|
||||||
if (!$r->result) {
|
if (!$r->result) {
|
||||||
$r->failed = !($score > 10);
|
$r->failed = !($score > 10);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$r->result = false; // make sure a result property is always there
|
$r->result = false; // make sure a result property is always there.
|
||||||
$r->failed = true;
|
$r->failed = true;
|
||||||
}
|
}
|
||||||
// Aways generate a little feedback
|
// Aways generate a little feedback.
|
||||||
$r->fb = $this->generatedfeedback();
|
$r->fb = $this->generatedfeedback();
|
||||||
$results[] = $r;
|
$results[] = $r;
|
||||||
|
|
||||||
if (!$gaveup && $i >= 3) {
|
if (!$gaveup && $i >= 3) {
|
||||||
// There is a slight chance the students with low endurance for this course will stop with this course's work entirely
|
// There is a slight chance the students with low endurance for this course will stop with this course's work entirely.
|
||||||
$gaveup = (rand(0, $end) < 15);
|
$gaveup = (rand(0, $end) < 15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,13 +178,12 @@ class gradegenerator {
|
||||||
$gi = $g->getGradeitem();
|
$gi = $g->getGradeitem();
|
||||||
$gr = $gen[$i];
|
$gr = $gen[$i];
|
||||||
|
|
||||||
// First get the configured interpretation for this scale or grade
|
// First get the configured interpretation for this scale or grade.
|
||||||
$scale = $gi->load_scale();
|
$scale = $gi->load_scale();
|
||||||
if ( isset($scale)) {
|
if ( isset($scale)) {
|
||||||
$gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]);
|
$gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]);
|
||||||
}
|
}
|
||||||
else if($gi->grademin == 0)
|
else if ($gi->grademin == 0) {
|
||||||
{
|
|
||||||
$gradecfg = $DB->get_record($table, ["grade_points"=>$gi->grademax]);
|
$gradecfg = $DB->get_record($table, ["grade_points"=>$gi->grademax]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -171,13 +191,12 @@ class gradegenerator {
|
||||||
$gradecfg = null;
|
$gradecfg = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// next generate the grade
|
// next generate the grade.
|
||||||
if($gradecfg)
|
if ($gradecfg) {
|
||||||
{
|
|
||||||
if (!$gr->done) {
|
if (!$gr->done) {
|
||||||
// INCOMPLETE
|
// INCOMPLETE.
|
||||||
// fair chance of teacher forgetting to set incomplete to "no evidence"
|
// fair chance of teacher forgetting to set incomplete to "no evidence".
|
||||||
$grade = 0;// $grade = (rand(0,100) > 15)?max(1, $gradecfg->min_progress-1):"0";
|
$grade = 0;// $grade = (rand(0, 100) > 15)?max(1, $gradecfg->min_progress-1):"0";.
|
||||||
$r = (object)["gi" => $g, "grade" => $grade, "fb" =>"" ];
|
$r = (object)["gi" => $g, "grade" => $grade, "fb" =>"" ];
|
||||||
}
|
}
|
||||||
else if (!$gr->result) {
|
else if (!$gr->result) {
|
||||||
|
@ -185,7 +204,7 @@ class gradegenerator {
|
||||||
$r = (object)["gi" => $g, "grade" => $grade, "fb" =>$gr->fb ];
|
$r = (object)["gi" => $g, "grade" => $grade, "fb" =>$gr->fb ];
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// COMPLETED
|
// COMPLETED.
|
||||||
$r = (object)["gi" => $g, "grade" => rand( $gradecfg->min_completed, $gi->grademax ), "fb" =>$gr->fb ];
|
$r = (object)["gi" => $g, "grade" => rand( $gradecfg->min_completed, $gi->grademax ), "fb" =>$gr->fb ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,41 +219,40 @@ class gradegenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if($gi->gradepass > 0)
|
else if ($gi->gradepass > 0) {
|
||||||
{
|
|
||||||
if (!$gr->done) {
|
if (!$gr->done) {
|
||||||
// INCOMPLETe or FAILED
|
// INCOMPLETe or FAILED.
|
||||||
$grade = rand(0, $gi->gradepass/2);
|
$grade = rand(0, $gi->gradepass/2);
|
||||||
$r = (object)["gi" => $g, "grade" => $grade, "fb" =>($grade > 0)?$gr->fb:"" ];
|
$r = (object)["gi" => $g, "grade" => $grade, "fb" =>($grade > 0)?$gr->fb:"" ];
|
||||||
}
|
}
|
||||||
else if (!$gr->result) {
|
else if (!$gr->result) {
|
||||||
//PROGRESS
|
//PROGRESS.
|
||||||
$r = (object)["gi" => $g, "grade" => rand( round($gi->gradepass/2), $gi->gradepass -1 ), "fb" =>$gr->fb ];
|
$r = (object)["gi" => $g, "grade" => rand( round($gi->gradepass/2), $gi->gradepass -1 ), "fb" =>$gr->fb ];
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// COMPLETED
|
// COMPLETED.
|
||||||
$r = (object)["gi" => $g, "grade" => rand( $gi->gradepass, $gi->grademax ), "fb" =>$gr->fb ];
|
$r = (object)["gi" => $g, "grade" => rand( $gi->gradepass, $gi->grademax ), "fb" =>$gr->fb ];
|
||||||
}
|
}
|
||||||
|
|
||||||
$r->gradetext = $r->grade;
|
$r->gradetext = $r->grade;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Blind assumptions if nothing is provided
|
// Blind assumptions if nothing is provided.
|
||||||
// over 55% of range is completed
|
// over 55% of range is completed.
|
||||||
// under 35% is not done
|
// under 35% is not done.
|
||||||
$range = floatval($gi->grademax - $gi->grademin);
|
$range = floatval($gi->grademax - $gi->grademin);
|
||||||
|
|
||||||
if (!$gr->done) {
|
if (!$gr->done) {
|
||||||
// INCOMPLETe or FAILED
|
// INCOMPLETe or FAILED.
|
||||||
$grade = rand(0, round($range * 0.35) - 1);
|
$grade = rand(0, round($range * 0.35) - 1);
|
||||||
$r = (object)["gi" => $g, "grade" => $gi->grademin+$grade, "fb" =>($grade > 0)?$gr->fb:"" ];
|
$r = (object)["gi" => $g, "grade" => $gi->grademin+$grade, "fb" =>($grade > 0)?$gr->fb:"" ];
|
||||||
}
|
}
|
||||||
else if (!$gr->result) {
|
else if (!$gr->result) {
|
||||||
//PROGRESS
|
//PROGRESS.
|
||||||
$r = (object)["gi" => $g, "grade" => $gi->grademin+rand(round($range * 0.35), round($range * 0.55) - 1 ), "fb" =>$gr->fb ];
|
$r = (object)["gi" => $g, "grade" => $gi->grademin+rand(round($range * 0.35), round($range * 0.55) - 1 ), "fb" =>$gr->fb ];
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// COMPLETED
|
// COMPLETED.
|
||||||
$r = (object)["gi" => $g, "grade" => $gi->grademin+rand(round($range * 0.55) , $range ), "fb" =>$gr->fb ];
|
$r = (object)["gi" => $g, "grade" => $gi->grademin+rand(round($range * 0.55) , $range ), "fb" =>$gr->fb ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,13 +292,12 @@ class gradegenerator {
|
||||||
$this->unserialize($json);
|
$this->unserialize($json);
|
||||||
} catch(Exception $x) {
|
} catch(Exception $x) {
|
||||||
cli_problem("ERROR loading from file");
|
cli_problem("ERROR loading from file");
|
||||||
throw $x; // Throw X up again to show the output
|
throw $x; // Throw X up again to show the output.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function expand_tilde($path)
|
private static function expand_tilde($path) {
|
||||||
{
|
|
||||||
if (function_exists('posix_getuid') && strpos($path, '~') !== false) {
|
if (function_exists('posix_getuid') && strpos($path, '~') !== false) {
|
||||||
$info = posix_getpwuid(posix_getuid());
|
$info = posix_getpwuid(posix_getuid());
|
||||||
$path = str_replace('~', $info['dir'], $path);
|
$path = str_replace('~', $info['dir'], $path);
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace local_treestudyplan\local\helpers;
|
namespace local_treestudyplan\local\helpers;
|
||||||
|
|
||||||
|
@ -10,20 +31,18 @@ class debugger {
|
||||||
private $tag;
|
private $tag;
|
||||||
private $enabled = false;
|
private $enabled = false;
|
||||||
|
|
||||||
public function __construct($filename,$tag)
|
public function __construct($filename, $tag) {
|
||||||
{
|
|
||||||
global $CFG;
|
global $CFG;
|
||||||
|
|
||||||
$this->fname = $filename;
|
$this->fname = $filename;
|
||||||
$this->tag = $tag;
|
$this->tag = $tag;
|
||||||
|
|
||||||
// assume debug environment if cachejs is false
|
// assume debug environment if cachejs is false.
|
||||||
$this->enabled = (isset($CFG->cachejs) && $CFG->cachejs == false);
|
$this->enabled = (isset($CFG->cachejs) && $CFG->cachejs == false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function dump($object,string $tag="")
|
public function dump($object, string $tag="") {
|
||||||
{
|
|
||||||
if (strlen($tag) > 0) {
|
if (strlen($tag) > 0) {
|
||||||
$tag .= ":\n";
|
$tag .= ":\n";
|
||||||
}
|
}
|
||||||
|
@ -31,8 +50,7 @@ class debugger {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function write($str)
|
public function write($str) {
|
||||||
{
|
|
||||||
$this->writeblock($str);
|
$this->writeblock($str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace local_treestudyplan\local\helpers;
|
namespace local_treestudyplan\local\helpers;
|
||||||
require_once($CFG->dirroot.'/webservice/lib.php');
|
require_once($CFG->dirroot.'/webservice/lib.php');
|
||||||
|
@ -24,7 +45,7 @@ class webservicehelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_array($capability)) {
|
if (is_array($capability)) {
|
||||||
//TODO: replace this by accesslib function \has_any_capability()
|
//TODO: replace this by accesslib function \has_any_capability().
|
||||||
foreach ($capability as $cap) {
|
foreach ($capability as $cap) {
|
||||||
if (has_capability($cap, $context)) {
|
if (has_capability($cap, $context)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -44,9 +65,9 @@ class webservicehelper {
|
||||||
*/
|
*/
|
||||||
public static function has_capability_in_any_category($capability, \core_course_category $parent=null) {
|
public static function has_capability_in_any_category($capability, \core_course_category $parent=null) {
|
||||||
|
|
||||||
// List the categories in which the user has a specific capability
|
// List the categories in which the user has a specific capability.
|
||||||
$list = [];
|
$list = [];
|
||||||
// initialize parent if needed
|
// initialize parent if needed.
|
||||||
if ($parent == null) {
|
if ($parent == null) {
|
||||||
$parent = \core_course_category::user_top();
|
$parent = \core_course_category::user_top();
|
||||||
if (has_capability($capability, $parent->get_context())) {
|
if (has_capability($capability, $parent->get_context())) {
|
||||||
|
@ -55,16 +76,16 @@ class webservicehelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
$children = $parent->get_children();
|
$children = $parent->get_children();
|
||||||
// Since the change for a category permission is greatest at the lower levels,
|
// Since the change for a category permission is greatest at the lower levels,.
|
||||||
// we scan in two stages, to focus the search more on the lower levels instead of diving deep into the first category
|
// we scan in two stages, to focus the search more on the lower levels instead of diving deep into the first category.
|
||||||
// Stage one (surface check): check all children for the capability
|
// Stage one (surface check): check all children for the capability.
|
||||||
foreach ($children as $child) {
|
foreach ($children as $child) {
|
||||||
// Check if we should add this category
|
// Check if we should add this category.
|
||||||
if (has_capability($capability, $child->get_context())) {
|
if (has_capability($capability, $child->get_context())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Stage two (deep dive): recurse into the child categories
|
// Stage two (deep dive): recurse into the child categories.
|
||||||
foreach ($children as $child) {
|
foreach ($children as $child) {
|
||||||
if ($child->get_children_count() > 0) {
|
if ($child->get_children_count() > 0) {
|
||||||
if (self::has_capability_in_any_category($capability, $child)) {
|
if (self::has_capability_in_any_category($capability, $child)) {
|
||||||
|
@ -105,16 +126,16 @@ class webservicehelper {
|
||||||
$context = \context::instance_by_id($contextid);
|
$context = \context::instance_by_id($contextid);
|
||||||
}
|
}
|
||||||
catch(\dml_missing_record_exception $x) {
|
catch(\dml_missing_record_exception $x) {
|
||||||
throw new \InvalidArgumentException("Context {$contextid} not available"); // Just throw it up again. catch is included here to make sure we know it throws this exception
|
throw new \InvalidArgumentException("Context {$contextid} not available"); // Just throw it up again. catch is included here to make sure we know it throws this exception.
|
||||||
}
|
}
|
||||||
// Validate the found context
|
// Validate the found context.
|
||||||
\external_api::validate_context($context);
|
\external_api::validate_context($context);
|
||||||
self::$validated_contexts[$contextid] = $context;
|
self::$validated_contexts[$contextid] = $context;
|
||||||
}
|
}
|
||||||
return self::$validated_contexts[$contextid];
|
return self::$validated_contexts[$contextid];
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
return static::system_context(); // This function ensures the system context is validated just once this call
|
return static::system_context(); // This function ensures the system context is validated just once this call.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace local_treestudyplan\local\ungradedscanners;
|
namespace local_treestudyplan\local\ungradedscanners;
|
||||||
|
|
||||||
|
@ -7,7 +28,7 @@ class assign_scanner extends scanner_base {
|
||||||
|
|
||||||
protected function get_ungraded_submissions() {
|
protected function get_ungraded_submissions() {
|
||||||
global $DB;
|
global $DB;
|
||||||
//SELECT asgn_sub.id as submissionid, a.id as instanceid, asgn_sub.userid as userid, asgn_sub.timemodified as timesubmitted, asgn_sub.attemptnumber , a.maxattempts
|
//SELECT asgn_sub.id as submissionid, a.id as instanceid, asgn_sub.userid as userid, asgn_sub.timemodified as timesubmitted, asgn_sub.attemptnumber , a.maxattempts.
|
||||||
$sql = "SELECT DISTINCT asgn_sub.userid
|
$sql = "SELECT DISTINCT asgn_sub.userid
|
||||||
FROM {assign_submission} asgn_sub
|
FROM {assign_submission} asgn_sub
|
||||||
JOIN {assign} a ON a.id = asgn_sub.assignment
|
JOIN {assign} a ON a.id = asgn_sub.assignment
|
||||||
|
@ -28,7 +49,7 @@ class assign_scanner extends scanner_base {
|
||||||
FROM {grade_grades} g
|
FROM {grade_grades} g
|
||||||
LEFT JOIN {grade_items} gi on g.itemid = gi.id
|
LEFT JOIN {grade_items} gi on g.itemid = gi.id
|
||||||
WHERE gi.itemmodule = 'assign' AND gi.iteminstance = {$this->gi->iteminstance}
|
WHERE gi.itemmodule = 'assign' AND gi.iteminstance = {$this->gi->iteminstance}
|
||||||
AND g.finalgrade IS NOT NULL"; // MAy turn out to be needed, dunno
|
AND g.finalgrade IS NOT NULL"; // MAy turn out to be needed, dunno.
|
||||||
return $DB->get_fieldset_sql($sql);
|
return $DB->get_fieldset_sql($sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,14 +72,13 @@ class assign_scanner extends scanner_base {
|
||||||
$graded = array_intersect($graded, $course_userids);
|
$graded = array_intersect($graded, $course_userids);
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine how many id's have a grade, but also an ungraded submission
|
// determine how many id's have a grade, but also an ungraded submission.
|
||||||
$dual = array_intersect($ungraded, $graded);
|
$dual = array_intersect($ungraded, $graded);
|
||||||
// subtract those from the graded count
|
// subtract those from the graded count.
|
||||||
return count($graded) - count($dual);
|
return count($graded) - count($dual);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function has_ungraded_submission($userid)
|
public function has_ungraded_submission($userid) {
|
||||||
{
|
|
||||||
$ungraded = $this->get_ungraded_submissions();
|
$ungraded = $this->get_ungraded_submissions();
|
||||||
return in_array($userid, $ungraded);
|
return in_array($userid, $ungraded);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,38 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace local_treestudyplan\local\ungradedscanners;
|
namespace local_treestudyplan\local\ungradedscanners;
|
||||||
|
|
||||||
require_once($CFG->dirroot.'/question/engine/states.php'); // for reading question state
|
require_once($CFG->dirroot.'/question/engine/states.php'); // for reading question state.
|
||||||
|
|
||||||
|
|
||||||
class quiz_scanner extends scanner_base {
|
class quiz_scanner extends scanner_base {
|
||||||
|
|
||||||
protected function get_ungraded_submissions() {
|
protected function get_ungraded_submissions() {
|
||||||
// count all users who have one or more questions that still need grading
|
// count all users who have one or more questions that still need grading.
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
// First find all question attempts that need grading
|
// First find all question attempts that need grading.
|
||||||
$sql = "SELECT qza.id as submissionid, qza.userid as userid, qas.questionattemptid as attempt_id, qas.sequencenumber as sequencenumber
|
$sql = "SELECT qza.id as submissionid, qza.userid as userid, qas.questionattemptid as attempt_id, qas.sequencenumber as sequencenumber
|
||||||
FROM {question_attempt_steps} qas
|
FROM {question_attempt_steps} qas
|
||||||
JOIN {question_attempts} qna ON qas.questionattemptid = qna.id
|
JOIN {question_attempts} qna ON qas.questionattemptid = qna.id
|
||||||
|
@ -21,11 +42,11 @@ class quiz_scanner extends scanner_base {
|
||||||
$rs = $DB->get_recordset_sql($sql);
|
$rs = $DB->get_recordset_sql($sql);
|
||||||
$submissions = [];
|
$submissions = [];
|
||||||
foreach ($rs as $r) {
|
foreach ($rs as $r) {
|
||||||
// Now, check if
|
// Now, check if .
|
||||||
$maxstate_sql = "SELECT MAX(qas.sequencenumber) FROM {question_attempt_steps} qas WHERE qas.questionattemptid = {$r->attempt_id}";
|
$maxstate_sql = "SELECT MAX(qas.sequencenumber) FROM {question_attempt_steps} qas WHERE qas.questionattemptid = {$r->attempt_id}";
|
||||||
$max = $DB->get_field_sql($maxstate_sql);
|
$max = $DB->get_field_sql($maxstate_sql);
|
||||||
if ($r->sequencenumber == $max) {
|
if ($r->sequencenumber == $max) {
|
||||||
$submissions[$r->userid] = true; // set array index based on user id, to avoid checking if value is in array
|
$submissions[$r->userid] = true; // set array index based on user id, to avoid checking if value is in array.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$rs->close();
|
$rs->close();
|
||||||
|
@ -47,7 +68,7 @@ class quiz_scanner extends scanner_base {
|
||||||
FROM {grade_grades} g
|
FROM {grade_grades} g
|
||||||
LEFT JOIN {grade_items} gi on g.itemid = gi.id
|
LEFT JOIN {grade_items} gi on g.itemid = gi.id
|
||||||
WHERE gi.itemmodule = 'quiz' AND gi.iteminstance = {$this->gi->iteminstance}
|
WHERE gi.itemmodule = 'quiz' AND gi.iteminstance = {$this->gi->iteminstance}
|
||||||
AND g.finalgrade IS NOT NULL"; // MAy turn out to be needed, dunno
|
AND g.finalgrade IS NOT NULL"; // MAy turn out to be needed, dunno.
|
||||||
|
|
||||||
$graded = $DB->get_fieldset_sql($sql);
|
$graded = $DB->get_fieldset_sql($sql);
|
||||||
|
|
||||||
|
@ -58,8 +79,7 @@ class quiz_scanner extends scanner_base {
|
||||||
return count($graded);
|
return count($graded);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function has_ungraded_submission($userid)
|
public function has_ungraded_submission($userid) {
|
||||||
{
|
|
||||||
$ungraded = $this->get_ungraded_submissions();
|
$ungraded = $this->get_ungraded_submissions();
|
||||||
return in_array($userid, $ungraded);
|
return in_array($userid, $ungraded);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace local_treestudyplan\local\ungradedscanners;
|
namespace local_treestudyplan\local\ungradedscanners;
|
||||||
use \grade_item;
|
use \grade_item;
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
|
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
@ -9,7 +30,7 @@ class period {
|
||||||
private static $PAGECACHE = [];
|
private static $PAGECACHE = [];
|
||||||
|
|
||||||
|
|
||||||
private $r; // Holds database record
|
private $r; // Holds database record.
|
||||||
private $id;
|
private $id;
|
||||||
private $page;
|
private $page;
|
||||||
|
|
||||||
|
@ -31,7 +52,7 @@ class period {
|
||||||
public static function find(studyplanpage $page, $periodnr): self{
|
public static function find(studyplanpage $page, $periodnr): self{
|
||||||
global $DB;
|
global $DB;
|
||||||
if ($periodnr < 1) {
|
if ($periodnr < 1) {
|
||||||
// Clamp period index
|
// Clamp period index .
|
||||||
$periodnr = 1;
|
$periodnr = 1;
|
||||||
}
|
}
|
||||||
try{
|
try{
|
||||||
|
@ -39,34 +60,34 @@ class period {
|
||||||
$period = self::findById($id);
|
$period = self::findById($id);
|
||||||
} catch(\dml_missing_record_exception $x) {
|
} catch(\dml_missing_record_exception $x) {
|
||||||
// Period does not exist - create one ...
|
// Period does not exist - create one ...
|
||||||
// Make a best guess estimate of the start and end date, based on surrounding periods,
|
// Make a best guess estimate of the start and end date, based on surrounding periods,.
|
||||||
// or specified duration of the page and the sequence of the periods
|
// or specified duration of the page and the sequence of the periods .
|
||||||
$pcount = $page->periods();
|
$pcount = $page->periods();
|
||||||
$ystart = $page->startdate()->getTimestamp();
|
$ystart = $page->startdate()->getTimestamp();
|
||||||
$yend = $page->enddate()->getTimestamp();
|
$yend = $page->enddate()->getTimestamp();
|
||||||
|
|
||||||
// Estimate the period's timing to make a reasonable first guess
|
// Estimate the period's timing to make a reasonable first guess.
|
||||||
$ydelta = $yend - $ystart;
|
$ydelta = $yend - $ystart;
|
||||||
$ptime = $ydelta / $pcount;
|
$ptime = $ydelta / $pcount;
|
||||||
|
|
||||||
try{
|
try{
|
||||||
// Check if we have a previous period to glance the end date of as a reference
|
// Check if we have a previous period to glance the end date of as a reference.
|
||||||
$startdate = $DB->get_field(self::TABLE, "enddate", ["page_id"=>$page->id(), "period" => $periodnr-1], MUST_EXIST);
|
$startdate = $DB->get_field(self::TABLE, "enddate", ["page_id"=>$page->id(), "period" => $periodnr-1], MUST_EXIST);
|
||||||
$pstart = strtotime($startdate)+(24*60*60); // Add one day
|
$pstart = strtotime($startdate)+(24*60*60); // Add one day.
|
||||||
} catch(\dml_missing_record_exception $x2) {
|
} catch(\dml_missing_record_exception $x2) {
|
||||||
// If not, do a fair guess
|
// If not, do a fair guess.
|
||||||
$pstart = $ystart + (($periodnr-1)*$ptime);
|
$pstart = $ystart + (($periodnr-1)*$ptime);
|
||||||
}
|
}
|
||||||
try{
|
try{
|
||||||
// Check if we have a next period to glance the start date of as a reference
|
// Check if we have a next period to glance the start date of as a reference.
|
||||||
$enddate = $DB->get_field(self::TABLE, "startdate", ["page_id"=>$page->id(), "period" => $periodnr+1], MUST_EXIST);
|
$enddate = $DB->get_field(self::TABLE, "startdate", ["page_id"=>$page->id(), "period" => $periodnr+1], MUST_EXIST);
|
||||||
$pstart = strtotime($enddate)-(24*60*60); // subtract one day
|
$pstart = strtotime($enddate)-(24*60*60); // subtract one day.
|
||||||
} catch(\dml_missing_record_exception $x2) {
|
} catch(\dml_missing_record_exception $x2) {
|
||||||
// If not, do a fair guess
|
// If not, do a fair guess.
|
||||||
$pend = $pstart + $ptime;
|
$pend = $pstart + $ptime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// And create the period
|
// And create the period.
|
||||||
$period = self::add([
|
$period = self::add([
|
||||||
'page_id' => $page->id(),
|
'page_id' => $page->id(),
|
||||||
'period' => $periodnr,
|
'period' => $periodnr,
|
||||||
|
@ -83,7 +104,7 @@ class period {
|
||||||
public static function findForPage(studyplanpage $page): array {
|
public static function findForPage(studyplanpage $page): array {
|
||||||
if (!array_key_exists($page->id(), self::$PAGECACHE)) {
|
if (!array_key_exists($page->id(), self::$PAGECACHE)) {
|
||||||
$periods = [];
|
$periods = [];
|
||||||
// find and add the periods to an array with the period sequence as a key
|
// find and add the periods to an array with the period sequence as a key.
|
||||||
for($i=1; $i <= $page->periods(); $i++) {
|
for($i=1; $i <= $page->periods(); $i++) {
|
||||||
$period = self::find($page, $i);
|
$period = self::find($page, $i);
|
||||||
$periods[$i] = $period;
|
$periods[$i] = $period;
|
||||||
|
@ -133,7 +154,7 @@ class period {
|
||||||
return new \DateTime($this->r->enddate);
|
return new \DateTime($this->r->enddate);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// return a date 100 years into the future
|
// return a date 100 years into the future.
|
||||||
return (new \DateTime($this->r->startdate))->add(new \DateInterval("P100Y"));
|
return (new \DateTime($this->r->startdate))->add(new \DateInterval("P100Y"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,8 +207,8 @@ class period {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$id = $DB->insert_record(self::TABLE, $info);
|
$id = $DB->insert_record(self::TABLE, $info);
|
||||||
unset(self::$PAGECACHE[$fields['page_id']]); // invalidate the cache for this page
|
unset(self::$PAGECACHE[$fields['page_id']]); // invalidate the cache for this page.
|
||||||
return self::findById($id); // make sure the new page is immediately cached
|
return self::findById($id); // make sure the new page is immediately cached.
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit($fields) {
|
public function edit($fields) {
|
||||||
|
@ -200,16 +221,16 @@ class period {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$DB->update_record(self::TABLE, $info);
|
$DB->update_record(self::TABLE, $info);
|
||||||
//reload record after edit
|
//reload record after edit.
|
||||||
$this->r = $DB->get_record(self::TABLE, ['id' => $this->id], "*", MUST_EXIST);
|
$this->r = $DB->get_record(self::TABLE, ['id' => $this->id], "*", MUST_EXIST);
|
||||||
unset(self::$PAGECACHE[$this->r->page_id]); // invalidate the cache for this page
|
unset(self::$PAGECACHE[$this->r->page_id]); // invalidate the cache for this page.
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete() {
|
public function delete() {
|
||||||
global $DB;
|
global $DB;
|
||||||
$DB->delete_records(self::TABLE, ['id' => $this->id]);
|
$DB->delete_records(self::TABLE, ['id' => $this->id]);
|
||||||
unset(self::$PAGECACHE[$this->r->page_id]); // invalidate the cache for this page
|
unset(self::$PAGECACHE[$this->r->page_id]); // invalidate the cache for this page.
|
||||||
return success::success();
|
return success::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
namespace local_treestudyplan\privacy;
|
namespace local_treestudyplan\privacy;
|
||||||
use core_privacy\local\metadata\collection;
|
use core_privacy\local\metadata\collection;
|
||||||
|
@ -57,9 +78,9 @@ class provider implements \core_privacy\local\metadata\provider,
|
||||||
*/
|
*/
|
||||||
public static function get_contexts_for_userid(int $userid) : contextlist {
|
public static function get_contexts_for_userid(int $userid) : contextlist {
|
||||||
$contextlist = new \core_privacy\local\request\contextlist();
|
$contextlist = new \core_privacy\local\request\contextlist();
|
||||||
$contextlist->add_system_context(); // For invitations
|
$contextlist->add_system_context(); // For invitations.
|
||||||
|
|
||||||
// add contexts for linked studyplans
|
// add contexts for linked studyplans.
|
||||||
$sql = "SELECT s.context_id FROM {local_treestudyplan} s
|
$sql = "SELECT s.context_id FROM {local_treestudyplan} s
|
||||||
INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
|
INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
|
||||||
WHERE ( a.user_id = :userid )
|
WHERE ( a.user_id = :userid )
|
||||||
|
@ -81,7 +102,7 @@ class provider implements \core_privacy\local\metadata\provider,
|
||||||
$user = $contextlist->get_user();
|
$user = $contextlist->get_user();
|
||||||
|
|
||||||
if ($context instanceof \context_system) {
|
if ($context instanceof \context_system) {
|
||||||
// Export invitations
|
// Export invitations.
|
||||||
$sql = "SELECT * FROM {local_treestudyplan_invit} i
|
$sql = "SELECT * FROM {local_treestudyplan_invit} i
|
||||||
WHERE ( aiuser_id = :userid )
|
WHERE ( aiuser_id = :userid )
|
||||||
";
|
";
|
||||||
|
@ -90,7 +111,7 @@ class provider implements \core_privacy\local\metadata\provider,
|
||||||
static::export_invitation_data_for_user($r);
|
static::export_invitation_data_for_user($r);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export empty associations
|
// Export empty associations.
|
||||||
$sql = "SELECT * FROM {local_treestudyplan} s
|
$sql = "SELECT * FROM {local_treestudyplan} s
|
||||||
INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
|
INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
|
||||||
WHERE ( a.user_id = :userid AND (s.context_id IS NULL or s.context_id = 0)
|
WHERE ( a.user_id = :userid AND (s.context_id IS NULL or s.context_id = 0)
|
||||||
|
@ -100,7 +121,7 @@ class provider implements \core_privacy\local\metadata\provider,
|
||||||
static::export_studyplan_data_for_user($r);
|
static::export_studyplan_data_for_user($r);
|
||||||
}
|
}
|
||||||
} else if ($context->contextlevel == CONTEXT_COURSECAT) {
|
} else if ($context->contextlevel == CONTEXT_COURSECAT) {
|
||||||
// Export studyplan associations
|
// Export studyplan associations.
|
||||||
$sql = "SELECT * FROM {local_treestudyplan} s
|
$sql = "SELECT * FROM {local_treestudyplan} s
|
||||||
INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
|
INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
|
||||||
WHERE ( a.user_id = :userid AND s.context_id = :contextid)
|
WHERE ( a.user_id = :userid AND s.context_id = :contextid)
|
||||||
|
@ -151,7 +172,7 @@ class provider implements \core_privacy\local\metadata\provider,
|
||||||
*/
|
*/
|
||||||
public static function delete_data_for_all_users_in_context(\context $context) {
|
public static function delete_data_for_all_users_in_context(\context $context) {
|
||||||
global $DB;
|
global $DB;
|
||||||
// find studyplans in context
|
// find studyplans in context.
|
||||||
if ($context->contextlevel == CONTEXT_COURSECAT) {
|
if ($context->contextlevel == CONTEXT_COURSECAT) {
|
||||||
$sql = "SELECT s.id FROM {local_treestudyplan} WHERE ( a.user_id = :userid AND s.context_id = :contextid)";
|
$sql = "SELECT s.id FROM {local_treestudyplan} WHERE ( a.user_id = :userid AND s.context_id = :contextid)";
|
||||||
$plan_ids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id]);
|
$plan_ids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id]);
|
||||||
|
@ -183,7 +204,7 @@ class provider implements \core_privacy\local\metadata\provider,
|
||||||
$DB->delete_records("local_treestudyplan_user", ["studyplan_id" => $plan_id, "user_id" => $user->id]);
|
$DB->delete_records("local_treestudyplan_user", ["studyplan_id" => $plan_id, "user_id" => $user->id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also delete all invitations for this user
|
// Also delete all invitations for this user.
|
||||||
$DB->delete_records("local_treestudyplan_invit", ["user_id" => $user->id]);
|
$DB->delete_records("local_treestudyplan_invit", ["user_id" => $user->id]);
|
||||||
|
|
||||||
} else if ($context->contextlevel == CONTEXT_COURSECAT) {
|
} else if ($context->contextlevel == CONTEXT_COURSECAT) {
|
||||||
|
@ -207,12 +228,12 @@ class provider implements \core_privacy\local\metadata\provider,
|
||||||
$context = $userlist->get_context();
|
$context = $userlist->get_context();
|
||||||
|
|
||||||
if ($context instanceof \context_system) {
|
if ($context instanceof \context_system) {
|
||||||
// Add all invitations
|
// Add all invitations.
|
||||||
$sql = "SELECT i.user_id as userid
|
$sql = "SELECT i.user_id as userid
|
||||||
FROM {local_treestudyplan_invit} i;";
|
FROM {local_treestudyplan_invit} i;";
|
||||||
$userlist->add_from_sql('userid', $sql, []);
|
$userlist->add_from_sql('userid', $sql, []);
|
||||||
|
|
||||||
// also add "contextless studyplans, they are considered in system context"
|
// also add "contextless studyplans, they are considered in system context".
|
||||||
$sql = "SELECT a.user_id as userid FROM {local_treestudyplan_user} a
|
$sql = "SELECT a.user_id as userid FROM {local_treestudyplan_user} a
|
||||||
INNER JOIN {local_treestudyplan} s ON a.studyplan_id = s.id
|
INNER JOIN {local_treestudyplan} s ON a.studyplan_id = s.id
|
||||||
WHERE ( a.context_id is NULL or a.context_id = 0)
|
WHERE ( a.context_id is NULL or a.context_id = 0)
|
||||||
|
@ -221,7 +242,7 @@ class provider implements \core_privacy\local\metadata\provider,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the links to all study plans in this context
|
// add the links to all study plans in this context.
|
||||||
$sql = "SELECT a.user_id as userid FROM {local_treestudyplan_user} a
|
$sql = "SELECT a.user_id as userid FROM {local_treestudyplan_user} a
|
||||||
INNER JOIN {local_treestudyplan} s ON a.studyplan_id = s.id
|
INNER JOIN {local_treestudyplan} s ON a.studyplan_id = s.id
|
||||||
WHERE ( a.context_id = :contextid )
|
WHERE ( a.context_id = :contextid )
|
||||||
|
@ -244,13 +265,13 @@ class provider implements \core_privacy\local\metadata\provider,
|
||||||
|
|
||||||
$plan_ids = [];
|
$plan_ids = [];
|
||||||
if ($context->contextlevel == CONTEXT_SYSTEM) {
|
if ($context->contextlevel == CONTEXT_SYSTEM) {
|
||||||
// Determine the relevant plan_ids for this context
|
// Determine the relevant plan_ids for this context.
|
||||||
$sql = "SELECT s.id FROM {local_treestudyplan}
|
$sql = "SELECT s.id FROM {local_treestudyplan}
|
||||||
WHERE ( s.context_id IS NULL OR s.context_id == 0 OR s.context_id = :contextid)) ";
|
WHERE ( s.context_id IS NULL OR s.context_id == 0 OR s.context_id = :contextid)) ";
|
||||||
$plan_ids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id, ]);
|
$plan_ids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id, ]);
|
||||||
// If plan ids not empty, they will be processed later
|
// If plan ids not empty, they will be processed later.
|
||||||
|
|
||||||
// Also delete all invitations for these users
|
// Also delete all invitations for these users.
|
||||||
$sql = "user_id {$userinsql}";
|
$sql = "user_id {$userinsql}";
|
||||||
$DB->delete_records_select("local_treestudyplan_invit", $sql, $userinparams);
|
$DB->delete_records_select("local_treestudyplan_invit", $sql, $userinparams);
|
||||||
|
|
||||||
|
@ -258,10 +279,10 @@ class provider implements \core_privacy\local\metadata\provider,
|
||||||
$sql = "SELECT s.id FROM {local_treestudyplan}
|
$sql = "SELECT s.id FROM {local_treestudyplan}
|
||||||
WHERE (s.context_id = :contextid)";
|
WHERE (s.context_id = :contextid)";
|
||||||
$plan_ids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id, ]);
|
$plan_ids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id, ]);
|
||||||
// If plan ids not empty, they will be processed later
|
// If plan ids not empty, they will be processed later.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now delete the studyplan associations if relevant
|
// Now delete the studyplan associations if relevant.
|
||||||
if (count($plan_ids) >0 && count($users) >0) {
|
if (count($plan_ids) >0 && count($users) >0) {
|
||||||
|
|
||||||
list($planinsql, $planinputparams) = $DB->get_in_or_equal($plan_ids, SQL_PARAMS_NAMED, 'plan');
|
list($planinsql, $planinputparams) = $DB->get_in_or_equal($plan_ids, SQL_PARAMS_NAMED, 'plan');
|
||||||
|
|
|
@ -1,16 +1,37 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
require_once("$CFG->libdir/formslib.php");
|
require_once("$CFG->libdir/formslib.php");
|
||||||
require_once("$CFG->dirroot/local/treestudyplan/lib.php");
|
require_once("$CFG->dirroot/local/treestudyplan/lib.php");
|
||||||
|
|
||||||
class reportinvite_form extends moodleform {
|
class reportinvite_form extends moodleform {
|
||||||
//Add elements to form
|
//Add elements to form.
|
||||||
const GOALS_EDITOR_OPTIONS = array('trusttext'=>true, 'subdirs'=>true, 'maxfiles'=>0, 'maxbytes'=>5*1024*1025);
|
const GOALS_EDITOR_OPTIONS = array('trusttext'=>true, 'subdirs'=>true, 'maxfiles'=>0, 'maxbytes'=>5*1024*1025);
|
||||||
|
|
||||||
public function definition() {
|
public function definition() {
|
||||||
global $CFG;
|
global $CFG;
|
||||||
|
|
||||||
// 'code', 'revision', 'description', 'goals', 'complexity', 'points', 'studyhours'
|
// 'code', 'revision', 'description', 'goals', 'complexity', 'points', 'studyhours'.
|
||||||
$mform = $this->_form; // Don't forget the underscore!
|
$mform = $this->_form; // Don't forget the underscore! .
|
||||||
|
|
||||||
$mform->addElement('hidden', 'add', 0);
|
$mform->addElement('hidden', 'add', 0);
|
||||||
$mform->setType('add', PARAM_ALPHANUM);
|
$mform->setType('add', PARAM_ALPHANUM);
|
||||||
|
@ -18,25 +39,25 @@ class reportinvite_form extends moodleform {
|
||||||
$mform->addElement('hidden', 'update', 0);
|
$mform->addElement('hidden', 'update', 0);
|
||||||
$mform->setType('update', PARAM_INT);
|
$mform->setType('update', PARAM_INT);
|
||||||
|
|
||||||
// $mform->addElement('static', 'desc_new', get_string('invite_desc_new','local_treestudyplan')); // Add elements to your form
|
// $mform->addElement('static', 'desc_new', get_string('invite_desc_new', 'local_treestudyplan')); // Add elements to your form.
|
||||||
// $mform->addElement('static', 'desc_edit', get_string('invite_desc_edit','local_treestudyplan')); // Add elements to your form
|
// $mform->addElement('static', 'desc_edit', get_string('invite_desc_edit', 'local_treestudyplan')); // Add elements to your form.
|
||||||
|
|
||||||
$mform->addElement('text', 'name', get_string('invite_name','local_treestudyplan'), array('size' => 50)); // Add elements to your form
|
$mform->addElement('text', 'name', get_string('invite_name', 'local_treestudyplan'), array('size' => 50)); // Add elements to your form.
|
||||||
$mform->setType('name', PARAM_NOTAGS); //Set type of element
|
$mform->setType('name', PARAM_NOTAGS); //Set type of element.
|
||||||
$mform->setDefault('name', ''); //Default value
|
$mform->setDefault('name', ''); //Default value.
|
||||||
$mform->addRule('name', get_string('required'), 'required', null, 'client');
|
$mform->addRule('name', get_string('required'), 'required', null, 'client');
|
||||||
|
|
||||||
$mform->addElement('text', 'email', get_string('invite_email','local_treestudyplan'), array('size' => 20)); // Add elements to your form
|
$mform->addElement('text', 'email', get_string('invite_email', 'local_treestudyplan'), array('size' => 20)); // Add elements to your form.
|
||||||
$mform->setType('email', PARAM_NOTAGS); //Set type of element
|
$mform->setType('email', PARAM_NOTAGS); //Set type of element.
|
||||||
$mform->setDefault('email', ''); //Default value
|
$mform->setDefault('email', ''); //Default value.
|
||||||
$mform->addRule('email', get_string('required'), 'required', null, 'client');
|
$mform->addRule('email', get_string('required'), 'required', null, 'client');
|
||||||
$mform->addRule('email', get_string('email'), 'email', null, 'client');
|
$mform->addRule('email', get_string('email'), 'email', null, 'client');
|
||||||
|
|
||||||
$mform->addElement('static', get_string('invite_email','local_treestudyplan') ); // Add elements to your form
|
$mform->addElement('static', get_string('invite_email', 'local_treestudyplan') ); // Add elements to your form.
|
||||||
|
|
||||||
$this->add_action_buttons();
|
$this->add_action_buttons();
|
||||||
}
|
}
|
||||||
//Custom validation should be added here
|
//Custom validation should be added here.
|
||||||
function validation($data, $files) {
|
function validation($data, $files) {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
@ -68,7 +89,7 @@ class reportinvite_form extends moodleform {
|
||||||
|
|
||||||
if (empty($data->update))
|
if (empty($data->update))
|
||||||
{
|
{
|
||||||
//create a new random key for the invite
|
//create a new random key for the invite.
|
||||||
do {
|
do {
|
||||||
$length = 20;
|
$length = 20;
|
||||||
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
@ -78,7 +99,7 @@ class reportinvite_form extends moodleform {
|
||||||
$randomkey .= $characters[rand(0, $charactersLength - 1)];
|
$randomkey .= $characters[rand(0, $charactersLength - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Double check that the key is unique before inserting
|
// Double check that the key is unique before inserting.
|
||||||
} while($DB->record_exists_select("local_treestudyplan_invit", $DB->sql_compare_text("invitekey"). " = " . $DB->sql_compare_text(":invitekey"), ['invitekey' => $randomkey]));
|
} while($DB->record_exists_select("local_treestudyplan_invit", $DB->sql_compare_text("invitekey"). " = " . $DB->sql_compare_text(":invitekey"), ['invitekey' => $randomkey]));
|
||||||
|
|
||||||
$data->invitekey = $randomkey;
|
$data->invitekey = $randomkey;
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
|
||||||
|
@ -34,9 +55,8 @@ class studentstudyplanservice extends \external_api
|
||||||
|
|
||||||
$list = [];
|
$list = [];
|
||||||
$studyplans = studyplan::find_for_user($userid);
|
$studyplans = studyplan::find_for_user($userid);
|
||||||
foreach($studyplans as $studyplan)
|
foreach ($studyplans as $studyplan) {
|
||||||
{
|
// only include studyplans in the context the user has permissions for.
|
||||||
// only include studyplans in the context the user has permissions for
|
|
||||||
if (webservicehelper::has_capabilities(self::CAP_VIEWOTHER, $studyplan->context(), false)) {
|
if (webservicehelper::has_capabilities(self::CAP_VIEWOTHER, $studyplan->context(), false)) {
|
||||||
$list[] =$studyplan->simple_model();
|
$list[] =$studyplan->simple_model();
|
||||||
}
|
}
|
||||||
|
@ -63,16 +83,14 @@ class studentstudyplanservice extends \external_api
|
||||||
studyplan::user_structure()
|
studyplan::user_structure()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public static function get_user_studyplans($userid)
|
public static function get_user_studyplans($userid) {
|
||||||
{
|
|
||||||
global $CFG, $DB;
|
global $CFG, $DB;
|
||||||
|
|
||||||
$studyplans = studyplan::find_for_user($userid);
|
$studyplans = studyplan::find_for_user($userid);
|
||||||
|
|
||||||
$map = [];
|
$map = [];
|
||||||
foreach($studyplans as $studyplan)
|
foreach ($studyplans as $studyplan) {
|
||||||
{
|
// only include studyplans in the context the user has permissions for.
|
||||||
// only include studyplans in the context the user has permissions for
|
|
||||||
if (webservicehelper::has_capabilities(self::CAP_VIEWOTHER, $studyplan->context(), false)) {
|
if (webservicehelper::has_capabilities(self::CAP_VIEWOTHER, $studyplan->context(), false)) {
|
||||||
$map[] = $studyplan->user_model($userid);
|
$map[] = $studyplan->user_model($userid);
|
||||||
}
|
}
|
||||||
|
@ -99,8 +117,7 @@ class studentstudyplanservice extends \external_api
|
||||||
{
|
{
|
||||||
return studyplan::user_structure();
|
return studyplan::user_structure();
|
||||||
}
|
}
|
||||||
public static function get_user_studyplan($userid,$studyplanid)
|
public static function get_user_studyplan($userid, $studyplanid) {
|
||||||
{
|
|
||||||
global $CFG, $DB;
|
global $CFG, $DB;
|
||||||
|
|
||||||
$studyplan = studyplan::findById($studyplanid);
|
$studyplan = studyplan::findById($studyplanid);
|
||||||
|
@ -133,8 +150,7 @@ class studentstudyplanservice extends \external_api
|
||||||
studyplan::user_structure()
|
studyplan::user_structure()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public static function get_invited_studyplan($invitekey)
|
public static function get_invited_studyplan($invitekey) {
|
||||||
{
|
|
||||||
global $CFG, $DB;
|
global $CFG, $DB;
|
||||||
|
|
||||||
$invite = $DB->get_record_select("local_treestudyplan_invit", $DB->sql_compare_text("invitekey"). " = " . $DB->sql_compare_text(":invitekey"), ['invitekey' => $invitekey]);
|
$invite = $DB->get_record_select("local_treestudyplan_invit", $DB->sql_compare_text("invitekey"). " = " . $DB->sql_compare_text(":invitekey"), ['invitekey' => $invitekey]);
|
||||||
|
@ -143,15 +159,14 @@ class studentstudyplanservice extends \external_api
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate context now
|
// Validate context now.
|
||||||
\external_api::validate_context(\context_system::instance());
|
\external_api::validate_context(\context_system::instance());
|
||||||
|
|
||||||
$userid = $invite->user_id;
|
$userid = $invite->user_id;
|
||||||
|
|
||||||
$map = [];
|
$map = [];
|
||||||
$studyplans = studyplan::find_for_user($userid);
|
$studyplans = studyplan::find_for_user($userid);
|
||||||
foreach($studyplans as $studyplan)
|
foreach ($studyplans as $studyplan) {
|
||||||
{
|
|
||||||
$map[] = $studyplan->user_model($userid);
|
$map[] = $studyplan->user_model($userid);
|
||||||
}
|
}
|
||||||
return $map;
|
return $map;
|
||||||
|
@ -181,8 +196,7 @@ class studentstudyplanservice extends \external_api
|
||||||
|
|
||||||
$list = [];
|
$list = [];
|
||||||
$studyplans = studyplan::find_for_user($userid);
|
$studyplans = studyplan::find_for_user($userid);
|
||||||
foreach($studyplans as $studyplan)
|
foreach ($studyplans as $studyplan) {
|
||||||
{
|
|
||||||
$list[] =$studyplan->simple_model();
|
$list[] =$studyplan->simple_model();
|
||||||
}
|
}
|
||||||
return $list;
|
return $list;
|
||||||
|
@ -208,8 +222,7 @@ class studentstudyplanservice extends \external_api
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function get_own_studyplan($id=null)
|
public static function get_own_studyplan($id=null) {
|
||||||
{
|
|
||||||
global $USER;
|
global $USER;
|
||||||
|
|
||||||
// Validate this call in the system context.
|
// Validate this call in the system context.
|
||||||
|
@ -256,8 +269,7 @@ class studentstudyplanservice extends \external_api
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function get_teaching_studyplans($id=null)
|
public static function get_teaching_studyplans($id=null) {
|
||||||
{
|
|
||||||
global $CFG, $DB, $USER;
|
global $CFG, $DB, $USER;
|
||||||
$userid = $USER->id;
|
$userid = $USER->id;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
|
||||||
|
@ -16,7 +37,7 @@ class studyitem {
|
||||||
public const TABLE = "local_treestudyplan_item";
|
public const TABLE = "local_treestudyplan_item";
|
||||||
|
|
||||||
private static $STUDYITEM_CACHE = [];
|
private static $STUDYITEM_CACHE = [];
|
||||||
private $r; // Holds database record
|
private $r; // Holds database record.
|
||||||
private $id;
|
private $id;
|
||||||
|
|
||||||
private $courseinfo = null;
|
private $courseinfo = null;
|
||||||
|
@ -101,12 +122,12 @@ class studyitem {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generate_model($mode) {
|
private function generate_model($mode) {
|
||||||
// Mode parameter is used to geep this function for both editor model and export model
|
// Mode parameter is used to geep this function for both editor model and export model.
|
||||||
// (Export model results in fewer parameters on children, but is otherwise basically the same as this function)
|
// (Export model results in fewer parameters on children, but is otherwise basically the same as this function).
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
$model = [
|
$model = [
|
||||||
'id' => $this->r->id, // Id is needed in export model because of link references
|
'id' => $this->r->id, // Id is needed in export model because of link references.
|
||||||
'type' => $this->isValid()?$this->r->type:self::INVALID,
|
'type' => $this->isValid()?$this->r->type:self::INVALID,
|
||||||
'conditions' => $this->r->conditions,
|
'conditions' => $this->r->conditions,
|
||||||
'slot' => $this->r->slot,
|
'slot' => $this->r->slot,
|
||||||
|
@ -119,17 +140,17 @@ class studyitem {
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
if ($mode == "export") {
|
if ($mode == "export") {
|
||||||
// remove slot and layer
|
// remove slot and layer.
|
||||||
unset($model["slot"]);
|
unset($model["slot"]);
|
||||||
unset($model["layer"]);
|
unset($model["layer"]);
|
||||||
unset($model["continuation_id"]);
|
unset($model["continuation_id"]);
|
||||||
$model["connections"] = []; // In export mode, connections is just an array of outgoing connections
|
$model["connections"] = []; // In export mode, connections is just an array of outgoing connections.
|
||||||
if (!isset($this->r->conditions)) {
|
if (!isset($this->r->conditions)) {
|
||||||
unset($model["conditions"]);
|
unset($model["conditions"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add course link if available
|
// Add course link if available.
|
||||||
$ci = $this->getcourseinfo();
|
$ci = $this->getcourseinfo();
|
||||||
if (isset($ci)) {
|
if (isset($ci)) {
|
||||||
if ($mode == "export") {
|
if ($mode == "export") {
|
||||||
|
@ -139,23 +160,22 @@ class studyitem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add badge info if available
|
// Add badge info if available.
|
||||||
if(is_numeric($this->r->badge_id) && $DB->record_exists('badge', array('id' => $this->r->badge_id)))
|
if (is_numeric($this->r->badge_id) && $DB->record_exists('badge', array('id' => $this->r->badge_id))) {
|
||||||
{
|
|
||||||
$badge = new \core_badges\badge($this->r->badge_id);
|
$badge = new \core_badges\badge($this->r->badge_id);
|
||||||
$badgeinfo = new badgeinfo($badge);
|
$badgeinfo = new badgeinfo($badge);
|
||||||
if ($mode == "export") {
|
if ($mode == "export") {
|
||||||
$model['badge'] = $badgeinfo->name();
|
$model['badge'] = $badgeinfo->name();
|
||||||
} else {
|
} else {
|
||||||
// Also supply a list of linked users, so the badgeinfo can give stats on
|
// Also supply a list of linked users, so the badgeinfo can give stats on .
|
||||||
// the amount issued, related to this studyplan
|
// the amount issued, related to this studyplan.
|
||||||
$studentids = $this->studyline()->studyplan()->find_linked_userids();
|
$studentids = $this->studyline()->studyplan()->find_linked_userids();
|
||||||
$model['badge'] = $badgeinfo->editor_model($studentids);
|
$model['badge'] = $badgeinfo->editor_model($studentids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($mode == "export") {
|
if ($mode == "export") {
|
||||||
// Also export gradables
|
// Also export gradables.
|
||||||
$gradables = gradeinfo::list_studyitem_gradables($this);
|
$gradables = gradeinfo::list_studyitem_gradables($this);
|
||||||
if (count($gradables) > 0) {
|
if (count($gradables) > 0) {
|
||||||
$model["gradables"] = [];
|
$model["gradables"] = [];
|
||||||
|
@ -166,7 +186,7 @@ class studyitem {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Add incoming and outgoing connection info
|
// Add incoming and outgoing connection info.
|
||||||
$conn_out = studyitemconnection::find_outgoing($this->id);
|
$conn_out = studyitemconnection::find_outgoing($this->id);
|
||||||
|
|
||||||
if ($mode == "export") {
|
if ($mode == "export") {
|
||||||
|
@ -188,8 +208,7 @@ class studyitem {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function add($fields,$import=false)
|
public static function add($fields, $import=false) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
$addable = ['line_id', 'type', 'layer', 'conditions', 'slot', 'competency_id', 'course_id', 'badge_id', 'continuation_id', 'span'];
|
$addable = ['line_id', 'type', 'layer', 'conditions', 'slot', 'competency_id', 'course_id', 'badge_id', 'continuation_id', 'span'];
|
||||||
$info = [ 'layer' => 0, ];
|
$info = [ 'layer' => 0, ];
|
||||||
|
@ -201,14 +220,13 @@ class studyitem {
|
||||||
$id = $DB->insert_record(self::TABLE, $info);
|
$id = $DB->insert_record(self::TABLE, $info);
|
||||||
$item = self::findById($id);
|
$item = self::findById($id);
|
||||||
if ($item->type() == self::COURSE) {
|
if ($item->type() == self::COURSE) {
|
||||||
// Signal the studyplan that a course has been added so it can be marked for csync cascading
|
// Signal the studyplan that a course has been added so it can be marked for csync cascading.
|
||||||
$item->studyline()->studyplan()->mark_csync_changed();
|
$item->studyline()->studyplan()->mark_csync_changed();
|
||||||
}
|
}
|
||||||
return $item;
|
return $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit($fields)
|
public function edit($fields) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
$editable = ['conditions', 'course_id', 'continuation_id', 'span'];
|
$editable = ['conditions', 'course_id', 'continuation_id', 'span'];
|
||||||
|
|
||||||
|
@ -220,13 +238,13 @@ class studyitem {
|
||||||
}
|
}
|
||||||
|
|
||||||
$DB->update_record(self::TABLE, $info);
|
$DB->update_record(self::TABLE, $info);
|
||||||
//reload record after edit
|
//reload record after edit.
|
||||||
$this->r = $DB->get_record(self::TABLE, ['id' => $this->id], "*", MUST_EXIST);
|
$this->r = $DB->get_record(self::TABLE, ['id' => $this->id], "*", MUST_EXIST);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isValid() {
|
public function isValid() {
|
||||||
// Check if referenced courses, badges and/or competencies still exist
|
// Check if referenced courses, badges and/or competencies still exist.
|
||||||
if ($this->r->type == static::COURSE) {
|
if ($this->r->type == static::COURSE) {
|
||||||
return courseinfo::exists($this->r->course_id);
|
return courseinfo::exists($this->r->course_id);
|
||||||
}
|
}
|
||||||
|
@ -238,13 +256,12 @@ class studyitem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete($force=false)
|
public function delete($force=false) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
// check if this item is referenced in a START item
|
// check if this item is referenced in a START item.
|
||||||
if ($force) {
|
if ($force) {
|
||||||
// clear continuation id from any references to this item
|
// clear continuation id from any references to this item.
|
||||||
$records = $DB->get_records(self::TABLE, ['continuation_id' => $this->id]);
|
$records = $DB->get_records(self::TABLE, ['continuation_id' => $this->id]);
|
||||||
foreach ($records as $r) {
|
foreach ($records as $r) {
|
||||||
$r->continuation_id = 0;
|
$r->continuation_id = 0;
|
||||||
|
@ -257,11 +274,11 @@ class studyitem {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// delete al related connections to this item
|
// delete al related connections to this item.
|
||||||
studyitemconnection::clear($this->id);
|
studyitemconnection::clear($this->id);
|
||||||
// delete all grade inclusion references to this item
|
// delete all grade inclusion references to this item.
|
||||||
$DB->delete_records("local_treestudyplan_gradeinc", ['studyitem_id' => $this->id]);
|
$DB->delete_records("local_treestudyplan_gradeinc", ['studyitem_id' => $this->id]);
|
||||||
// delete the item itself
|
// delete the item itself.
|
||||||
$DB->delete_records(self::TABLE, ['id' => $this->id]);
|
$DB->delete_records(self::TABLE, ['id' => $this->id]);
|
||||||
|
|
||||||
return success::success();
|
return success::success();
|
||||||
|
@ -274,12 +291,10 @@ class studyitem {
|
||||||
* *
|
* *
|
||||||
************************/
|
************************/
|
||||||
|
|
||||||
public static function reorder($resequence)
|
public static function reorder($resequence) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
foreach($resequence as $sq)
|
foreach ($resequence as $sq) {
|
||||||
{
|
|
||||||
$DB->update_record(self::TABLE, [
|
$DB->update_record(self::TABLE, [
|
||||||
'id' => $sq['id'],
|
'id' => $sq['id'],
|
||||||
'line_id' => $sq['line_id'],
|
'line_id' => $sq['line_id'],
|
||||||
|
@ -291,8 +306,7 @@ class studyitem {
|
||||||
return success::success();
|
return success::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function find_studyline_children(studyline $line)
|
public static function find_studyline_children(studyline $line) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
$list = [];
|
$list = [];
|
||||||
$ids = $DB->get_fieldset_select(self::TABLE, "id", "line_id = :line_id ORDER BY layer", ['line_id' => $line->id()]);
|
$ids = $DB->get_fieldset_select(self::TABLE, "id", "line_id = :line_id ORDER BY layer", ['line_id' => $line->id()]);
|
||||||
|
@ -362,29 +376,26 @@ class studyitem {
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
// Add badge info if available
|
// Add badge info if available.
|
||||||
if(badgeinfo::exists($this->r->badge_id))
|
if (badgeinfo::exists($this->r->badge_id)) {
|
||||||
{
|
|
||||||
$badge = new \core_badges\badge($this->r->badge_id);
|
$badge = new \core_badges\badge($this->r->badge_id);
|
||||||
$badgeinfo = new badgeinfo($badge);
|
$badgeinfo = new badgeinfo($badge);
|
||||||
$model['badge'] = $badgeinfo->user_model($userid);
|
$model['badge'] = $badgeinfo->user_model($userid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add continuation_info if available
|
// Add continuation_info if available.
|
||||||
if(self::exists($this->r->continuation_id))
|
if (self::exists($this->r->continuation_id)) {
|
||||||
{
|
|
||||||
$c_item = self::findById($this->r->continuation_id);
|
$c_item = self::findById($this->r->continuation_id);
|
||||||
$model['continuation'] = $c_item->link_model($userid);
|
$model['continuation'] = $c_item->link_model($userid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add course if available
|
// Add course if available.
|
||||||
if(courseinfo::exists($this->r->course_id))
|
if (courseinfo::exists($this->r->course_id)) {
|
||||||
{
|
|
||||||
$cinfo = $this->getcourseinfo();
|
$cinfo = $this->getcourseinfo();
|
||||||
$model['course'] = $cinfo->user_model($userid, $this->aggregator->usecorecompletioninfo());
|
$model['course'] = $cinfo->user_model($userid, $this->aggregator->usecorecompletioninfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add incoming and outgoing connection info
|
// Add incoming and outgoing connection info.
|
||||||
$conn_out = studyitemconnection::find_outgoing($this->id);
|
$conn_out = studyitemconnection::find_outgoing($this->id);
|
||||||
foreach ($conn_out as $c) {
|
foreach ($conn_out as $c) {
|
||||||
$model['connections']['out'][$c->to_id()] = $c->model();
|
$model['connections']['out'][$c->to_id()] = $c->model();
|
||||||
|
@ -398,8 +409,7 @@ class studyitem {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getcourseinfo()
|
public function getcourseinfo() {
|
||||||
{
|
|
||||||
if (empty($this->courseinfo) && courseinfo::exists($this->r->course_id)) {
|
if (empty($this->courseinfo) && courseinfo::exists($this->r->course_id)) {
|
||||||
$this->courseinfo = new courseinfo($this->r->course_id, $this);
|
$this->courseinfo = new courseinfo($this->r->course_id, $this);
|
||||||
}
|
}
|
||||||
|
@ -411,13 +421,13 @@ class studyitem {
|
||||||
|
|
||||||
if ($this->isValid()) {
|
if ($this->isValid()) {
|
||||||
if (strtolower($this->r->type) == 'course') {
|
if (strtolower($this->r->type) == 'course') {
|
||||||
// determine competency by competency completion
|
// determine competency by competency completion.
|
||||||
$courseinfo = $this->getcourseinfo();
|
$courseinfo = $this->getcourseinfo();
|
||||||
return $this->aggregator->aggregate_course($courseinfo, $this, $userid);
|
return $this->aggregator->aggregate_course($courseinfo, $this, $userid);
|
||||||
}
|
}
|
||||||
else if (strtolower($this->r->type) =='start') {
|
else if (strtolower($this->r->type) =='start') {
|
||||||
// Does not need to use aggregator.
|
// Does not need to use aggregator.
|
||||||
// Either true, or the completion of the reference
|
// Either true, or the completion of the reference.
|
||||||
if (self::exists($this->r->continuation_id)) {
|
if (self::exists($this->r->continuation_id)) {
|
||||||
$c_item = self::findById($this->r->continuation_id);
|
$c_item = self::findById($this->r->continuation_id);
|
||||||
return $c_item->completion($userid);
|
return $c_item->completion($userid);
|
||||||
|
@ -426,9 +436,9 @@ class studyitem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (in_array(strtolower($this->r->type), ['junction', 'finish'])) {
|
else if (in_array(strtolower($this->r->type), ['junction', 'finish'])) {
|
||||||
// completion of the linked items, according to the rule
|
// completion of the linked items, according to the rule.
|
||||||
$in_completed = [];
|
$in_completed = [];
|
||||||
// Retrieve incoming connections
|
// Retrieve incoming connections.
|
||||||
$incoming = $DB->get_records(studyitemconnection::TABLE, ['to_id' => $this->r->id]);
|
$incoming = $DB->get_records(studyitemconnection::TABLE, ['to_id' => $this->r->id]);
|
||||||
foreach ($incoming as $conn) {
|
foreach ($incoming as $conn) {
|
||||||
$item = self::findById($conn->from_id);
|
$item = self::findById($conn->from_id);
|
||||||
|
@ -438,13 +448,12 @@ class studyitem {
|
||||||
}
|
}
|
||||||
else if (strtolower($this->r->type) =='badge') {
|
else if (strtolower($this->r->type) =='badge') {
|
||||||
global $DB;
|
global $DB;
|
||||||
// badge awarded
|
// badge awarded.
|
||||||
if(badgeinfo::exists($this->r->badge_id))
|
if (badgeinfo::exists($this->r->badge_id)) {
|
||||||
{
|
|
||||||
$badge = new \core_badges\badge($this->r->badge_id);
|
$badge = new \core_badges\badge($this->r->badge_id);
|
||||||
if ($badge->is_issued($userid)) {
|
if ($badge->is_issued($userid)) {
|
||||||
if ($badge->can_expire()) {
|
if ($badge->can_expire()) {
|
||||||
// get the issued badges and check if any of them have not expired yet
|
// get the issued badges and check if any of them have not expired yet.
|
||||||
$badges_issued = $DB->get_records("badge_issued", ["badge_id" => $this->r->badge_id, "user_id" => $userid]);
|
$badges_issued = $DB->get_records("badge_issued", ["badge_id" => $this->r->badge_id, "user_id" => $userid]);
|
||||||
$notexpired = false;
|
$notexpired = false;
|
||||||
$now = time();
|
$now = time();
|
||||||
|
@ -467,31 +476,31 @@ class studyitem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// return incomplete for other types
|
// return incomplete for other types.
|
||||||
return completion::INCOMPLETE;
|
return completion::INCOMPLETE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// return incomplete for other types
|
// return incomplete for other types.
|
||||||
return completion::INCOMPLETE;
|
return completion::INCOMPLETE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function duplicate($new_line) {
|
public function duplicate($new_line) {
|
||||||
global $DB;
|
global $DB;
|
||||||
// clone the database fields
|
// clone the database fields.
|
||||||
$fields = clone $this->r;
|
$fields = clone $this->r;
|
||||||
// set new line id
|
// set new line id.
|
||||||
unset($fields->id);
|
unset($fields->id);
|
||||||
$fields->line_id = $new_line->id();
|
$fields->line_id = $new_line->id();
|
||||||
//create new record with the new data
|
//create new record with the new data.
|
||||||
$id = $DB->insert_record(self::TABLE, (array)$fields);
|
$id = $DB->insert_record(self::TABLE, (array)$fields);
|
||||||
$new = self::findById($id, $new_line);
|
$new = self::findById($id, $new_line);
|
||||||
|
|
||||||
// copy the grading info if relevant
|
// copy the grading info if relevant.
|
||||||
$gradables = gradeinfo::list_studyitem_gradables($this);
|
$gradables = gradeinfo::list_studyitem_gradables($this);
|
||||||
foreach ($gradables as $g) {
|
foreach ($gradables as $g) {
|
||||||
gradeinfo::include_grade($g->getGradeitem()->id,$new,true);
|
gradeinfo::include_grade($g->getGradeitem()->id, $new->id(), true);
|
||||||
}
|
}
|
||||||
return $new;
|
return $new;
|
||||||
}
|
}
|
||||||
|
@ -515,7 +524,7 @@ class studyitem {
|
||||||
$item = self::add($model, true);
|
$item = self::add($model, true);
|
||||||
|
|
||||||
if (isset($model["course_id"])) {
|
if (isset($model["course_id"])) {
|
||||||
// attempt to import the gradables
|
// attempt to import the gradables.
|
||||||
foreach ($model["gradables"] as $gradable) {
|
foreach ($model["gradables"] as $gradable) {
|
||||||
gradeinfo::import($item, $gradable);
|
gradeinfo::import($item, $gradable);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
|
||||||
|
@ -64,14 +85,12 @@ class studyitemconnection {
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function connect($from_id,$to_id)
|
public static function connect($from_id, $to_id) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
//check if link already exists
|
//check if link already exists.
|
||||||
|
|
||||||
if(!$DB->record_exists(self::TABLE, ['from_id' => $from_id, 'to_id' => $to_id]))
|
if (!$DB->record_exists(self::TABLE, ['from_id' => $from_id, 'to_id' => $to_id])) {
|
||||||
{
|
|
||||||
$id = $DB->insert_record(self::TABLE, [
|
$id = $DB->insert_record(self::TABLE, [
|
||||||
'from_id' => $from_id,
|
'from_id' => $from_id,
|
||||||
'to_id' => $to_id,
|
'to_id' => $to_id,
|
||||||
|
@ -84,12 +103,10 @@ class studyitemconnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function disconnect($from_id,$to_id)
|
public static function disconnect($from_id, $to_id) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
if($DB->record_exists(self::TABLE, ['from_id' => $from_id, 'to_id' => $to_id]))
|
if ($DB->record_exists(self::TABLE, ['from_id' => $from_id, 'to_id' => $to_id])) {
|
||||||
{
|
|
||||||
$DB->delete_records(self::TABLE, [
|
$DB->delete_records(self::TABLE, [
|
||||||
'from_id' => $from_id,
|
'from_id' => $from_id,
|
||||||
'to_id' => $to_id,
|
'to_id' => $to_id,
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
|
||||||
|
@ -24,7 +45,7 @@ class studyline {
|
||||||
|
|
||||||
private static $STUDYLINE_CACHE = [];
|
private static $STUDYLINE_CACHE = [];
|
||||||
|
|
||||||
private $r; // Holds database record
|
private $r; // Holds database record.
|
||||||
private $id;
|
private $id;
|
||||||
private $page;
|
private $page;
|
||||||
private $studyplan;
|
private $studyplan;
|
||||||
|
@ -88,8 +109,8 @@ class studyline {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function generate_model($mode) {
|
protected function generate_model($mode) {
|
||||||
// Mode parameter is used to geep this function for both editor model and export model
|
// Mode parameter is used to geep this function for both editor model and export model.
|
||||||
// (Export model results in fewer parameters on children, but is otherwise basically the same as this function)
|
// (Export model results in fewer parameters on children, but is otherwise basically the same as this function).
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
$model = [
|
$model = [
|
||||||
|
@ -101,23 +122,23 @@ class studyline {
|
||||||
'slots' => [],
|
'slots' => [],
|
||||||
];
|
];
|
||||||
if ($mode == "export") {
|
if ($mode == "export") {
|
||||||
// Id and sequence are not used in export model
|
// Id and sequence are not used in export model.
|
||||||
unset($model["id"]);
|
unset($model["id"]);
|
||||||
unset($model["sequence"]);
|
unset($model["sequence"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make this a little nicer
|
// TODO: Make this a little nicer.
|
||||||
// Get the number of slots
|
// Get the number of slots.
|
||||||
// As a safety data integrity measure, if there are any items in a higher slot than currently allowed,
|
// As a safety data integrity measure, if there are any items in a higher slot than currently allowed, .
|
||||||
// make sure there are enought slots to account for them
|
// make sure there are enought slots to account for them.
|
||||||
// Alternatively, we could ensure that on reduction of slots, the items that no longer have a slot will be removed.
|
// Alternatively, we could ensure that on reduction of slots, the items that no longer have a slot will be removed.
|
||||||
$max_slot = $DB->get_field_select(studyitem::TABLE, "MAX(slot)", "line_id = :lineid", ['lineid' => $this->id]);
|
$max_slot = $DB->get_field_select(studyitem::TABLE, "MAX(slot)", "line_id = :lineid", ['lineid' => $this->id]);
|
||||||
$num_slots = max($this->page->periods(), $max_slot +1);
|
$num_slots = max($this->page->periods(), $max_slot +1);
|
||||||
|
|
||||||
// Create the required amount of slots
|
// Create the required amount of slots.
|
||||||
for($i=0; $i < $num_slots+1; $i++) {
|
for($i=0; $i < $num_slots+1; $i++) {
|
||||||
if ($mode == "export") {
|
if ($mode == "export") {
|
||||||
// Export mode does not separate between filter or competency type, since that is determined automatically
|
// Export mode does not separate between filter or competency type, since that is determined automatically.
|
||||||
$slots = [];
|
$slots = [];
|
||||||
} else {
|
} else {
|
||||||
if ($i > 0) {
|
if ($i > 0) {
|
||||||
|
@ -130,8 +151,7 @@ class studyline {
|
||||||
}
|
}
|
||||||
|
|
||||||
$children = studyitem::find_studyline_children($this);
|
$children = studyitem::find_studyline_children($this);
|
||||||
foreach($children as $c)
|
foreach ($children as $c) {
|
||||||
{
|
|
||||||
if ($mode == "export") {
|
if ($mode == "export") {
|
||||||
$model['slots'][$c->slot()][] = $c->export_model();
|
$model['slots'][$c->slot()][] = $c->export_model();
|
||||||
} else {
|
} else {
|
||||||
|
@ -184,7 +204,7 @@ class studyline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$DB->update_record(self::TABLE, $info);
|
$DB->update_record(self::TABLE, $info);
|
||||||
//reload record after edit
|
//reload record after edit.
|
||||||
$this->r = $DB->get_record(self::TABLE, ['id' => $this->id], "*", MUST_EXIST);
|
$this->r = $DB->get_record(self::TABLE, ['id' => $this->id], "*", MUST_EXIST);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -198,7 +218,7 @@ class studyline {
|
||||||
$c->delete($force);
|
$c->delete($force);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check if this item has study items in it
|
// check if this item has study items in it.
|
||||||
if ($DB->count_records(studyitem::TABLE, ['line_id' => $this->id]) > 0) {
|
if ($DB->count_records(studyitem::TABLE, ['line_id' => $this->id]) > 0) {
|
||||||
return success::fail('cannot delete studyline with items');
|
return success::fail('cannot delete studyline with items');
|
||||||
}
|
}
|
||||||
|
@ -209,12 +229,10 @@ class studyline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function reorder($resequence)
|
public static function reorder($resequence) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
foreach($resequence as $sq)
|
foreach ($resequence as $sq) {
|
||||||
{
|
|
||||||
$DB->update_record(self::TABLE, [
|
$DB->update_record(self::TABLE, [
|
||||||
'id' => $sq['id'],
|
'id' => $sq['id'],
|
||||||
'sequence' => $sq['sequence'],
|
'sequence' => $sq['sequence'],
|
||||||
|
@ -224,8 +242,7 @@ class studyline {
|
||||||
return success::success();
|
return success::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function find_page_children(studyplanpage $page)
|
public static function find_page_children(studyplanpage $page) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
$list = [];
|
$list = [];
|
||||||
$ids = $DB->get_fieldset_select(self::TABLE, "id", "page_id = :page_id ORDER BY sequence",
|
$ids = $DB->get_fieldset_select(self::TABLE, "id", "page_id = :page_id ORDER BY sequence",
|
||||||
|
@ -253,7 +270,7 @@ class studyline {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function user_model($userid) {
|
public function user_model($userid) {
|
||||||
// TODO: Integrate this function into generate_model() for ease of maintenance
|
// TODO: Integrate this function into generate_model() for ease of maintenance.
|
||||||
|
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
|
@ -266,14 +283,14 @@ class studyline {
|
||||||
'slots' => [],
|
'slots' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
// Get the number of slots
|
// Get the number of slots.
|
||||||
// As a safety data integrity measure, if there are any items in a higher slot than currently allowed,
|
// As a safety data integrity measure, if there are any items in a higher slot than currently allowed, .
|
||||||
// make sure there are enought slots to account for them
|
// make sure there are enought slots to account for them.
|
||||||
// Alternatively, we could ensure that on reduction of slots, the items that no longer have a slot will be removed.
|
// Alternatively, we could ensure that on reduction of slots, the items that no longer have a slot will be removed.
|
||||||
$max_slot = $DB->get_field_select(studyitem::TABLE, "MAX(slot)", "line_id = :lineid", ['lineid' => $this->id]);
|
$max_slot = $DB->get_field_select(studyitem::TABLE, "MAX(slot)", "line_id = :lineid", ['lineid' => $this->id]);
|
||||||
$num_slots = max($this->page->periods(), $max_slot +1);
|
$num_slots = max($this->page->periods(), $max_slot +1);
|
||||||
|
|
||||||
// Create the required amount of slots
|
// Create the required amount of slots.
|
||||||
for($i=0; $i < $num_slots+1; $i++) {
|
for($i=0; $i < $num_slots+1; $i++) {
|
||||||
if ($i > 0) {
|
if ($i > 0) {
|
||||||
$slots = [self::SLOTSET_COMPETENCY => [], self::SLOTSET_FILTER => []];
|
$slots = [self::SLOTSET_COMPETENCY => [], self::SLOTSET_FILTER => []];
|
||||||
|
@ -284,8 +301,7 @@ class studyline {
|
||||||
}
|
}
|
||||||
|
|
||||||
$children = studyitem::find_studyline_children($this);
|
$children = studyitem::find_studyline_children($this);
|
||||||
foreach($children as $c)
|
foreach ($children as $c) {
|
||||||
{
|
|
||||||
if ($c->isValid()) {
|
if ($c->isValid()) {
|
||||||
$slotset = null;
|
$slotset = null;
|
||||||
if ($c->slot() > 0) {
|
if ($c->slot() > 0) {
|
||||||
|
@ -312,41 +328,37 @@ class studyline {
|
||||||
public function duplicate($new_studyplan, &$translation) {
|
public function duplicate($new_studyplan, &$translation) {
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
// clone the database fields
|
// clone the database fields.
|
||||||
$fields = clone $this->r;
|
$fields = clone $this->r;
|
||||||
// set new studyplan id
|
// set new studyplan id.
|
||||||
unset($fields->id);
|
unset($fields->id);
|
||||||
$fields->studyplan_id = $new_studyplan->id();
|
$fields->studyplan_id = $new_studyplan->id();
|
||||||
// create new record with the new data
|
// create new record with the new data.
|
||||||
$id = $DB->insert_record(self::TABLE, (array)$fields);
|
$id = $DB->insert_record(self::TABLE, (array)$fields);
|
||||||
$new = self::findById($id);
|
$new = self::findById($id);
|
||||||
|
|
||||||
// Next copy all the study items for this studyline
|
// Next copy all the study items for this studyline.
|
||||||
// and record the original and copy id's in the $translation array
|
// and record the original and copy id's in the $translation array.
|
||||||
// so the calling function can connect the new studyitems as required
|
// so the calling function can connect the new studyitems as required.
|
||||||
$children = studyitem::find_studyline_children($this);
|
$children = studyitem::find_studyline_children($this);
|
||||||
$translation = [];
|
$translation = [];
|
||||||
foreach($children as $c)
|
foreach ($children as $c) {
|
||||||
{
|
|
||||||
$newchild = $c->duplicate($new);
|
$newchild = $c->duplicate($new);
|
||||||
$translation[$c->id()] = $newchild->id();
|
$translation[$c->id()] = $newchild->id();
|
||||||
}
|
}
|
||||||
return $new;
|
return $new;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function export_model()
|
public function export_model() {
|
||||||
{
|
|
||||||
return $this->generate_model("export");
|
return $this->generate_model("export");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function import_studyitems($model, &$itemtranslation, &$connections) {
|
public function import_studyitems($model, &$itemtranslation, &$connections) {
|
||||||
global $DB;
|
global $DB;
|
||||||
foreach($model as $slot=>$slotmodel)
|
foreach ($model as $slot=>$slotmodel) {
|
||||||
{
|
|
||||||
$courselayer = 0;
|
$courselayer = 0;
|
||||||
$filterlayer = 0;
|
$filterlayer = 0;
|
||||||
foreach($slotmodel as $itemmodel)
|
foreach ($slotmodel as $itemmodel) {
|
||||||
{
|
|
||||||
if ($itemmodel["type"] == "course") {
|
if ($itemmodel["type"] == "course") {
|
||||||
$itemmodel["layer"] = $courselayer;
|
$itemmodel["layer"] = $courselayer;
|
||||||
$courselayer++;
|
$courselayer++;
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
|
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
@ -10,11 +31,11 @@ class studyplan {
|
||||||
private static $STUDYPLAN_CACHE = [];
|
private static $STUDYPLAN_CACHE = [];
|
||||||
|
|
||||||
|
|
||||||
private $r; // Holds database record
|
private $r; // Holds database record.
|
||||||
private $id;
|
private $id;
|
||||||
private $aggregator;
|
private $aggregator;
|
||||||
private $context = null; // Hold context object once retrieved
|
private $context = null; // Hold context object once retrieved.
|
||||||
private $linked_userids = null; // cache lookup of linked users (saves queries)
|
private $linked_userids = null; // cache lookup of linked users (saves queries).
|
||||||
private $page_cache = null;
|
private $page_cache = null;
|
||||||
|
|
||||||
public function aggregator() {
|
public function aggregator() {
|
||||||
|
@ -51,8 +72,8 @@ class studyplan {
|
||||||
|
|
||||||
public function pages() {
|
public function pages() {
|
||||||
// cached version of find_studyplan_children.
|
// cached version of find_studyplan_children.
|
||||||
// (may be premature optimization, since
|
// (may be premature optimization, since .
|
||||||
// find_studyplan_children also does some caching)
|
// find_studyplan_children also does some caching).
|
||||||
if (empty($this->page_cache)) {
|
if (empty($this->page_cache)) {
|
||||||
$this->page_cache = studyplanpage::find_studyplan_children($this);
|
$this->page_cache = studyplanpage::find_studyplan_children($this);
|
||||||
}
|
}
|
||||||
|
@ -68,7 +89,7 @@ class studyplan {
|
||||||
$this->context = contextinfo::by_id($this->r->context_id)->context;
|
$this->context = contextinfo::by_id($this->r->context_id)->context;
|
||||||
}
|
}
|
||||||
catch(\dml_missing_record_exception $x) {
|
catch(\dml_missing_record_exception $x) {
|
||||||
throw new \InvalidArgumentException("Context {$this->r->context_id} not available"); // Just throw it up again. catch is included here to make sure we know it throws this exception
|
throw new \InvalidArgumentException("Context {$this->r->context_id} not available"); // Just throw it up again. catch is included here to make sure we know it throws this exception.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $this->context;
|
return $this->context;
|
||||||
|
@ -148,19 +169,18 @@ class studyplan {
|
||||||
'pages' => [],
|
'pages' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach($this->pages() as $p)
|
foreach ($this->pages() as $p) {
|
||||||
{
|
|
||||||
$model['pages'][] = $p->editor_model();
|
$model['pages'][] = $p->editor_model();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_capability('local/treestudyplan:forcescales', \context_system::instance())) {
|
if (has_capability('local/treestudyplan:forcescales', \context_system::instance())) {
|
||||||
|
|
||||||
if (!array_key_exists('advanced', $model)) {
|
if (!array_key_exists('advanced', $model)) {
|
||||||
// Create advanced node if it does not exist
|
// Create advanced node if it does not exist.
|
||||||
$model['advanced'] = [];
|
$model['advanced'] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// get a list of available scales
|
// get a list of available scales.
|
||||||
$scales = array_map( function($scale) {
|
$scales = array_map( function($scale) {
|
||||||
return [ "id" => $scale->id, "name" => $scale->name, ];
|
return [ "id" => $scale->id, "name" => $scale->name, ];
|
||||||
}, \grade_scale::fetch_all(array('courseid'=>0)) ) ;
|
}, \grade_scale::fetch_all(array('courseid'=>0)) ) ;
|
||||||
|
@ -185,14 +205,14 @@ class studyplan {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$id = $DB->insert_record(self::TABLE, $info);
|
$id = $DB->insert_record(self::TABLE, $info);
|
||||||
$plan = self::findById($id); // make sure the new studyplan is immediately cached
|
$plan = self::findById($id); // make sure the new studyplan is immediately cached.
|
||||||
|
|
||||||
|
|
||||||
// Start temporary skräpp code
|
// Start temporary skräpp code.
|
||||||
// Add a single page and copy the names.This keeps the data sane until the upgrade to
|
// Add a single page and copy the names.This keeps the data sane until the upgrade to .
|
||||||
// real page management is done
|
// real page management is done.
|
||||||
// On import, adding an empty page messes things up for now, so we have an option to skip this....
|
// On import, adding an empty page messes things up for now, so we have an option to skip this....
|
||||||
// TODO: Remove this when proper page management is implemented
|
// TODO: Remove this when proper page management is implemented.
|
||||||
if (!$bare) {
|
if (!$bare) {
|
||||||
|
|
||||||
$pageaddable = ['name', 'shortname', 'description', 'periods', 'startdate', 'enddate'];
|
$pageaddable = ['name', 'shortname', 'description', 'periods', 'startdate', 'enddate'];
|
||||||
|
@ -210,7 +230,7 @@ class studyplan {
|
||||||
$page = studyplanpage::add($pageinfo);
|
$page = studyplanpage::add($pageinfo);
|
||||||
$plan->page_cache = [$page];
|
$plan->page_cache = [$page];
|
||||||
}
|
}
|
||||||
// End temporary skräpp code
|
// End temporary skräpp code.
|
||||||
|
|
||||||
return $plan;
|
return $plan;
|
||||||
}
|
}
|
||||||
|
@ -225,20 +245,20 @@ class studyplan {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$DB->update_record(self::TABLE, $info);
|
$DB->update_record(self::TABLE, $info);
|
||||||
//reload record after edit
|
//reload record after edit.
|
||||||
$this->r = $DB->get_record(self::TABLE, ['id' => $this->id], "*", MUST_EXIST);
|
$this->r = $DB->get_record(self::TABLE, ['id' => $this->id], "*", MUST_EXIST);
|
||||||
|
|
||||||
//reload the context...
|
//reload the context...
|
||||||
$this->context = null;
|
$this->context = null;
|
||||||
$this->context();
|
$this->context();
|
||||||
// reload aggregator
|
// reload aggregator.
|
||||||
$this->aggregator = aggregator::createOrDefault($this->r->aggregation, $this->r->aggregation_config);
|
$this->aggregator = aggregator::createOrDefault($this->r->aggregation, $this->r->aggregation_config);
|
||||||
|
|
||||||
// Start temporary skräpp code
|
// Start temporary skräpp code.
|
||||||
// TODO: Until proper page editing is implemented, copy data from studyplan to it's first page
|
// TODO: Until proper page editing is implemented, copy data from studyplan to it's first page.
|
||||||
// This keeps the data sane until the upgrade is done.
|
// This keeps the data sane until the upgrade is done.
|
||||||
if (count($this->pages()) == 1) {
|
if (count($this->pages()) == 1) {
|
||||||
// update the info to the page as well
|
// update the info to the page as well.
|
||||||
$page = $this->pages()[0];
|
$page = $this->pages()[0];
|
||||||
$pageeditable = ['name', 'shortname', 'description', 'periods', 'startdate', 'enddate'];
|
$pageeditable = ['name', 'shortname', 'description', 'periods', 'startdate', 'enddate'];
|
||||||
$pageinfo = [];
|
$pageinfo = [];
|
||||||
|
@ -253,7 +273,7 @@ class studyplan {
|
||||||
}
|
}
|
||||||
$page->edit($pageinfo);
|
$page->edit($pageinfo);
|
||||||
}
|
}
|
||||||
// End temporary skräpp code
|
// End temporary skräpp code.
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -295,8 +315,7 @@ class studyplan {
|
||||||
$ids = $DB->get_fieldset_select(self::TABLE, "id", $where, ["contextid" => $contextid]);
|
$ids = $DB->get_fieldset_select(self::TABLE, "id", $where, ["contextid" => $contextid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($ids as $id)
|
foreach ($ids as $id) {
|
||||||
{
|
|
||||||
$list[] = studyplan::findById($id);
|
$list[] = studyplan::findById($id);
|
||||||
}
|
}
|
||||||
return $list;
|
return $list;
|
||||||
|
@ -311,15 +330,13 @@ class studyplan {
|
||||||
$where .= "OR context_id IS NULL";
|
$where .= "OR context_id IS NULL";
|
||||||
}
|
}
|
||||||
$ids = $DB->get_fieldset_select(self::TABLE, "id", $where, ["shortname"=>$shortname, "contextid" => $contextid]);
|
$ids = $DB->get_fieldset_select(self::TABLE, "id", $where, ["shortname"=>$shortname, "contextid" => $contextid]);
|
||||||
foreach($ids as $id)
|
foreach ($ids as $id) {
|
||||||
{
|
|
||||||
$list[] = studyplan::findById($id);
|
$list[] = studyplan::findById($id);
|
||||||
}
|
}
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function find_for_user($userid)
|
public static function find_for_user($userid) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
$sql = "SELECT s.id FROM {local_treestudyplan} s
|
$sql = "SELECT s.id FROM {local_treestudyplan} s
|
||||||
|
@ -347,8 +364,7 @@ class studyplan {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function exist_for_user($userid)
|
static public function exist_for_user($userid) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
$count = 0;
|
$count = 0;
|
||||||
$sql = "SELECT s.* FROM {local_treestudyplan} s
|
$sql = "SELECT s.* FROM {local_treestudyplan} s
|
||||||
|
@ -392,7 +408,7 @@ class studyplan {
|
||||||
|
|
||||||
if ($this->linked_userids === null) {
|
if ($this->linked_userids === null) {
|
||||||
$uids = [];
|
$uids = [];
|
||||||
// First get directly linked userids
|
// First get directly linked userids.
|
||||||
$sql = "SELECT j.user_id FROM {local_treestudyplan_user} j
|
$sql = "SELECT j.user_id FROM {local_treestudyplan_user} j
|
||||||
WHERE j.studyplan_id = :planid";
|
WHERE j.studyplan_id = :planid";
|
||||||
$ulist = $DB->get_fieldset_sql($sql, ['planid' => $this->id]);
|
$ulist = $DB->get_fieldset_sql($sql, ['planid' => $this->id]);
|
||||||
|
@ -402,7 +418,7 @@ class studyplan {
|
||||||
$users[] = $DB->get_record("user", ["id"=>$uid]);
|
$users[] = $DB->get_record("user", ["id"=>$uid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next het users linked though cohort
|
// Next het users linked though cohort.
|
||||||
$sql = "SELECT cm.userid FROM {local_treestudyplan_cohort} j
|
$sql = "SELECT cm.userid FROM {local_treestudyplan_cohort} j
|
||||||
INNER JOIN {cohort_members} cm ON j.cohort_id = cm.cohortid
|
INNER JOIN {cohort_members} cm ON j.cohort_id = cm.cohortid
|
||||||
WHERE j.studyplan_id = :planid";
|
WHERE j.studyplan_id = :planid";
|
||||||
|
@ -457,30 +473,27 @@ class studyplan {
|
||||||
'aggregation_info' => $this->aggregator->basic_model(),
|
'aggregation_info' => $this->aggregator->basic_model(),
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach($this->pages() as $p)
|
foreach ($this->pages() as $p) {
|
||||||
{
|
|
||||||
$model['pages'][] = $p->user_model($userid);
|
$model['pages'][] = $p->user_model($userid);
|
||||||
}
|
}
|
||||||
return $model;
|
return $model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function duplicate_plan($plan_id,$name,$shortname)
|
public static function duplicate_plan($plan_id, $name, $shortname) {
|
||||||
{
|
|
||||||
$ori = self::findById($plan_id);
|
$ori = self::findById($plan_id);
|
||||||
$new = $ori->duplicate($name, $shortname);
|
$new = $ori->duplicate($name, $shortname);
|
||||||
return $new->simple_model();
|
return $new->simple_model();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function duplicate($name,$shortname)
|
public function duplicate($name, $shortname) {
|
||||||
{
|
// First duplicate the studyplan structure.
|
||||||
// First duplicate the studyplan structure
|
|
||||||
$newplan =studyplan::add([
|
$newplan =studyplan::add([
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'shortname' => $shortname,
|
'shortname' => $shortname,
|
||||||
'description' => $this->r->description,
|
'description' => $this->r->description,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// next, copy the studylines
|
// next, copy the studylines.
|
||||||
|
|
||||||
foreach ($this->pages() as $p) {
|
foreach ($this->pages() as $p) {
|
||||||
$newchild = $p->duplicate($newplan);
|
$newchild = $p->duplicate($newplan);
|
||||||
|
@ -489,16 +502,14 @@ class studyplan {
|
||||||
return $newplan;
|
return $newplan;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function export_structure()
|
public static function export_structure() {
|
||||||
{
|
|
||||||
return new \external_single_structure([
|
return new \external_single_structure([
|
||||||
"format" => new \external_value(PARAM_TEXT, 'format of studyplan export'),
|
"format" => new \external_value(PARAM_TEXT, 'format of studyplan export'),
|
||||||
"content"=> new \external_value(PARAM_TEXT, 'exported studyplan content'),
|
"content"=> new \external_value(PARAM_TEXT, 'exported studyplan content'),
|
||||||
], 'Exported studyplan');
|
], 'Exported studyplan');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function export_plan()
|
public function export_plan() {
|
||||||
{
|
|
||||||
$model = $this->export_model();
|
$model = $this->export_model();
|
||||||
$json = json_encode([
|
$json = json_encode([
|
||||||
"type"=>"studyplan",
|
"type"=>"studyplan",
|
||||||
|
@ -508,8 +519,7 @@ class studyplan {
|
||||||
return [ "format" => "application/json", "content" => $json];
|
return [ "format" => "application/json", "content" => $json];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function export_model()
|
public function export_model() {
|
||||||
{
|
|
||||||
$model = [
|
$model = [
|
||||||
'name' => $this->r->name,
|
'name' => $this->r->name,
|
||||||
'shortname' => $this->r->shortname,
|
'shortname' => $this->r->shortname,
|
||||||
|
@ -522,32 +532,29 @@ class studyplan {
|
||||||
return $model;
|
return $model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function export_pages_model()
|
public function export_pages_model() {
|
||||||
{
|
|
||||||
$pages = [];
|
$pages = [];
|
||||||
foreach($this->pages() as $p)
|
foreach ($this->pages() as $p) {
|
||||||
{
|
|
||||||
$pages[] = $p->export_model();
|
$pages[] = $p->export_model();
|
||||||
}
|
}
|
||||||
return $pages;
|
return $pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function import_studyplan($content,$format="application/json",$context_id=1)
|
public static function import_studyplan($content, $format="application/json", $context_id=1) {
|
||||||
{
|
|
||||||
if ($format != "application/json") { return false;}
|
if ($format != "application/json") { return false;}
|
||||||
|
|
||||||
$content = json_decode($content, true);
|
$content = json_decode($content, true);
|
||||||
if ($content["type"] == "studyplan" && $content["version"] >= 2.0) {
|
if ($content["type"] == "studyplan" && $content["version"] >= 2.0) {
|
||||||
|
|
||||||
// Make sure the aggregation_config is re-encoded as json text
|
// Make sure the aggregation_config is re-encoded as json text.
|
||||||
$content["studyplan"]["aggregation_config"] = json_encode($content["studyplan"]["aggregation_config"]);
|
$content["studyplan"]["aggregation_config"] = json_encode($content["studyplan"]["aggregation_config"]);
|
||||||
|
|
||||||
// And make sure the context_id is set to the provided context for import
|
// And make sure the context_id is set to the provided context for import.
|
||||||
$content["studyplan"]["context_id"] = $context_id;
|
$content["studyplan"]["context_id"] = $context_id;
|
||||||
|
|
||||||
// Create a new plan, based on the given parameters - this is the import studyplan part
|
// Create a new plan, based on the given parameters - this is the import studyplan part.
|
||||||
$plan = self::add($content["studyplan"], true);
|
$plan = self::add($content["studyplan"], true);
|
||||||
// Now import each page
|
// Now import each page.
|
||||||
return $plan->import_pages_model($content["studyplan"]["pages"]);
|
return $plan->import_pages_model($content["studyplan"]["pages"]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -557,17 +564,16 @@ class studyplan {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function import_pages($content,$format="application/json")
|
public function import_pages($content, $format="application/json") {
|
||||||
{
|
|
||||||
if ($format != "application/json") { return false;}
|
if ($format != "application/json") { return false;}
|
||||||
$content = json_decode($content, true);
|
$content = json_decode($content, true);
|
||||||
if ($content["version"] >= 2.0) {
|
if ($content["version"] >= 2.0) {
|
||||||
if ($content["type"] == "studyplanpage") {
|
if ($content["type"] == "studyplanpage") {
|
||||||
// import single page from a studyplanpage (wrapped in array of one page)
|
// import single page from a studyplanpage (wrapped in array of one page).
|
||||||
return $this->import_pages_model([$content["page"]]);
|
return $this->import_pages_model([$content["page"]]);
|
||||||
}
|
}
|
||||||
else if ($content["type"] == "studyplan") {
|
else if ($content["type"] == "studyplan") {
|
||||||
// Import all pages from the studyplan
|
// Import all pages from the studyplan.
|
||||||
return $this->import_pages_model($content["studyplan"]["pages"]);
|
return $this->import_pages_model($content["studyplan"]["pages"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -576,8 +582,7 @@ class studyplan {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function import_pages_model($model)
|
protected function import_pages_model($model) {
|
||||||
{
|
|
||||||
$this->pages(); // make sure the page cache is initialized, since we will be adding to it.
|
$this->pages(); // make sure the page cache is initialized, since we will be adding to it.
|
||||||
foreach ($model as $p) {
|
foreach ($model as $p) {
|
||||||
$p["studyplan_id"] = $this->id();
|
$p["studyplan_id"] = $this->id();
|
||||||
|
@ -595,7 +600,7 @@ class studyplan {
|
||||||
public function mark_csync_changed() {
|
public function mark_csync_changed() {
|
||||||
global $DB;
|
global $DB;
|
||||||
$DB->update_record(self::TABLE, ['id' => $this->id, "csync_flag" => 1]);
|
$DB->update_record(self::TABLE, ['id' => $this->id, "csync_flag" => 1]);
|
||||||
$this->r->csync_flag = 1; //manually set it in the cache, if something unexpected happened, an exception has already been thrown anyway
|
$this->r->csync_flag = 1; //manually set it in the cache, if something unexpected happened, an exception has already been thrown anyway.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -604,7 +609,7 @@ class studyplan {
|
||||||
public function clear_csync_changed() {
|
public function clear_csync_changed() {
|
||||||
global $DB;
|
global $DB;
|
||||||
$DB->update_record(self::TABLE, ['id' => $this->id, "csync_flag" => 0]);
|
$DB->update_record(self::TABLE, ['id' => $this->id, "csync_flag" => 0]);
|
||||||
$this->r->csync_flag = 0; //manually set it in the cache, if something unexpected happened, an exception has already been thrown anyway
|
$this->r->csync_flag = 0; //manually set it in the cache, if something unexpected happened, an exception has already been thrown anyway.
|
||||||
}
|
}
|
||||||
|
|
||||||
public function has_csync_changed() {
|
public function has_csync_changed() {
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
|
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
require_once($CFG->libdir.'/externallib.php');
|
||||||
|
@ -10,7 +31,7 @@ class studyplanpage {
|
||||||
private static $CACHE = [];
|
private static $CACHE = [];
|
||||||
|
|
||||||
|
|
||||||
private $r; // Holds database record
|
private $r; // Holds database record.
|
||||||
private $id;
|
private $id;
|
||||||
private $studyplan;
|
private $studyplan;
|
||||||
|
|
||||||
|
@ -62,7 +83,7 @@ class studyplanpage {
|
||||||
return new \DateTime($this->r->enddate);
|
return new \DateTime($this->r->enddate);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// return a date 100 years into the future
|
// return a date 100 years into the future.
|
||||||
return (new \DateTime($this->r->startdate))->add(new \DateInterval("P100Y"));
|
return (new \DateTime($this->r->startdate))->add(new \DateInterval("P100Y"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,8 +145,7 @@ class studyplanpage {
|
||||||
];
|
];
|
||||||
|
|
||||||
$children = studyline::find_page_children($this);
|
$children = studyline::find_page_children($this);
|
||||||
foreach($children as $c)
|
foreach ($children as $c) {
|
||||||
{
|
|
||||||
$model['studylines'][] = $c->editor_model();
|
$model['studylines'][] = $c->editor_model();
|
||||||
}
|
}
|
||||||
return $model;
|
return $model;
|
||||||
|
@ -152,7 +172,7 @@ class studyplanpage {
|
||||||
}
|
}
|
||||||
|
|
||||||
$id = $DB->insert_record(self::TABLE, $info);
|
$id = $DB->insert_record(self::TABLE, $info);
|
||||||
return self::findById($id); // make sure the new page is immediately cached
|
return self::findById($id); // make sure the new page is immediately cached.
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit($fields) {
|
public function edit($fields) {
|
||||||
|
@ -169,7 +189,7 @@ class studyplanpage {
|
||||||
}
|
}
|
||||||
|
|
||||||
$DB->update_record(self::TABLE, $info);
|
$DB->update_record(self::TABLE, $info);
|
||||||
//reload record after edit
|
//reload record after edit.
|
||||||
$this->r = $DB->get_record(self::TABLE, ['id' => $this->id], "*", MUST_EXIST);
|
$this->r = $DB->get_record(self::TABLE, ['id' => $this->id], "*", MUST_EXIST);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -224,15 +244,13 @@ class studyplanpage {
|
||||||
];
|
];
|
||||||
|
|
||||||
$children = studyline::find_page_children($this);
|
$children = studyline::find_page_children($this);
|
||||||
foreach($children as $c)
|
foreach ($children as $c) {
|
||||||
{
|
|
||||||
$model['studylines'][] = $c->user_model($userid);
|
$model['studylines'][] = $c->user_model($userid);
|
||||||
}
|
}
|
||||||
return $model;
|
return $model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function find_studyplan_children(studyplan $plan)
|
public static function find_studyplan_children(studyplan $plan) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
$list = [];
|
$list = [];
|
||||||
$ids = $DB->get_fieldset_select(self::TABLE, "id", "studyplan_id = :plan_id ORDER BY startdate",
|
$ids = $DB->get_fieldset_select(self::TABLE, "id", "studyplan_id = :plan_id ORDER BY startdate",
|
||||||
|
@ -243,16 +261,14 @@ class studyplanpage {
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function duplicate_page($page_id,$name,$shortname)
|
public static function duplicate_page($page_id, $name, $shortname) {
|
||||||
{
|
|
||||||
$ori = self::findById($page_id);
|
$ori = self::findById($page_id);
|
||||||
$new = $ori->duplicate($name, $shortname);
|
$new = $ori->duplicate($name, $shortname);
|
||||||
return $new->simple_model();
|
return $new->simple_model();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function duplicate($new_studyplan)
|
public function duplicate($new_studyplan) {
|
||||||
{
|
// First duplicate the studyplan structure.
|
||||||
// First duplicate the studyplan structure
|
|
||||||
$new = studyplanpage::add([
|
$new = studyplanpage::add([
|
||||||
'studyplan_id' => $new_studyplan->id(),
|
'studyplan_id' => $new_studyplan->id(),
|
||||||
'fullname' => $this->r->fullname,
|
'fullname' => $this->r->fullname,
|
||||||
|
@ -263,7 +279,7 @@ class studyplanpage {
|
||||||
'enddate' => empty($this->r->enddate)?null:$this->r->enddate,
|
'enddate' => empty($this->r->enddate)?null:$this->r->enddate,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// next, copy the studylines
|
// next, copy the studylines.
|
||||||
|
|
||||||
$children = studyline::find_page_children($this);
|
$children = studyline::find_page_children($this);
|
||||||
$itemtranslation = [];
|
$itemtranslation = [];
|
||||||
|
@ -273,11 +289,11 @@ class studyplanpage {
|
||||||
$linetranslation[$c->id()] = $newchild->id();
|
$linetranslation[$c->id()] = $newchild->id();
|
||||||
}
|
}
|
||||||
|
|
||||||
// now the itemtranslation array contains all of the old child id's as keys and all of the related new ids as values
|
// now the itemtranslation array contains all of the old child id's as keys and all of the related new ids as values.
|
||||||
// (feature of the studyline::duplicate function)
|
// (feature of the studyline::duplicate function).
|
||||||
// use this to recreate the lines in the new plan
|
// use this to recreate the lines in the new plan.
|
||||||
foreach (array_keys($itemtranslation) as $item_id) {
|
foreach (array_keys($itemtranslation) as $item_id) {
|
||||||
// copy based on the outgoing connections of each item, to avoid duplicates
|
// copy based on the outgoing connections of each item, to avoid duplicates.
|
||||||
$connections = studyitemconnection::find_outgoing($item_id);
|
$connections = studyitemconnection::find_outgoing($item_id);
|
||||||
foreach ($connections as $conn) {
|
foreach ($connections as $conn) {
|
||||||
studyitemconnection::connect($itemtranslation[$conn->from_id], $itemtranslation[$conn->to_id]);
|
studyitemconnection::connect($itemtranslation[$conn->from_id], $itemtranslation[$conn->to_id]);
|
||||||
|
@ -286,16 +302,14 @@ class studyplanpage {
|
||||||
return $new;
|
return $new;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function export_structure()
|
public static function export_structure() {
|
||||||
{
|
|
||||||
return new \external_single_structure([
|
return new \external_single_structure([
|
||||||
"format" => new \external_value(PARAM_TEXT, 'format of studyplan export'),
|
"format" => new \external_value(PARAM_TEXT, 'format of studyplan export'),
|
||||||
"content"=> new \external_value(PARAM_TEXT, 'exported studyplan content'),
|
"content"=> new \external_value(PARAM_TEXT, 'exported studyplan content'),
|
||||||
], 'Exported studyplan');
|
], 'Exported studyplan');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function export_page()
|
public function export_page() {
|
||||||
{
|
|
||||||
$model = $this->export_model();
|
$model = $this->export_model();
|
||||||
$json = json_encode([
|
$json = json_encode([
|
||||||
"type"=>"studyplanpage",
|
"type"=>"studyplanpage",
|
||||||
|
@ -305,23 +319,22 @@ class studyplanpage {
|
||||||
return [ "format" => "application/json", "content" => $json];
|
return [ "format" => "application/json", "content" => $json];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function export_page_csv()
|
public function export_page_csv() {
|
||||||
{
|
|
||||||
$plist = period::findForPage($this);
|
$plist = period::findForPage($this);
|
||||||
|
|
||||||
$model = $this->editor_model();
|
$model = $this->editor_model();
|
||||||
|
|
||||||
$periods = intval($model["periods"]);
|
$periods = intval($model["periods"]);
|
||||||
// First line
|
// First line.
|
||||||
$csv = "\"\"";
|
$csv = "\"\"";
|
||||||
for($i = 1; $i <= $periods; $i++) {
|
for($i = 1; $i <= $periods; $i++) {
|
||||||
$name = $plist[$i]->shortname();
|
$name = $plist[$i]->shortname();
|
||||||
$csv .= ", \"{$name}\"";
|
$csv .= ", \"{$name}\"";
|
||||||
}
|
}
|
||||||
$csv .= "\r\n";
|
$csv .= "\r\n";
|
||||||
// next, make one line per studyline
|
// next, make one line per studyline.
|
||||||
foreach ($model["studylines"] as $line) {
|
foreach ($model["studylines"] as $line) {
|
||||||
// determine how many fields are simultaneous in the line at maximum
|
// determine how many fields are simultaneous in the line at maximum.
|
||||||
$maxlines = 1;
|
$maxlines = 1;
|
||||||
for($i = 1; $i <= $periods; $i++) {
|
for($i = 1; $i <= $periods; $i++) {
|
||||||
if (count($line["slots"]) > $i) {
|
if (count($line["slots"]) > $i) {
|
||||||
|
@ -402,8 +415,7 @@ class studyplanpage {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function export_model()
|
public function export_model() {
|
||||||
{
|
|
||||||
$model = [
|
$model = [
|
||||||
'fullname' => $this->r->fullname,
|
'fullname' => $this->r->fullname,
|
||||||
'shortname' => $this->r->shortname,
|
'shortname' => $this->r->shortname,
|
||||||
|
@ -417,20 +429,17 @@ class studyplanpage {
|
||||||
return $model;
|
return $model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function export_studylines_model()
|
public function export_studylines_model() {
|
||||||
{
|
|
||||||
$children = studyline::find_page_children($this);
|
$children = studyline::find_page_children($this);
|
||||||
$lines = [];
|
$lines = [];
|
||||||
foreach($children as $c)
|
foreach ($children as $c) {
|
||||||
{
|
|
||||||
$lines[] = $c->export_model();
|
$lines[] = $c->export_model();
|
||||||
}
|
}
|
||||||
return $lines;
|
return $lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function import_periods($content,$format="application/json")
|
public function import_periods($content, $format="application/json") {
|
||||||
{
|
|
||||||
if ($format != "application/json") { return false;}
|
if ($format != "application/json") { return false;}
|
||||||
$content = json_decode($content, true);
|
$content = json_decode($content, true);
|
||||||
if ($content["type"] == "periods" && $content["version"] >= 2.0) {
|
if ($content["type"] == "periods" && $content["version"] >= 2.0) {
|
||||||
|
@ -444,8 +453,7 @@ class studyplanpage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function import_studylines($content,$format="application/json")
|
public function import_studylines($content, $format="application/json") {
|
||||||
{
|
|
||||||
if ($format != "application/json") { return false;}
|
if ($format != "application/json") { return false;}
|
||||||
$content = json_decode($content, true);
|
$content = json_decode($content, true);
|
||||||
if ($content["type"] == "studylines" && $content["version"] >= 2.0) {
|
if ($content["type"] == "studylines" && $content["version"] >= 2.0) {
|
||||||
|
@ -482,9 +490,8 @@ class studyplanpage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function import_studylines_model($model)
|
public function import_studylines_model($model) {
|
||||||
{
|
// First attempt to map each studyline model to an existing or new line.
|
||||||
// First attempt to map each studyline model to an existing or new line
|
|
||||||
$line_map = [];
|
$line_map = [];
|
||||||
foreach ($model as $ix => $linemodel) {
|
foreach ($model as $ix => $linemodel) {
|
||||||
$line = $this->find_studyline_by_shortname($linemodel["shortname"]);
|
$line = $this->find_studyline_by_shortname($linemodel["shortname"]);
|
||||||
|
@ -492,19 +499,19 @@ class studyplanpage {
|
||||||
$linemodel["page_id"] = $this->id;
|
$linemodel["page_id"] = $this->id;
|
||||||
$line = studyline::add($linemodel);
|
$line = studyline::add($linemodel);
|
||||||
} else {
|
} else {
|
||||||
//$line->edit($linemodel); // Update the line with the settings from the imported file
|
//$line->edit($linemodel); // Update the line with the settings from the imported file.
|
||||||
}
|
}
|
||||||
$line_map[$ix] = $line;
|
$line_map[$ix] = $line;
|
||||||
}
|
}
|
||||||
|
|
||||||
// next, let each study line import the study items
|
// next, let each study line import the study items.
|
||||||
$itemtranslation = [];
|
$itemtranslation = [];
|
||||||
$connections = [];
|
$connections = [];
|
||||||
foreach ($model as $ix => $linemodel) {
|
foreach ($model as $ix => $linemodel) {
|
||||||
$line_map[$ix]->import_studyitems($linemodel["slots"], $itemtranslation, $connections);
|
$line_map[$ix]->import_studyitems($linemodel["slots"], $itemtranslation, $connections);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, create the links between the study items
|
// Finally, create the links between the study items.
|
||||||
foreach ($connections as $from => $dests) {
|
foreach ($connections as $from => $dests) {
|
||||||
foreach ($dests as $to) {
|
foreach ($dests as $to) {
|
||||||
studyitemconnection::connect($from, $itemtranslation[$to]);
|
studyitemconnection::connect($from, $itemtranslation[$to]);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
|
|
||||||
|
@ -20,8 +40,7 @@ class success {
|
||||||
$this->msg = $msg;
|
$this->msg = $msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function structure()
|
public static function structure() {
|
||||||
{
|
|
||||||
return new \external_single_structure([
|
return new \external_single_structure([
|
||||||
"success" => new \external_value(PARAM_BOOL, 'operation completed succesfully'),
|
"success" => new \external_value(PARAM_BOOL, 'operation completed succesfully'),
|
||||||
"msg" => new \external_value(PARAM_TEXT, 'message'),
|
"msg" => new \external_value(PARAM_TEXT, 'message'),
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan\task;
|
namespace local_treestudyplan\task;
|
||||||
require_once($CFG->dirroot.'/course/externallib.php');
|
require_once($CFG->dirroot.'/course/externallib.php');
|
||||||
use local_treestudyplan\studyplan;
|
use local_treestudyplan\studyplan;
|
||||||
|
@ -25,7 +46,7 @@ class autocohortsync extends \core\task\scheduled_task {
|
||||||
$studyplans = studyplan::find_all();
|
$studyplans = studyplan::find_all();
|
||||||
|
|
||||||
foreach ($studyplans as $studyplan) {
|
foreach ($studyplans as $studyplan) {
|
||||||
// Only process studyplans that have been marked for change because
|
// Only process studyplans that have been marked for change because .
|
||||||
// a cohort change has occurred or a course has been added....
|
// a cohort change has occurred or a course has been added....
|
||||||
if ($studyplan->has_csync_changed()) {
|
if ($studyplan->has_csync_changed()) {
|
||||||
\mtrace("Studyplan {$studyplan->shortname()} needs processing");
|
\mtrace("Studyplan {$studyplan->shortname()} needs processing");
|
||||||
|
|
|
@ -1,10 +1,31 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan\task;
|
namespace local_treestudyplan\task;
|
||||||
require_once($CFG->dirroot.'/course/externallib.php');
|
require_once($CFG->dirroot.'/course/externallib.php');
|
||||||
use local_treestudyplan\teachingfinder;
|
use local_treestudyplan\teachingfinder;
|
||||||
|
|
||||||
class refreshteacherlist extends \core\task\scheduled_task {
|
class refreshteacherlist extends \core\task\scheduled_task {
|
||||||
const CACHE_TIME = 4 * 60 * 60; // 2 hours
|
const CACHE_TIME = 4 * 60 * 60; // 2 hours.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the task's name as shown in admin screens.
|
* Return the task's name as shown in admin screens.
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
|
|
||||||
class teachingfinder {
|
class teachingfinder {
|
||||||
|
@ -11,7 +32,7 @@ class teachingfinder {
|
||||||
|
|
||||||
$records = $DB->get_records(self::TABLE, ['teacher_id' => $userid]);
|
$records = $DB->get_records(self::TABLE, ['teacher_id' => $userid]);
|
||||||
if (count($records) == 0) {
|
if (count($records) == 0) {
|
||||||
// initiate a search if the cache is empty
|
// initiate a search if the cache is empty.
|
||||||
self::update_teaching_cache($userid);
|
self::update_teaching_cache($userid);
|
||||||
$DB->get_records(self::TABLE, ['teacher_id' => $userid]);
|
$DB->get_records(self::TABLE, ['teacher_id' => $userid]);
|
||||||
}
|
}
|
||||||
|
@ -32,14 +53,14 @@ class teachingfinder {
|
||||||
global $DB;
|
global $DB;
|
||||||
$list = [];
|
$list = [];
|
||||||
|
|
||||||
// First find all active study plans
|
// First find all active study plans.
|
||||||
|
|
||||||
$sql = "SELECT p.id FROM {local_treestudyplan_page} p
|
$sql = "SELECT p.id FROM {local_treestudyplan_page} p
|
||||||
WHERE startdate <= NOW() and enddate >= NOW()";
|
WHERE startdate <= NOW() and enddate >= NOW()";
|
||||||
$page_ids = $DB->get_fieldset_sql($sql, []);
|
$page_ids = $DB->get_fieldset_sql($sql, []);
|
||||||
|
|
||||||
// then parse them to see if the user has the grading permission in any of them
|
// then parse them to see if the user has the grading permission in any of them .
|
||||||
// (Which would make them a teacher for all intents and purposes)
|
// (Which would make them a teacher for all intents and purposes).
|
||||||
|
|
||||||
foreach ($page_ids as $page_id) {
|
foreach ($page_ids as $page_id) {
|
||||||
$sql = "SELECT i.course_id FROM {local_treestudyplan_item} i
|
$sql = "SELECT i.course_id FROM {local_treestudyplan_item} i
|
||||||
|
@ -52,24 +73,23 @@ class teachingfinder {
|
||||||
$coursecontext = \context_course::instance($cid);
|
$coursecontext = \context_course::instance($cid);
|
||||||
if (is_enrolled($coursecontext, $userid, 'mod/assign:grade')) {
|
if (is_enrolled($coursecontext, $userid, 'mod/assign:grade')) {
|
||||||
$linked = true;
|
$linked = true;
|
||||||
break; // No need to search further
|
break; // No need to search further.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($linked)
|
if ($linked) {
|
||||||
{
|
|
||||||
$list[] = $page_id;
|
$list[] = $page_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, clear the database of all records for this user
|
// Now, clear the database of all records for this user.
|
||||||
$DB->delete_records(self::TABLE, ["teacher_id"=>$userid]);
|
$DB->delete_records(self::TABLE, ["teacher_id"=>$userid]);
|
||||||
// And add new records for the found studyplans
|
// And add new records for the found studyplans.
|
||||||
$now = time();
|
$now = time();
|
||||||
foreach ($list as $page_id) {
|
foreach ($list as $page_id) {
|
||||||
// Retrieve the studyplan id from the page
|
// Retrieve the studyplan id from the page.
|
||||||
//TODO: Change this when page management is implemented to return the page instead of the plan
|
//TODO: Change this when page management is implemented to return the page instead of the plan.
|
||||||
$planid = $DB->get_field("local_treestudyplan_page", "studyplan_id", ["id" => $page_id]);
|
$planid = $DB->get_field("local_treestudyplan_page", "studyplan_id", ["id" => $page_id]);
|
||||||
$DB->insert_record(self::TABLE, ["teacher_id"=>$userid, "studyplan_id"=>$planid, "update_time"=>$now]);
|
$DB->insert_record(self::TABLE, ["teacher_id"=>$userid, "studyplan_id"=>$planid, "update_time"=>$now]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
|
|
||||||
use \local_treestudyplan\local\gradegenerator;
|
use \local_treestudyplan\local\gradegenerator;
|
||||||
|
@ -39,7 +60,7 @@ if ($options['help']) {
|
||||||
cli_writeln($usage);
|
cli_writeln($usage);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
//cli_writeln(print_r($options,true));
|
//cli_writeln(print_r($options, true));.
|
||||||
|
|
||||||
if (empty($options['studyplan']) && empty($options["all"])) {
|
if (empty($options['studyplan']) && empty($options["all"])) {
|
||||||
cli_error('Missing mandatory argument studyplan.', 2);
|
cli_error('Missing mandatory argument studyplan.', 2);
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
namespace local_treestudyplan;
|
namespace local_treestudyplan;
|
||||||
|
|
||||||
use \local_treestudyplan\local\gradegenerator;
|
use \local_treestudyplan\local\gradegenerator;
|
||||||
|
@ -46,7 +67,7 @@ if ($options['help']) {
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////.
|
||||||
$user = get_admin();
|
$user = get_admin();
|
||||||
|
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
|
@ -65,7 +86,7 @@ login_attempt_valid($user);
|
||||||
complete_user_login($user);
|
complete_user_login($user);
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////.
|
||||||
|
|
||||||
|
|
||||||
if (empty($options['studyplan']) && empty($options["all"])) {
|
if (empty($options['studyplan']) && empty($options["all"])) {
|
||||||
|
@ -95,7 +116,7 @@ foreach($plans as $plan){
|
||||||
cli_writeln(" ** {$line->name()} **");
|
cli_writeln(" ** {$line->name()} **");
|
||||||
$items = studyitem::find_studyline_children($line);
|
$items = studyitem::find_studyline_children($line);
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
if($item->type() == studyitem::COURSE) { // only handle courses for now
|
if ($item->type() == studyitem::COURSE) { // only handle courses for now.
|
||||||
$courseinfo = $item->getcourseinfo();
|
$courseinfo = $item->getcourseinfo();
|
||||||
cli_writeln(" # {$courseinfo->shortname()}");
|
cli_writeln(" # {$courseinfo->shortname()}");
|
||||||
|
|
||||||
|
@ -113,14 +134,14 @@ foreach($plans as $plan){
|
||||||
$grade = $gg->gradetext;
|
$grade = $gg->gradetext;
|
||||||
cli_write (" - {$name} = {$grade}");
|
cli_write (" - {$name} = {$grade}");
|
||||||
|
|
||||||
// Check if the item is alreaady graded for this user
|
// Check if the item is alreaady graded for this user.
|
||||||
$existing = $count = $DB->count_records_select('grade_grades', 'itemid = :gradeitemid AND finalgrade IS NOT NULL and userid = :userid',
|
$existing = $count = $DB->count_records_select('grade_grades', 'itemid = :gradeitemid AND finalgrade IS NOT NULL and userid = :userid',
|
||||||
['gradeitemid' => $gi->id, 'userid' => $u->id]);
|
['gradeitemid' => $gi->id, 'userid' => $u->id]);
|
||||||
|
|
||||||
if (!$existing) {
|
if (!$existing) {
|
||||||
if ($gg->grade > 0) {
|
if ($gg->grade > 0) {
|
||||||
if ($gi->itemmodule == "assign") {
|
if ($gi->itemmodule == "assign") {
|
||||||
// If it is an assignment, submit though that interface
|
// If it is an assignment, submit though that interface .
|
||||||
list($c, $cminfo) = get_course_and_cm_from_instance($gi->iteminstance, $gi->itemmodule);
|
list($c, $cminfo) = get_course_and_cm_from_instance($gi->iteminstance, $gi->itemmodule);
|
||||||
$cm_ctx = \context_module::instance($cminfo->id);
|
$cm_ctx = \context_module::instance($cminfo->id);
|
||||||
$a = new \assign($cm_ctx, $cminfo, $c);
|
$a = new \assign($cm_ctx, $cminfo, $c);
|
||||||
|
@ -131,7 +152,7 @@ foreach($plans as $plan){
|
||||||
$ug->feedbacktext = nl2br( htmlspecialchars($gg->fb));
|
$ug->feedbacktext = nl2br( htmlspecialchars($gg->fb));
|
||||||
$ug->feedbackformat = FORMAT_HTML;
|
$ug->feedbackformat = FORMAT_HTML;
|
||||||
|
|
||||||
//print_r($ug);
|
//print_r($ug);.
|
||||||
if (!$options["dryrun"]) {
|
if (!$options["dryrun"]) {
|
||||||
$a->update_grade($ug);
|
$a->update_grade($ug);
|
||||||
|
|
||||||
|
@ -142,7 +163,7 @@ foreach($plans as $plan){
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, set the grade through the manual grading override
|
// Otherwise, set the grade through the manual grading override.
|
||||||
cli_writeln(" ... Cannot store");
|
cli_writeln(" ... Cannot store");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
$capabilities = [
|
$capabilities = [
|
||||||
|
|
||||||
|
|
690
db/services.php
690
db/services.php
|
@ -1,4 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
$services = [
|
$services = [
|
||||||
"Competency listing" => [
|
"Competency listing" => [
|
||||||
|
@ -36,527 +56,527 @@ $functions = [
|
||||||
/***************************
|
/***************************
|
||||||
* Studyplan functions
|
* Studyplan functions
|
||||||
***************************/
|
***************************/
|
||||||
'local_treestudyplan_list_studyplans' => [ //web service function name
|
'local_treestudyplan_list_studyplans' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'list_studyplans', //external function name
|
'methodname' => 'list_studyplans', //external function name.
|
||||||
'description' => 'List available studyplans', //human readable description of the web service function
|
'description' => 'List available studyplans', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan, local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan, local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_get_studyplan_map' => [ //web service function name
|
'local_treestudyplan_get_studyplan_map' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'get_studyplan_map', //external function name
|
'methodname' => 'get_studyplan_map', //external function name.
|
||||||
'description' => 'Retrieve studyplan map', //human readable description of the web service function
|
'description' => 'Retrieve studyplan map', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan, local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan, local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_get_studyline_map' => [ //web service function name
|
'local_treestudyplan_get_studyline_map' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'get_studyline_map', //external function name
|
'methodname' => 'get_studyline_map', //external function name.
|
||||||
'description' => 'Retrieve studyline map', //human readable description of the web service function
|
'description' => 'Retrieve studyline map', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_add_studyplan' => [ //web service function name
|
'local_treestudyplan_add_studyplan' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'add_studyplan', //external function name
|
'methodname' => 'add_studyplan', //external function name.
|
||||||
'description' => 'Add studyplan', //human readable description of the web service function
|
'description' => 'Add studyplan', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_add_studyline' => [ //web service function name
|
'local_treestudyplan_add_studyline' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'add_studyline', //external function name
|
'methodname' => 'add_studyline', //external function name.
|
||||||
'description' => 'Add studyline', //human readable description of the web service function
|
'description' => 'Add studyline', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_edit_studyplan' => [ //web service function name
|
'local_treestudyplan_edit_studyplan' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'edit_studyplan', //external function name
|
'methodname' => 'edit_studyplan', //external function name.
|
||||||
'description' => 'Edit studyplan', //human readable description of the web service function
|
'description' => 'Edit studyplan', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_edit_studyline' => [ //web service function name
|
'local_treestudyplan_edit_studyline' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'edit_studyline', //external function name
|
'methodname' => 'edit_studyline', //external function name.
|
||||||
'description' => 'Edit studyline', //human readable description of the web service function
|
'description' => 'Edit studyline', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_delete_studyplan' => [ //web service function name
|
'local_treestudyplan_delete_studyplan' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'delete_studyplan', //external function name
|
'methodname' => 'delete_studyplan', //external function name.
|
||||||
'description' => 'Delete studyplan', //human readable description of the web service function
|
'description' => 'Delete studyplan', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_delete_studyline' => [ //web service function name
|
'local_treestudyplan_delete_studyline' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'delete_studyline', //external function name
|
'methodname' => 'delete_studyline', //external function name.
|
||||||
'description' => 'Delete studyline', //human readable description of the web service function
|
'description' => 'Delete studyline', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_reorder_studylines' => [ //web service function name
|
'local_treestudyplan_reorder_studylines' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'reorder_studylines', //external function name
|
'methodname' => 'reorder_studylines', //external function name.
|
||||||
'description' => 'Reorder studylines', //human readable description of the web service function
|
'description' => 'Reorder studylines', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_get_studyitem' => [ //web service function name
|
'local_treestudyplan_get_studyitem' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'get_studyitem', //external function name
|
'methodname' => 'get_studyitem', //external function name.
|
||||||
'description' => 'Retrieve study item', //human readable description of the web service function
|
'description' => 'Retrieve study item', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_add_studyitem' => [ //web service function name
|
'local_treestudyplan_add_studyitem' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'add_studyitem', //external function name
|
'methodname' => 'add_studyitem', //external function name.
|
||||||
'description' => 'Add study item', //human readable description of the web service function
|
'description' => 'Add study item', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_edit_studyitem' => [ //web service function name
|
'local_treestudyplan_edit_studyitem' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'edit_studyitem', //external function name
|
'methodname' => 'edit_studyitem', //external function name.
|
||||||
'description' => 'Edit study item', //human readable description of the web service function
|
'description' => 'Edit study item', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_reorder_studyitems' => [ //web service function name
|
'local_treestudyplan_reorder_studyitems' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'reorder_studyitems', //external function name
|
'methodname' => 'reorder_studyitems', //external function name.
|
||||||
'description' => 'Reorder study items', //human readable description of the web service function
|
'description' => 'Reorder study items', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_delete_studyitem' => [ //web service function name
|
'local_treestudyplan_delete_studyitem' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'delete_studyitem', //external function name
|
'methodname' => 'delete_studyitem', //external function name.
|
||||||
'description' => 'Delete study item', //human readable description of the web service function
|
'description' => 'Delete study item', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_connect_studyitems' => [ //web service function name
|
'local_treestudyplan_connect_studyitems' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'connect_studyitems', //external function name
|
'methodname' => 'connect_studyitems', //external function name.
|
||||||
'description' => 'Connect study items', //human readable description of the web service function
|
'description' => 'Connect study items', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_disconnect_studyitems' => [ //web service function name
|
'local_treestudyplan_disconnect_studyitems' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'disconnect_studyitems', //external function name
|
'methodname' => 'disconnect_studyitems', //external function name.
|
||||||
'description' => 'Disconnect study items', //human readable description of the web service function
|
'description' => 'Disconnect study items', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
/***************************
|
/***************************
|
||||||
* Badge functions
|
* Badge functions
|
||||||
***************************/
|
***************************/
|
||||||
|
|
||||||
'local_treestudyplan_list_badges' => [ //web service function name
|
'local_treestudyplan_list_badges' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'list_badges', //external function name
|
'methodname' => 'list_badges', //external function name.
|
||||||
'description' => 'List availabel site badges', //human readable description of the web service function
|
'description' => 'List availabel site badges', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
/***************************
|
/***************************
|
||||||
* Association functions
|
* Association functions
|
||||||
***************************/
|
***************************/
|
||||||
'local_treestudyplan_list_cohort' => [ //web service function name
|
'local_treestudyplan_list_cohort' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\associationservice', //class containing the external function
|
'classname' => '\local_treestudyplan\associationservice', //class containing the external function.
|
||||||
'methodname' => 'list_cohort', //external function name
|
'methodname' => 'list_cohort', //external function name.
|
||||||
'description' => 'List available cohorts', //human readable description of the web service function
|
'description' => 'List available cohorts', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_find_user' => [ //web service function name
|
'local_treestudyplan_find_user' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\associationservice', //class containing the external function
|
'classname' => '\local_treestudyplan\associationservice', //class containing the external function.
|
||||||
'methodname' => 'find_user', //external function name
|
'methodname' => 'find_user', //external function name.
|
||||||
'description' => 'Find user', //human readable description of the web service function
|
'description' => 'Find user', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_connect_cohort' => [ //web service function name
|
'local_treestudyplan_connect_cohort' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\associationservice', //class containing the external function
|
'classname' => '\local_treestudyplan\associationservice', //class containing the external function.
|
||||||
'methodname' => 'connect_cohort', //external function name
|
'methodname' => 'connect_cohort', //external function name.
|
||||||
'description' => 'Connect cohort to studyplan', //human readable description of the web service function
|
'description' => 'Connect cohort to studyplan', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_disconnect_cohort' => [ //web service function name
|
'local_treestudyplan_disconnect_cohort' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\associationservice', //class containing the external function
|
'classname' => '\local_treestudyplan\associationservice', //class containing the external function.
|
||||||
'methodname' => 'disconnect_cohort', //external function name
|
'methodname' => 'disconnect_cohort', //external function name.
|
||||||
'description' => 'Disconnect cohort from study plan', //human readable description of the web service function
|
'description' => 'Disconnect cohort from study plan', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'local_treestudyplan_connect_user' => [ //web service function name
|
'local_treestudyplan_connect_user' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\associationservice', //class containing the external function
|
'classname' => '\local_treestudyplan\associationservice', //class containing the external function.
|
||||||
'methodname' => 'connect_user', //external function name
|
'methodname' => 'connect_user', //external function name.
|
||||||
'description' => 'Connect user to study plan', //human readable description of the web service function
|
'description' => 'Connect user to study plan', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_disconnect_user' => [ //web service function name
|
'local_treestudyplan_disconnect_user' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\associationservice', //class containing the external function
|
'classname' => '\local_treestudyplan\associationservice', //class containing the external function.
|
||||||
'methodname' => 'disconnect_user', //external function name
|
'methodname' => 'disconnect_user', //external function name.
|
||||||
'description' => 'Disconnect user from studyplan', //human readable description of the web service function
|
'description' => 'Disconnect user from studyplan', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_associated_users' => [ //web service function name
|
'local_treestudyplan_associated_users' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\associationservice', //class containing the external function
|
'classname' => '\local_treestudyplan\associationservice', //class containing the external function.
|
||||||
'methodname' => 'associated_users', //external function name
|
'methodname' => 'associated_users', //external function name.
|
||||||
'description' => 'List users associated with a studyplan', //human readable description of the web service function
|
'description' => 'List users associated with a studyplan', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_associated_cohorts' => [ //web service function name
|
'local_treestudyplan_associated_cohorts' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\associationservice', //class containing the external function
|
'classname' => '\local_treestudyplan\associationservice', //class containing the external function.
|
||||||
'methodname' => 'associated_cohorts', //external function name
|
'methodname' => 'associated_cohorts', //external function name.
|
||||||
'description' => 'List cohorts associated with a studyplan', //human readable description of the web service function
|
'description' => 'List cohorts associated with a studyplan', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_list_user_studyplans' => [ //web service function name
|
'local_treestudyplan_list_user_studyplans' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function.
|
||||||
'methodname' => 'list_user_studyplans', //external function name
|
'methodname' => 'list_user_studyplans', //external function name.
|
||||||
'description' => 'List user studyplans', //human readable description of the web service function
|
'description' => 'List user studyplans', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_get_user_studyplans' => [ //web service function name
|
'local_treestudyplan_get_user_studyplans' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function.
|
||||||
'methodname' => 'get_user_studyplans', //external function name
|
'methodname' => 'get_user_studyplans', //external function name.
|
||||||
'description' => 'Retrieve user studyplan', //human readable description of the web service function
|
'description' => 'Retrieve user studyplan', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_get_user_studyplan' => [ //web service function name
|
'local_treestudyplan_get_user_studyplan' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function.
|
||||||
'methodname' => 'get_user_studyplan', //external function name
|
'methodname' => 'get_user_studyplan', //external function name.
|
||||||
'description' => 'Retrieve user studyplan', //human readable description of the web service function
|
'description' => 'Retrieve user studyplan', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_get_invited_studyplan' => [ //web service function name
|
'local_treestudyplan_get_invited_studyplan' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function.
|
||||||
'methodname' => 'get_invited_studyplan', //external function name
|
'methodname' => 'get_invited_studyplan', //external function name.
|
||||||
'description' => 'Retrieve user studyplan based on invite', //human readable description of the web service function
|
'description' => 'Retrieve user studyplan based on invite', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => '', // Advises the admin which capabilities are required
|
'capabilities' => '', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => false,
|
'loginrequired' => false,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_list_own_studyplans' => [ //web service function name
|
'local_treestudyplan_list_own_studyplans' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function.
|
||||||
'methodname' => 'list_own_studyplans', //external function name
|
'methodname' => 'list_own_studyplans', //external function name.
|
||||||
'description' => 'List own studyplans', //human readable description of the web service function
|
'description' => 'List own studyplans', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => '', // Advises the admin which capabilities are required
|
'capabilities' => '', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_get_own_studyplan' => [ //web service function name
|
'local_treestudyplan_get_own_studyplan' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function.
|
||||||
'methodname' => 'get_own_studyplan', //external function name
|
'methodname' => 'get_own_studyplan', //external function name.
|
||||||
'description' => 'Retrieve own studyplan', //human readable description of the web service function
|
'description' => 'Retrieve own studyplan', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => '', // Advises the admin which capabilities are required
|
'capabilities' => '', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_map_categories' => [ //web service function name
|
'local_treestudyplan_map_categories' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\courseservice', //class containing the external function
|
'classname' => '\local_treestudyplan\courseservice', //class containing the external function.
|
||||||
'methodname' => 'map_categories', //external function name
|
'methodname' => 'map_categories', //external function name.
|
||||||
'description' => 'List available root categories', //human readable description of the web service function
|
'description' => 'List available root categories', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_get_category' => [ //web service function name
|
'local_treestudyplan_get_category' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\courseservice', //class containing the external function
|
'classname' => '\local_treestudyplan\courseservice', //class containing the external function.
|
||||||
'methodname' => 'get_category', //external function name
|
'methodname' => 'get_category', //external function name.
|
||||||
'description' => 'Get details for specified category', //human readable description of the web service function
|
'description' => 'Get details for specified category', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_include_grade' => [ //web service function name
|
'local_treestudyplan_include_grade' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'include_grade', //external function name
|
'methodname' => 'include_grade', //external function name.
|
||||||
'description' => 'Include gradable in result', //human readable description of the web service function
|
'description' => 'Include gradable in result', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan, local/treestudyplan:selectowngradables', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan, local/treestudyplan:selectowngradables', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_all_associated' => [ //web service function name
|
'local_treestudyplan_all_associated' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\associationservice', //class containing the external function
|
'classname' => '\local_treestudyplan\associationservice', //class containing the external function.
|
||||||
'methodname' => 'all_associated', //external function name
|
'methodname' => 'all_associated', //external function name.
|
||||||
'description' => 'List associated users', //human readable description of the web service function
|
'description' => 'List associated users', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_list_aggregators' => [ //web service function name
|
'local_treestudyplan_list_aggregators' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'list_aggregators', //external function name
|
'methodname' => 'list_aggregators', //external function name.
|
||||||
'description' => 'List available aggregators', //human readable description of the web service function
|
'description' => 'List available aggregators', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_disable_autoenddate' => [ //web service function name
|
'local_treestudyplan_disable_autoenddate' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'disable_autoenddate', //external function name
|
'methodname' => 'disable_autoenddate', //external function name.
|
||||||
'description' => 'Disable automatic end dates on courses in the study plan', //human readable description of the web service function
|
'description' => 'Disable automatic end dates on courses in the study plan', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:forcescales', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:forcescales', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_force_studyplan_scale' => [ //web service function name
|
'local_treestudyplan_force_studyplan_scale' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'force_studyplan_scale', //external function name
|
'methodname' => 'force_studyplan_scale', //external function name.
|
||||||
'description' => 'Change all associated gradables to the chosen scale if possible', //human readable description of the web service function
|
'description' => 'Change all associated gradables to the chosen scale if possible', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:forcescales', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:forcescales', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_list_scales' => [ //web service function name
|
'local_treestudyplan_list_scales' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'list_scales', //external function name
|
'methodname' => 'list_scales', //external function name.
|
||||||
'description' => 'List system scales', //human readable description of the web service function
|
'description' => 'List system scales', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:forcescales', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:forcescales', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_duplicate_plan' => [ //web service function name
|
'local_treestudyplan_duplicate_plan' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'duplicate_plan', //external function name
|
'methodname' => 'duplicate_plan', //external function name.
|
||||||
'description' => 'Copy studyplan', //human readable description of the web service function
|
'description' => 'Copy studyplan', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_export_plan' => [ //web service function name
|
'local_treestudyplan_export_plan' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'export_plan', //external function name
|
'methodname' => 'export_plan', //external function name.
|
||||||
'description' => 'Export study plan', //human readable description of the web service function
|
'description' => 'Export study plan', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_export_studylines' => [ //web service function name
|
'local_treestudyplan_export_studylines' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'export_studylines', //external function name
|
'methodname' => 'export_studylines', //external function name.
|
||||||
'description' => 'Export study plan', //human readable description of the web service function
|
'description' => 'Export study plan', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_import_plan' => [ //web service function name
|
'local_treestudyplan_import_plan' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'import_plan', //external function name
|
'methodname' => 'import_plan', //external function name.
|
||||||
'description' => 'Import study plan', //human readable description of the web service function
|
'description' => 'Import study plan', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_import_studylines' => [ //web service function name
|
'local_treestudyplan_import_studylines' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'import_studylines', //external function name
|
'methodname' => 'import_studylines', //external function name.
|
||||||
'description' => 'Import study plan', //human readable description of the web service function
|
'description' => 'Import study plan', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_edit_period' => [ //web service function name
|
'local_treestudyplan_edit_period' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'edit_period', //external function name
|
'methodname' => 'edit_period', //external function name.
|
||||||
'description' => 'Edit period name and timing', //human readable description of the web service function
|
'description' => 'Edit period name and timing', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_submit_cm_editform' => [ //web service function name
|
'local_treestudyplan_submit_cm_editform' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'submit_cm_editform', //external function name
|
'methodname' => 'submit_cm_editform', //external function name.
|
||||||
'description' => 'Submit course module edit form', //human readable description of the web service function
|
'description' => 'Submit course module edit form', //human readable description of the web service function.
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
'type' => 'write', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_get_teaching_studyplans' => [ //web service function name
|
'local_treestudyplan_get_teaching_studyplans' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studentstudyplanservice', //class containing the external function.
|
||||||
'methodname' => 'get_teaching_studyplans', //external function name
|
'methodname' => 'get_teaching_studyplans', //external function name.
|
||||||
'description' => 'Get the studyplans I currently teach in', //human readable description of the web service function
|
'description' => 'Get the studyplans I currently teach in', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required.
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_list_accessible_categories' => [ //web service function name
|
'local_treestudyplan_list_accessible_categories' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\courseservice', //class containing the external function
|
'classname' => '\local_treestudyplan\courseservice', //class containing the external function.
|
||||||
'methodname' => 'list_accessible_categories', //external function name
|
'methodname' => 'list_accessible_categories', //external function name.
|
||||||
'description' => 'Get categories accessible to the current user', //human readable description of the web service function
|
'description' => 'Get categories accessible to the current user', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_list_used_categories' => [ //web service function name
|
'local_treestudyplan_list_used_categories' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\courseservice', //class containing the external function
|
'classname' => '\local_treestudyplan\courseservice', //class containing the external function.
|
||||||
'methodname' => 'list_used_categories', //external function name
|
'methodname' => 'list_used_categories', //external function name.
|
||||||
'description' => 'Get categories hosting a studyplan', //human readable description of the web service function
|
'description' => 'Get categories hosting a studyplan', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_scan_badge_progress' => [ //web service function name
|
'local_treestudyplan_scan_badge_progress' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\courseservice', //class containing the external function
|
'classname' => '\local_treestudyplan\courseservice', //class containing the external function.
|
||||||
'methodname' => 'scan_badge_progress', //external function name
|
'methodname' => 'scan_badge_progress', //external function name.
|
||||||
'description' => 'Scan progress of students in attaining badge', //human readable description of the web service function
|
'description' => 'Scan progress of students in attaining badge', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required.
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_scan_completion_progress' => [ //web service function name
|
'local_treestudyplan_scan_completion_progress' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\courseservice', //class containing the external function
|
'classname' => '\local_treestudyplan\courseservice', //class containing the external function.
|
||||||
'methodname' => 'scan_completion_progress', //external function name
|
'methodname' => 'scan_completion_progress', //external function name.
|
||||||
'description' => 'Scan progress of students in attaining completions', //human readable description of the web service function
|
'description' => 'Scan progress of students in attaining completions', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required.
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_scan_grade_progress' => [ //web service function name
|
'local_treestudyplan_scan_grade_progress' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\courseservice', //class containing the external function
|
'classname' => '\local_treestudyplan\courseservice', //class containing the external function.
|
||||||
'methodname' => 'scan_grade_progress', //external function name
|
'methodname' => 'scan_grade_progress', //external function name.
|
||||||
'description' => 'Scan progress of students in attaining grades', //human readable description of the web service function
|
'description' => 'Scan progress of students in attaining grades', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:viewuserreports', // Advises the admin which capabilities are required.
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_cascade_cohortsync' => [ //web service function name
|
'local_treestudyplan_cascade_cohortsync' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\associationservice', //class containing the external function
|
'classname' => '\local_treestudyplan\associationservice', //class containing the external function.
|
||||||
'methodname' => 'cascade_cohortsync', //external function name
|
'methodname' => 'cascade_cohortsync', //external function name.
|
||||||
'description' => 'Sync cohortsync to studyplan association', //human readable description of the web service function
|
'description' => 'Sync cohortsync to studyplan association', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_course_period_timing' => [ //web service function name
|
'local_treestudyplan_course_period_timing' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'course_period_timing', //external function name
|
'methodname' => 'course_period_timing', //external function name.
|
||||||
'description' => 'Chenge course start and end times to match period', //human readable description of the web service function
|
'description' => 'Chenge course start and end times to match period', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
'local_treestudyplan_set_studyitem_span' => [ //web service function name
|
'local_treestudyplan_set_studyitem_span' => [ //web service function name.
|
||||||
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function
|
'classname' => '\local_treestudyplan\studyplanservice', //class containing the external function.
|
||||||
'methodname' => 'set_studyitem_span', //external function name
|
'methodname' => 'set_studyitem_span', //external function name.
|
||||||
'description' => 'Change the span of a course item', //human readable description of the web service function
|
'description' => 'Change the span of a course item', //human readable description of the web service function.
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
'type' => 'read', //database rights of the web service function (read, write).
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required
|
'capabilities' => 'local/treestudyplan:editstudyplan', // Advises the admin which capabilities are required.
|
||||||
'ajax' => true,
|
'ajax' => true,
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
|
21
db/tasks.php
21
db/tasks.php
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
$tasks = [
|
$tasks = [
|
||||||
[
|
[
|
||||||
'classname' => 'local_treestudyplan\task\autocohortsync',
|
'classname' => 'local_treestudyplan\task\autocohortsync',
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
function xmldb_local_treestudyplan_upgrade($oldversion) {
|
function xmldb_local_treestudyplan_upgrade($oldversion) {
|
||||||
global $DB;
|
global $DB;
|
||||||
$dbman = $DB->get_manager();
|
$dbman = $DB->get_manager();
|
||||||
|
@ -266,7 +287,7 @@ function xmldb_local_treestudyplan_upgrade($oldversion) {
|
||||||
if (!$dbman->table_exists($table)) {
|
if (!$dbman->table_exists($table)) {
|
||||||
$dbman->create_table($table);
|
$dbman->create_table($table);
|
||||||
|
|
||||||
// Create a page 0 with it's data copied
|
// Create a page 0 with it's data copied.
|
||||||
$plans = $DB->get_recordset("local_treestudyplan");
|
$plans = $DB->get_recordset("local_treestudyplan");
|
||||||
foreach ($plans as $p) {
|
foreach ($plans as $p) {
|
||||||
$o = [ "studyplan_id" => $p->id,
|
$o = [ "studyplan_id" => $p->id,
|
||||||
|
@ -279,8 +300,8 @@ function xmldb_local_treestudyplan_upgrade($oldversion) {
|
||||||
];
|
];
|
||||||
$pageid = $DB->insert_record("local_treestudyplan_page", $o);
|
$pageid = $DB->insert_record("local_treestudyplan_page", $o);
|
||||||
|
|
||||||
// Now find all studyline references to the studyplan
|
// Now find all studyline references to the studyplan .
|
||||||
// And update their record to reference the page instead of the plan
|
// And update their record to reference the page instead of the plan.
|
||||||
$lines = $DB->get_recordset("local_treestudyplan_line", ["studyplan_id" => $p->id]);
|
$lines = $DB->get_recordset("local_treestudyplan_line", ["studyplan_id" => $p->id]);
|
||||||
foreach ($lines as $l) {
|
foreach ($lines as $l) {
|
||||||
$lo = [
|
$lo = [
|
||||||
|
@ -347,16 +368,16 @@ function xmldb_local_treestudyplan_upgrade($oldversion) {
|
||||||
if (!$dbman->table_exists($table)) {
|
if (!$dbman->table_exists($table)) {
|
||||||
$dbman->create_table($table);
|
$dbman->create_table($table);
|
||||||
|
|
||||||
// Create a period page for all slots in the study
|
// Create a period page for all slots in the study.
|
||||||
$recordset = $DB->get_recordset("local_treestudyplan_page");
|
$recordset = $DB->get_recordset("local_treestudyplan_page");
|
||||||
foreach ($recordset as $r) {
|
foreach ($recordset as $r) {
|
||||||
|
|
||||||
// Make a best guess for the periods based on the specified period for the plan and the
|
// Make a best guess for the periods based on the specified period for the plan and the .
|
||||||
$pcount = $r->periods;
|
$pcount = $r->periods;
|
||||||
$ystart = strtotime($r->startdate)+0;
|
$ystart = strtotime($r->startdate)+0;
|
||||||
$yend = strtotime($r->enddate)+0;
|
$yend = strtotime($r->enddate)+0;
|
||||||
if ($yend < $ystart) {
|
if ($yend < $ystart) {
|
||||||
// If no end time is given, assume a year duration for period calculations
|
// If no end time is given, assume a year duration for period calculations.
|
||||||
$ydelta = (365*24*60*60)/$pcount;
|
$ydelta = (365*24*60*60)/$pcount;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -367,7 +388,7 @@ function xmldb_local_treestudyplan_upgrade($oldversion) {
|
||||||
for($i=0; $i < $pcount; $i++) {
|
for($i=0; $i < $pcount; $i++) {
|
||||||
$pnum = $i+1;
|
$pnum = $i+1;
|
||||||
$pstart = $ystart + ($i*$ptime);
|
$pstart = $ystart + ($i*$ptime);
|
||||||
$pend = ($pstart + $ptime)-(24*60*60); // minus one day
|
$pend = ($pstart + $ptime)-(24*60*60); // minus one day.
|
||||||
|
|
||||||
$o = [ "page_id" => $r->id,
|
$o = [ "page_id" => $r->id,
|
||||||
"period" => $pnum,
|
"period" => $pnum,
|
||||||
|
@ -458,8 +479,8 @@ function xmldb_local_treestudyplan_upgrade($oldversion) {
|
||||||
|
|
||||||
if ($oldversion < 2023082100) {
|
if ($oldversion < 2023082100) {
|
||||||
|
|
||||||
// Up to version 20230821 the studyplan_id field still existed in the install.xml file
|
// Up to version 20230821 the studyplan_id field still existed in the install.xml file.
|
||||||
// Below code remedies that - even though this is a repeat of part of an earlier upgrade
|
// Below code remedies that - even though this is a repeat of part of an earlier upgrade.
|
||||||
|
|
||||||
// Define field studyplan_id to be dropped from local_treestudyplan_line.
|
// Define field studyplan_id to be dropped from local_treestudyplan_line.
|
||||||
$table = new xmldb_table('local_treestudyplan_line');
|
$table = new xmldb_table('local_treestudyplan_line');
|
||||||
|
|
26
doc.php
26
doc.php
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
require_once("../../config.php");
|
require_once("../../config.php");
|
||||||
|
|
||||||
require_once($CFG->libdir.'/weblib.php');
|
require_once($CFG->libdir.'/weblib.php');
|
||||||
|
@ -14,7 +35,7 @@ require_login();
|
||||||
$pi = $_SERVER['PATH_INFO'];
|
$pi = $_SERVER['PATH_INFO'];
|
||||||
$file = $CFG->dirroot."/local/treestudyplan/doc".$pi;
|
$file = $CFG->dirroot."/local/treestudyplan/doc".$pi;
|
||||||
|
|
||||||
// Fallback to index
|
// Fallback to index.
|
||||||
if (!file_exists($file)) {
|
if (!file_exists($file)) {
|
||||||
$file = $CFG->dirroot."/local/treestudyplan/doc/index.htm";
|
$file = $CFG->dirroot."/local/treestudyplan/doc/index.htm";
|
||||||
}
|
}
|
||||||
|
@ -22,8 +43,7 @@ if(!file_exists($file)){
|
||||||
$mime = mime_content_type($file);
|
$mime = mime_content_type($file);
|
||||||
$text_types = ["text/html", "text/plain"];
|
$text_types = ["text/html", "text/plain"];
|
||||||
|
|
||||||
if( in_array($mime,$text_types))
|
if ( in_array($mime, $text_types)) {
|
||||||
{
|
|
||||||
print $OUTPUT->header();
|
print $OUTPUT->header();
|
||||||
print file_get_contents($file);
|
print file_get_contents($file);
|
||||||
print $OUTPUT->footer();
|
print $OUTPUT->footer();
|
||||||
|
|
|
@ -1,23 +1,32 @@
|
||||||
<?php
|
<?php
|
||||||
if(isset($_SERVER['SCRIPT_FILENAME']))
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
{
|
//
|
||||||
// If SCRIPT_FILENAME is set, use that so the symlinked directories the developmen environment uses are handled correctly
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
$root = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])));
|
// it under the terms of the GNU General Public License as published by
|
||||||
error_log("Using {$root}/config.php");
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
require_once($root."/config.php");
|
// (at your option) any later version.
|
||||||
}
|
//
|
||||||
else
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
{
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// If not, assume the cwd is not symlinked and proceed as we are used to
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
require_once("../../config.php");
|
// GNU General Public License for more details.
|
||||||
}
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once("../../config.php");
|
||||||
|
|
||||||
require_once("./lib.php");
|
require_once("./lib.php");
|
||||||
require_once($CFG->libdir.'/weblib.php');
|
require_once($CFG->libdir.'/weblib.php');
|
||||||
require_once($CFG->dirroot.'/local/treestudyplan/classes/reportinvite_form.php');
|
require_once($CFG->dirroot.'/local/treestudyplan/classes/reportinvite_form.php');
|
||||||
|
|
||||||
$add = optional_param('add', '', PARAM_ALPHANUM); // module name
|
$add = optional_param('add', '', PARAM_ALPHANUM); // module name.
|
||||||
$update = optional_param('update', 0, PARAM_INT);
|
$update = optional_param('update', 0, PARAM_INT);
|
||||||
$resend = optional_param('resend', 0, PARAM_INT);
|
$resend = optional_param('resend', 0, PARAM_INT);
|
||||||
$delete = optional_param('delete', 0, PARAM_INT);
|
$delete = optional_param('delete', 0, PARAM_INT);
|
||||||
|
@ -28,8 +37,7 @@ $PAGE->set_url("/local/treestudyplan/edit-invite.php");
|
||||||
$PAGE->set_pagelayout('base');
|
$PAGE->set_pagelayout('base');
|
||||||
$PAGE->set_context($systemcontext);
|
$PAGE->set_context($systemcontext);
|
||||||
|
|
||||||
if($update > 0)
|
if ($update > 0) {
|
||||||
{
|
|
||||||
$PAGE->set_title(get_string('invite_desc_edit', 'local_treestudyplan'));
|
$PAGE->set_title(get_string('invite_desc_edit', 'local_treestudyplan'));
|
||||||
$PAGE->set_heading(get_string('invite_desc_edit', 'local_treestudyplan'));
|
$PAGE->set_heading(get_string('invite_desc_edit', 'local_treestudyplan'));
|
||||||
}
|
}
|
||||||
|
@ -40,20 +48,18 @@ else
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check if user has capability to manage study plan units
|
// Check if user has capability to manage study plan units.
|
||||||
require_login();
|
require_login();
|
||||||
|
|
||||||
print $OUTPUT->header();
|
print $OUTPUT->header();
|
||||||
|
|
||||||
if(!empty($add))
|
if (!empty($add)) {
|
||||||
{
|
|
||||||
$data = array(
|
$data = array(
|
||||||
'add' => 1,
|
'add' => 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(!empty($update))
|
else if (!empty($update)) {
|
||||||
{
|
|
||||||
$data = $DB->get_record("local_treestudyplan_invit", array('id' => $update));
|
$data = $DB->get_record("local_treestudyplan_invit", array('id' => $update));
|
||||||
$data->update = $update;
|
$data->update = $update;
|
||||||
if (empty($data) || $data->user_id != $USER->id)
|
if (empty($data) || $data->user_id != $USER->id)
|
||||||
|
@ -63,8 +69,7 @@ else if(!empty($update))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(!empty($resend))
|
else if (!empty($resend)) {
|
||||||
{
|
|
||||||
$data = $DB->get_record("local_treestudyplan_invit", array('id' => $resend));
|
$data = $DB->get_record("local_treestudyplan_invit", array('id' => $resend));
|
||||||
$data->resend = $resend;
|
$data->resend = $resend;
|
||||||
if (empty($data) || $data->user_id != $USER->id)
|
if (empty($data) || $data->user_id != $USER->id)
|
||||||
|
@ -73,7 +78,7 @@ else if(!empty($resend))
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do some resending of an invitation
|
// Do some resending of an invitation.
|
||||||
local_treestudyplan_send_invite($data->id);
|
local_treestudyplan_send_invite($data->id);
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,8 +87,7 @@ else if(!empty($resend))
|
||||||
print $OUTPUT->footer();
|
print $OUTPUT->footer();
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
else if(!empty($delete))
|
else if (!empty($delete)) {
|
||||||
{
|
|
||||||
$data = $DB->get_record("local_treestudyplan_invit", array('id' => $delete));
|
$data = $DB->get_record("local_treestudyplan_invit", array('id' => $delete));
|
||||||
$data->delete = $delete;
|
$data->delete = $delete;
|
||||||
if (empty($data) || $data->user_id != $USER->id)
|
if (empty($data) || $data->user_id != $USER->id)
|
||||||
|
@ -105,12 +109,10 @@ else {
|
||||||
$mform = new reportinvite_form();
|
$mform = new reportinvite_form();
|
||||||
$mform->set_data($data);
|
$mform->set_data($data);
|
||||||
|
|
||||||
if($mform->is_cancelled())
|
if ($mform->is_cancelled()) {
|
||||||
{
|
|
||||||
redirect("$CFG->wwwroot/local/treestudyplan/invitations.php");
|
redirect("$CFG->wwwroot/local/treestudyplan/invitations.php");
|
||||||
}
|
}
|
||||||
else if ($data = $mform->get_data())
|
else if ($data = $mform->get_data()) {
|
||||||
{
|
|
||||||
if (!empty($data->update))
|
if (!empty($data->update))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -128,7 +130,7 @@ else if ($data = $mform->get_data())
|
||||||
|
|
||||||
$id = $DB->insert_record("local_treestudyplan_invit", $data, true);
|
$id = $DB->insert_record("local_treestudyplan_invit", $data, true);
|
||||||
|
|
||||||
// Send invitaion mail
|
// Send invitaion mail.
|
||||||
local_treestudyplan_send_invite($id);
|
local_treestudyplan_send_invite($id);
|
||||||
|
|
||||||
redirect("$CFG->wwwroot/local/treestudyplan/invitations.php?sent={$id}");
|
redirect("$CFG->wwwroot/local/treestudyplan/invitations.php?sent={$id}");
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
require_once("../../config.php");
|
require_once("../../config.php");
|
||||||
|
|
||||||
require_once($CFG->libdir.'/weblib.php');
|
require_once($CFG->libdir.'/weblib.php');
|
||||||
|
@ -10,15 +31,14 @@ $systemcontext = context_system::instance();
|
||||||
$PAGE->set_url("/local/treestudyplan/edit-plan.php", array());
|
$PAGE->set_url("/local/treestudyplan/edit-plan.php", array());
|
||||||
require_login();
|
require_login();
|
||||||
|
|
||||||
// Figure out the context (category or system, based on either category or context parameter)
|
// Figure out the context (category or system, based on either category or context parameter).
|
||||||
$categoryid = optional_param('categoryid', 0, PARAM_INT); // Category id
|
$categoryid = optional_param('categoryid', 0, PARAM_INT); // Category id.
|
||||||
$contextid = optional_param('contextid', 0, PARAM_INT); // Context id
|
$contextid = optional_param('contextid', 0, PARAM_INT); // Context id.
|
||||||
if ($categoryid > 0) {
|
if ($categoryid > 0) {
|
||||||
$studyplancontext = context_coursecat::instance($categoryid);
|
$studyplancontext = context_coursecat::instance($categoryid);
|
||||||
|
|
||||||
}
|
}
|
||||||
elseif($contextid > 0)
|
else if ($contextid > 0) {
|
||||||
{
|
|
||||||
$studyplancontext = context::instance_by_id($contextid);
|
$studyplancontext = context::instance_by_id($contextid);
|
||||||
if (in_array($studyplancontext->contextlevel, [CONTEXT_SYSTEM, CONTEXT_COURSECAT]))
|
if (in_array($studyplancontext->contextlevel, [CONTEXT_SYSTEM, CONTEXT_COURSECAT]))
|
||||||
{
|
{
|
||||||
|
@ -31,16 +51,16 @@ elseif($contextid > 0)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If no context is selected, find the first available one
|
// If no context is selected, find the first available one.
|
||||||
$available_contexts = courseservice::list_accessible_categories_with_usage("edit");
|
$available_contexts = courseservice::list_accessible_categories_with_usage("edit");
|
||||||
$contextid=1; // fallback to system context
|
$contextid=1; // fallback to system context.
|
||||||
foreach ($available_contexts as $ctx) {
|
foreach ($available_contexts as $ctx) {
|
||||||
if ($ctx->count > 0) {
|
if ($ctx->count > 0) {
|
||||||
$contextid = $ctx->ctxid;
|
$contextid = $ctx->ctxid;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// reload page with selected category
|
// reload page with selected category.
|
||||||
$url = new \moodle_url('/local/treestudyplan/edit-plan.php', ["contextid" => $contextid]);
|
$url = new \moodle_url('/local/treestudyplan/edit-plan.php', ["contextid" => $contextid]);
|
||||||
header('Location: '.$url->out(false), true, 302);
|
header('Location: '.$url->out(false), true, 302);
|
||||||
exit;
|
exit;
|
||||||
|
@ -60,7 +80,7 @@ if($studyplancontext->id > 1){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Load javascripts and specific css
|
// Load javascripts and specific css.
|
||||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue/bootstrap-vue.css'));
|
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue/bootstrap-vue.css'));
|
||||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css'));
|
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css'));
|
||||||
$PAGE->requires->js_call_amd('local_treestudyplan/page-edit-plan', 'init', [$studyplancontext->id, $categoryid]);
|
$PAGE->requires->js_call_amd('local_treestudyplan/page-edit-plan', 'init', [$studyplancontext->id, $categoryid]);
|
||||||
|
@ -69,7 +89,7 @@ $PAGE->requires->js_call_amd('local_treestudyplan/page-edit-plan', 'init', [$stu
|
||||||
$catlist = courseservice::list_accessible_categories_with_usage("edit");
|
$catlist = courseservice::list_accessible_categories_with_usage("edit");
|
||||||
|
|
||||||
|
|
||||||
//Local translate function
|
//Local translate function.
|
||||||
function t($str, $param=null, $plugin='local_treestudyplan') {
|
function t($str, $param=null, $plugin='local_treestudyplan') {
|
||||||
print get_string($str, $plugin, $param);
|
print get_string($str, $plugin, $param);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,34 @@
|
||||||
<?php
|
<?php
|
||||||
if(isset($_SERVER['SCRIPT_FILENAME']))
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
{
|
//
|
||||||
// If SCRIPT_FILENAME is set, use that so the symlinked directories the developmen environment uses are handled correctly
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (isset($_SERVER['SCRIPT_FILENAME'])) {
|
||||||
|
// If SCRIPT_FILENAME is set, use that so the symlinked directories the developmen environment uses are handled correctly.
|
||||||
$root = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])));
|
$root = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])));
|
||||||
error_log("Using {$root}/config.php");
|
error_log("Using {$root}/config.php");
|
||||||
require_once($root."/config.php");
|
require_once($root."/config.php");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If not, assume the cwd is not symlinked and proceed as we are used to
|
// If not, assume the cwd is not symlinked and proceed as we are used to.
|
||||||
require_once("../../config.php");
|
require_once("../../config.php");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +39,7 @@ use local_treestudyplan;
|
||||||
|
|
||||||
$INVITED_URL = "/local/treestudyplan/invited.php";
|
$INVITED_URL = "/local/treestudyplan/invited.php";
|
||||||
|
|
||||||
//admin_externalpage_setup('major');
|
//admin_externalpage_setup('major');.
|
||||||
$systemcontext = context_system::instance();
|
$systemcontext = context_system::instance();
|
||||||
|
|
||||||
$PAGE->set_url("/local/treestudyplan/invitations.php", array());
|
$PAGE->set_url("/local/treestudyplan/invitations.php", array());
|
||||||
|
@ -30,14 +50,13 @@ $PAGE->set_context($systemcontext);
|
||||||
$PAGE->set_title(get_string('manage_invites', 'local_treestudyplan'));
|
$PAGE->set_title(get_string('manage_invites', 'local_treestudyplan'));
|
||||||
$PAGE->set_heading(get_string('manage_invites', 'local_treestudyplan'));
|
$PAGE->set_heading(get_string('manage_invites', 'local_treestudyplan'));
|
||||||
|
|
||||||
// Load javascripts
|
// Load javascripts.
|
||||||
$PAGE->requires->js_call_amd('local_treestudyplan/page-invitemanager', 'init');
|
$PAGE->requires->js_call_amd('local_treestudyplan/page-invitemanager', 'init');
|
||||||
$PAGE->requires->js_call_amd('local_treestudyplan/buttonlinks', 'init');
|
$PAGE->requires->js_call_amd('local_treestudyplan/buttonlinks', 'init');
|
||||||
|
|
||||||
// retrieve list of courses that the student is enrolled in
|
// retrieve list of courses that the student is enrolled in.
|
||||||
$sent = optional_param('sent', '', PARAM_INT);
|
$sent = optional_param('sent', '', PARAM_INT);
|
||||||
if(!empty($sent))
|
if (!empty($sent)) {
|
||||||
{
|
|
||||||
$invite = $DB->get_record('local_treestudyplan_invit', array('id' => $sent));
|
$invite = $DB->get_record('local_treestudyplan_invit', array('id' => $sent));
|
||||||
\core\notification::success(get_string('invite_resent_msg', 'local_treestudyplan', $invite));
|
\core\notification::success(get_string('invite_resent_msg', 'local_treestudyplan', $invite));
|
||||||
|
|
||||||
|
@ -59,8 +78,7 @@ print "<th> </th>";
|
||||||
print "</thead>";
|
print "</thead>";
|
||||||
|
|
||||||
print "<tbody>";
|
print "<tbody>";
|
||||||
if(count($invites) > 0)
|
if (count($invites) > 0) {
|
||||||
{
|
|
||||||
foreach ($invites as $invite)
|
foreach ($invites as $invite)
|
||||||
{
|
{
|
||||||
$testlink = $INVITED_URL."?key={$invite->invitekey}";
|
$testlink = $INVITED_URL."?key={$invite->invitekey}";
|
||||||
|
|
35
invited.php
35
invited.php
|
@ -1,8 +1,28 @@
|
||||||
<?php
|
<?php
|
||||||
// If not, assume the cwd is not symlinked and proceed as we are used to
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
require_once("../../config.php");
|
require_once("../../config.php");
|
||||||
|
|
||||||
//Local translate function
|
//Local translate function.
|
||||||
function t($str, $param=null, $plugin='local_treestudyplan') {
|
function t($str, $param=null, $plugin='local_treestudyplan') {
|
||||||
print get_string($str, $plugin, $param);
|
print get_string($str, $plugin, $param);
|
||||||
}
|
}
|
||||||
|
@ -11,14 +31,13 @@ $systemcontext = context_system::instance();
|
||||||
$PAGE->set_pagelayout('base');
|
$PAGE->set_pagelayout('base');
|
||||||
$PAGE->set_context($systemcontext);
|
$PAGE->set_context($systemcontext);
|
||||||
|
|
||||||
// See if we can get a valid user for this invited
|
// See if we can get a valid user for this invited.
|
||||||
$invitekey = optional_param('key', '', PARAM_ALPHANUM); // module name
|
$invitekey = optional_param('key', '', PARAM_ALPHANUM); // module name.
|
||||||
$PAGE->set_url("/local/treestudyplan/invited.php", array('key' => $invitekey));
|
$PAGE->set_url("/local/treestudyplan/invited.php", array('key' => $invitekey));
|
||||||
|
|
||||||
$invite = $DB->get_record_select("local_treestudyplan_invit", $DB->sql_compare_text("invitekey"). " = " . $DB->sql_compare_text(":invitekey"), ['invitekey' => $invitekey]);
|
$invite = $DB->get_record_select("local_treestudyplan_invit", $DB->sql_compare_text("invitekey"). " = " . $DB->sql_compare_text(":invitekey"), ['invitekey' => $invitekey]);
|
||||||
|
|
||||||
if(empty($invite))
|
if (empty($invite)) {
|
||||||
{
|
|
||||||
$PAGE->set_title(get_string('invalid_invitekey_title', 'local_treestudyplan'));
|
$PAGE->set_title(get_string('invalid_invitekey_title', 'local_treestudyplan'));
|
||||||
$PAGE->set_heading(get_string('invalid_invitekey_title', 'local_treestudyplan'));
|
$PAGE->set_heading(get_string('invalid_invitekey_title', 'local_treestudyplan'));
|
||||||
|
|
||||||
|
@ -26,7 +45,7 @@ if(empty($invite))
|
||||||
print $OUTPUT->header();
|
print $OUTPUT->header();
|
||||||
|
|
||||||
|
|
||||||
// render page for skill level 0 (global)
|
// render page for skill level 0 (global).
|
||||||
|
|
||||||
print "<div class='box errorbox alert alert-danger'>";
|
print "<div class='box errorbox alert alert-danger'>";
|
||||||
print get_string('invalid_invitekey_error', 'local_treestudyplan');
|
print get_string('invalid_invitekey_error', 'local_treestudyplan');
|
||||||
|
@ -38,7 +57,7 @@ if(empty($invite))
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Load javascripts and specific css
|
// Load javascripts and specific css.
|
||||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue/bootstrap-vue.css'));
|
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue/bootstrap-vue.css'));
|
||||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css'));
|
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css'));
|
||||||
$PAGE->requires->js_call_amd('local_treestudyplan/page-myreport', 'init', ['invited', $invitekey]);
|
$PAGE->requires->js_call_amd('local_treestudyplan/page-myreport', 'init', ['invited', $invitekey]);
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
$string['pluginname'] = 'Studyplans';
|
$string['pluginname'] = 'Studyplans';
|
||||||
|
|
||||||
$string['privacy:metadata'] = 'This plugin stores a link between users and their associated study plans. It also needs to store an email address and user provided handle, which may be a name, to send invitations to view the study plan to whomever the user chooses by email.';
|
$string['privacy:metadata'] = 'This plugin stores a link between users and their associated study plans. It also needs to store an email address and user provided handle, which may be a name, to send invitations to view the study plan to whomever the user chooses by email.';
|
||||||
|
|
|
@ -1,4 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
$string['pluginname'] = 'Studieplannen';
|
$string['pluginname'] = 'Studieplannen';
|
||||||
|
|
||||||
|
|
83
lib.php
83
lib.php
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
require_once($CFG->dirroot.'/course/modlib.php');
|
require_once($CFG->dirroot.'/course/modlib.php');
|
||||||
|
|
||||||
use local_treestudyplan\local\helpers\webservicehelper;
|
use local_treestudyplan\local\helpers\webservicehelper;
|
||||||
|
@ -15,30 +36,30 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) {
|
||||||
|
|
||||||
$systemcontext = context_system::instance();
|
$systemcontext = context_system::instance();
|
||||||
|
|
||||||
// Moodle 4.0-4.2 do not yet support customizing the primary navigation bar (it is a planned feature though)
|
// Moodle 4.0-4.2 do not yet support customizing the primary navigation bar (it is a planned feature though).
|
||||||
// For now, go to theme settings and add the following into "Custom menu items"
|
// For now, go to theme settings and add the following into "Custom menu items".
|
||||||
// [your name for my studyplan]|/local/treestudyplan/myreport.php
|
// [your name for my studyplan]|/local/treestudyplan/myreport.php.
|
||||||
// [your name for studyplan viewing]|/local/treestudyplan/view-plan.php
|
// [your name for studyplan viewing]|/local/treestudyplan/view-plan.php.
|
||||||
// [your name for studyplan managing]|/local/treestudyplan/edit-plan.php
|
// [your name for studyplan managing]|/local/treestudyplan/edit-plan.php.
|
||||||
// For example:
|
// For example:.
|
||||||
// Mijn studieplan|/local/treestudyplan/myreport.php
|
// Mijn studieplan|/local/treestudyplan/myreport.php.
|
||||||
// Studieplannen|/local/treestudyplan/view-plan.php
|
// Studieplannen|/local/treestudyplan/view-plan.php.
|
||||||
// Studieplannen beheren|/local/treestudyplan/edit-plan.php
|
// Studieplannen beheren|/local/treestudyplan/edit-plan.php.
|
||||||
|
|
||||||
// Using some javascript magic we'll hide the links that are not accessible
|
// Using some javascript magic we'll hide the links that are not accessible.
|
||||||
// (Since the Output API does not easily support inline style tags, adding one through Javascript is easier,
|
// (Since the Output API does not easily support inline style tags, adding one through Javascript is easier,.
|
||||||
// and not much more complex than loading a separate stylesheet for each link we want to hide)
|
// and not much more complex than loading a separate stylesheet for each link we want to hide).
|
||||||
// we will add all the hrefs that should be hidden to this variable below
|
// we will add all the hrefs that should be hidden to this variable below.
|
||||||
$hide_primary_hrefs = [];
|
$hide_primary_hrefs = [];
|
||||||
|
|
||||||
if($USER->id > 1) // Don't show if user is not logged in (id == 0) or is guest user (id == 1)
|
if ($USER->id > 1) // Don't show if user is not logged in (id == 0) or is guest user (id == 1).
|
||||||
{
|
{
|
||||||
|
|
||||||
$userstudyplans = studyplan::find_for_user($USER->id);
|
$userstudyplans = studyplan::find_for_user($USER->id);
|
||||||
if (!empty($userstudyplans))
|
if (!empty($userstudyplans))
|
||||||
{
|
{
|
||||||
|
|
||||||
// create studyplan node
|
// create studyplan node.
|
||||||
$node = navigation_node::create(
|
$node = navigation_node::create(
|
||||||
get_string("link_myreport", "local_treestudyplan"),
|
get_string("link_myreport", "local_treestudyplan"),
|
||||||
new moodle_url($CFG->wwwroot . "/local/treestudyplan/myreport.php", array()),
|
new moodle_url($CFG->wwwroot . "/local/treestudyplan/myreport.php", array()),
|
||||||
|
@ -50,7 +71,7 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) {
|
||||||
$node->showinflatnavigation = true;
|
$node->showinflatnavigation = true;
|
||||||
$node->showinsecondarynavigation=true;
|
$node->showinsecondarynavigation=true;
|
||||||
|
|
||||||
// create invitenode node
|
// create invitenode node.
|
||||||
$invitenode = navigation_node::create(
|
$invitenode = navigation_node::create(
|
||||||
get_string("manage_invites", "local_treestudyplan"),
|
get_string("manage_invites", "local_treestudyplan"),
|
||||||
new moodle_url($CFG->wwwroot . "/local/treestudyplan/invitations.php", array()),
|
new moodle_url($CFG->wwwroot . "/local/treestudyplan/invitations.php", array()),
|
||||||
|
@ -111,7 +132,7 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) {
|
||||||
$hide_primary_hrefs[] = "/local/treestudyplan/edit-plan.php";
|
$hide_primary_hrefs[] = "/local/treestudyplan/edit-plan.php";
|
||||||
$hide_primary_hrefs[] = "/local/treestudyplan/view-plan.php";
|
$hide_primary_hrefs[] = "/local/treestudyplan/view-plan.php";
|
||||||
}
|
}
|
||||||
// create invitenode node
|
// create invitenode node.
|
||||||
$invitenode = navigation_node::create(
|
$invitenode = navigation_node::create(
|
||||||
get_string("nav_invited", "local_treestudyplan"),
|
get_string("nav_invited", "local_treestudyplan"),
|
||||||
new moodle_url($CFG->wwwroot . "/local/treestudyplan/invited.php", array()),
|
new moodle_url($CFG->wwwroot . "/local/treestudyplan/invited.php", array()),
|
||||||
|
@ -124,7 +145,7 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) {
|
||||||
$navigation->add_node($invitenode, 'mycourses');
|
$navigation->add_node($invitenode, 'mycourses');
|
||||||
|
|
||||||
|
|
||||||
// Now using some javascript magic, we'll hide the links that are not accessible
|
// Now using some javascript magic, we'll hide the links that are not accessible.
|
||||||
$PAGE->requires->js_call_amd('local_treestudyplan/primary-nav-tools', 'hide_primary', [$hide_primary_hrefs]);
|
$PAGE->requires->js_call_amd('local_treestudyplan/primary-nav-tools', 'hide_primary', [$hide_primary_hrefs]);
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,7 +164,7 @@ function local_treestudyplan_extend_navigation_category_settings($navigation, co
|
||||||
"local_treestudyplan_editplan",
|
"local_treestudyplan_editplan",
|
||||||
new pix_icon("editplans", '', 'local_treestudyplan')
|
new pix_icon("editplans", '', 'local_treestudyplan')
|
||||||
);
|
);
|
||||||
//$node->make_active();
|
//$node->make_active();.
|
||||||
}
|
}
|
||||||
if (has_capability('local/treestudyplan:viewuserreports', $coursecategorycontext)) {
|
if (has_capability('local/treestudyplan:viewuserreports', $coursecategorycontext)) {
|
||||||
$node = $navigation->add(
|
$node = $navigation->add(
|
||||||
|
@ -154,7 +175,7 @@ function local_treestudyplan_extend_navigation_category_settings($navigation, co
|
||||||
"local_treestudyplan_viewplan",
|
"local_treestudyplan_viewplan",
|
||||||
new pix_icon("viewplans", '', 'local_treestudyplan')
|
new pix_icon("viewplans", '', 'local_treestudyplan')
|
||||||
);
|
);
|
||||||
//$node->make_active();
|
//$node->make_active();.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -184,8 +205,7 @@ function local_treestudyplan_reset_fontawesome_icon_map() {
|
||||||
$instance->get_icon_name_map();
|
$instance->get_icon_name_map();
|
||||||
}
|
}
|
||||||
|
|
||||||
function local_treestudyplan_send_invite($inviteid)
|
function local_treestudyplan_send_invite($inviteid) {
|
||||||
{
|
|
||||||
global $DB, $USER, $CFG;
|
global $DB, $USER, $CFG;
|
||||||
$invite = $DB->get_record("local_treestudyplan_invit", array('id' => $inviteid));
|
$invite = $DB->get_record("local_treestudyplan_invit", array('id' => $inviteid));
|
||||||
|
|
||||||
|
@ -226,8 +246,8 @@ function local_treestudyplan_send_invite($inviteid)
|
||||||
$subject = get_string('invite_mail_subject', 'local_treestudyplan', $data);
|
$subject = get_string('invite_mail_subject', 'local_treestudyplan', $data);
|
||||||
|
|
||||||
$html = "
|
$html = "
|
||||||
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
|
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>.
|
||||||
<html xmlns='http://www.w3.org/1999/xhtml'>
|
<html xmlns='http://www.w3.org/1999/xhtml'>.
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
|
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
|
||||||
<title>{$subject}</title>
|
<title>{$subject}</title>
|
||||||
|
@ -247,8 +267,7 @@ function local_treestudyplan_send_invite($inviteid)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function local_treestudyplan_find_cohortmembers($cohortid)
|
function local_treestudyplan_find_cohortmembers($cohortid) {
|
||||||
{
|
|
||||||
global $DB;
|
global $DB;
|
||||||
// By default wherecondition retrieves all users except the deleted, not confirmed and guest.
|
// By default wherecondition retrieves all users except the deleted, not confirmed and guest.
|
||||||
$params = ['cohortid' => $cohortid];
|
$params = ['cohortid' => $cohortid];
|
||||||
|
@ -261,16 +280,14 @@ function local_treestudyplan_find_cohortmembers($cohortid)
|
||||||
return $availableusers;
|
return $availableusers;
|
||||||
}
|
}
|
||||||
|
|
||||||
function local_treestudyplan_get_cohort_path($cohort)
|
function local_treestudyplan_get_cohort_path($cohort) {
|
||||||
{
|
|
||||||
$cohortcontext = context::instance_by_id($cohort->contextid);
|
$cohortcontext = context::instance_by_id($cohort->contextid);
|
||||||
if($cohortcontext && $cohortcontext->id != SYSCONTEXTID)
|
if ($cohortcontext && $cohortcontext->id != SYSCONTEXTID) {
|
||||||
{
|
|
||||||
$ctxpath = array_map(
|
$ctxpath = array_map(
|
||||||
function($ctx) { return $ctx->get_context_name(false);},
|
function($ctx) { return $ctx->get_context_name(false);},
|
||||||
$cohortcontext->get_parent_contexts(true)
|
$cohortcontext->get_parent_contexts(true)
|
||||||
);
|
);
|
||||||
array_pop($ctxpath); // pop system context off the list
|
array_pop($ctxpath); // pop system context off the list.
|
||||||
$ctxpath = array_reverse($ctxpath);
|
$ctxpath = array_reverse($ctxpath);
|
||||||
$ctxpath[] = $cohort->name;
|
$ctxpath[] = $cohort->name;
|
||||||
|
|
||||||
|
@ -299,8 +316,8 @@ function local_treestudyplan_output_fragment_mod_edit_form($args){
|
||||||
// Check the course exists.
|
// Check the course exists.
|
||||||
$course = \get_course($cm->course);
|
$course = \get_course($cm->course);
|
||||||
|
|
||||||
// require_login
|
// require_login.
|
||||||
require_login($course, false, $cm); // needed to setup proper $COURSE
|
require_login($course, false, $cm); // needed to setup proper $COURSE.
|
||||||
|
|
||||||
list($cm, $context, $module, $data, $cw) = \get_moduleinfo_data($cm, $course);
|
list($cm, $context, $module, $data, $cw) = \get_moduleinfo_data($cm, $course);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
require_once("../../config.php");
|
require_once("../../config.php");
|
||||||
|
|
||||||
require_once($CFG->libdir.'/weblib.php');
|
require_once($CFG->libdir.'/weblib.php');
|
||||||
|
@ -15,12 +36,12 @@ $PAGE->set_context($systemcontext);
|
||||||
$PAGE->set_title(get_string('report_invited', 'local_treestudyplan', "{$USER->firstname} {$USER->lastname}"));
|
$PAGE->set_title(get_string('report_invited', 'local_treestudyplan', "{$USER->firstname} {$USER->lastname}"));
|
||||||
$PAGE->set_heading(get_string('report_invited', 'local_treestudyplan', "{$USER->firstname} {$USER->lastname}"));
|
$PAGE->set_heading(get_string('report_invited', 'local_treestudyplan', "{$USER->firstname} {$USER->lastname}"));
|
||||||
|
|
||||||
// Load javascripts and specific css
|
// Load javascripts and specific css.
|
||||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue/bootstrap-vue.css'));
|
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue/bootstrap-vue.css'));
|
||||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css'));
|
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css'));
|
||||||
$PAGE->requires->js_call_amd('local_treestudyplan/page-myreport', 'init');
|
$PAGE->requires->js_call_amd('local_treestudyplan/page-myreport', 'init');
|
||||||
|
|
||||||
//Local translate function
|
//Local translate function.
|
||||||
function t($str, $param=null, $plugin='local_treestudyplan') {
|
function t($str, $param=null, $plugin='local_treestudyplan') {
|
||||||
print get_string($str, $plugin, $param);
|
print get_string($str, $plugin, $param);
|
||||||
}
|
}
|
||||||
|
|
25
myreport.php
25
myreport.php
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
require_once("../../config.php");
|
require_once("../../config.php");
|
||||||
|
|
||||||
require_once($CFG->libdir.'/weblib.php');
|
require_once($CFG->libdir.'/weblib.php');
|
||||||
|
@ -23,12 +44,12 @@ if($teachermode){
|
||||||
$PAGE->set_heading(get_string('report_invited', 'local_treestudyplan', "{$USER->firstname} {$USER->lastname}"));
|
$PAGE->set_heading(get_string('report_invited', 'local_treestudyplan', "{$USER->firstname} {$USER->lastname}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load javascripts and specific css
|
// Load javascripts and specific css.
|
||||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue/bootstrap-vue.css'));
|
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue/bootstrap-vue.css'));
|
||||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css'));
|
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css'));
|
||||||
$PAGE->requires->js_call_amd('local_treestudyplan/page-myreport', 'init', [$teachermode?'teaching':'myreport']);
|
$PAGE->requires->js_call_amd('local_treestudyplan/page-myreport', 'init', [$teachermode?'teaching':'myreport']);
|
||||||
|
|
||||||
//Local translate function
|
//Local translate function.
|
||||||
function t($str, $param=null, $plugin='local_treestudyplan') {
|
function t($str, $param=null, $plugin='local_treestudyplan') {
|
||||||
print get_string($str, $plugin, $param);
|
print get_string($str, $plugin, $param);
|
||||||
}
|
}
|
||||||
|
|
168
reports.php
168
reports.php
|
@ -1,168 +0,0 @@
|
||||||
<?php
|
|
||||||
// If not, assume the cwd is not symlinked and proceed as we are used to
|
|
||||||
require_once("../../config.php");
|
|
||||||
|
|
||||||
require_once($CFG->libdir.'/weblib.php');
|
|
||||||
require_once($CFG->dirroot.'/grade/querylib.php');
|
|
||||||
require_once($CFG->dirroot.'/cohort/lib.php');
|
|
||||||
require_once($CFG->dirroot.'/cohort/locallib.php');
|
|
||||||
require_once("lib.php");
|
|
||||||
|
|
||||||
use local_treestudyplan;
|
|
||||||
|
|
||||||
//admin_externalpage_setup('major');
|
|
||||||
$systemcontext = context_system::instance();
|
|
||||||
|
|
||||||
|
|
||||||
require_login();
|
|
||||||
require_capability('local/treestudyplan:viewothercards',$systemcontext);
|
|
||||||
|
|
||||||
$PAGE->set_pagelayout('base');
|
|
||||||
$PAGE->set_context($systemcontext);
|
|
||||||
$PAGE->set_title(get_string('report_index','local_treestudyplan'));
|
|
||||||
$PAGE->set_heading(get_string('report_index','local_treestudyplan'));
|
|
||||||
|
|
||||||
// Load javascripts
|
|
||||||
//$PAGE->requires->js_call_amd('local_treestudyplan/fixlinks', 'init', ['div.tab-content']);
|
|
||||||
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
|
|
||||||
$PAGE->requires->js_call_amd('local_treestudyplan/report', 'init');
|
|
||||||
//$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/eqstyles.css'));
|
|
||||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-toggle.min.css'));
|
|
||||||
|
|
||||||
|
|
||||||
$userid = null;
|
|
||||||
$studentid = optional_param('studentid', '', PARAM_INT);
|
|
||||||
$cohortid = optional_param('cohortid', '', PARAM_INT);
|
|
||||||
if(!empty($studentid)){
|
|
||||||
$PAGE->set_url("/local/treestudyplan/reports.php",array('studentid' => $studentid));
|
|
||||||
$student = $DB->get_record("user",['id' => $studentid]);
|
|
||||||
|
|
||||||
$userlist = [];
|
|
||||||
$nextstudent = null;
|
|
||||||
$prevstudent = null;
|
|
||||||
if(!empty($cohortid))
|
|
||||||
{
|
|
||||||
$cohort = $DB->get_record("cohort",['id' => $cohortid]);
|
|
||||||
$userlist = array_values(local_treestudyplan_find_cohortmembers($cohortid));
|
|
||||||
for($i = 0; $i < count($userlist); $i++)
|
|
||||||
{
|
|
||||||
if($userlist[$i]->userid == $studentid)
|
|
||||||
{
|
|
||||||
if($i > 0)
|
|
||||||
{
|
|
||||||
$prevstudent = (object)['id' => $userlist[$i - 1]->userid, 'name' => "{$userlist[$i - 1]->firstname} {$userlist[$i - 1]->lastname}"];
|
|
||||||
}
|
|
||||||
if($i < count($userlist) - 1)
|
|
||||||
{
|
|
||||||
$nextstudent = (object)['id' => $userlist[$i + 1]->userid, 'name' => "{$userlist[$i + 1]->firstname} {$userlist[$i + 1]->lastname}"];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$cohortpath = local_treestudyplan_get_cohort_path($cohort);
|
|
||||||
$PAGE->set_title(get_string('report_invited','local_treestudyplan',"{$cohortpath}: {$student->firstname} {$student->lastname}"));
|
|
||||||
$PAGE->set_heading(get_string('report_invited','local_treestudyplan',"{$cohortpath}: {$student->firstname} {$student->lastname}"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$PAGE->set_title(get_string('report_invited','local_treestudyplan',"$cohort->{$student->firstname} {$student->lastname}"));
|
|
||||||
$PAGE->set_heading(get_string('report_invited','local_treestudyplan',"{$student->firstname} {$student->lastname}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
$gradewriter = new local_treestudyplan_cardwriter($studentid,true);
|
|
||||||
$badgewriter = new local_treestudyplan_badgewriter($studentid);
|
|
||||||
$calendarwriter = new local_treestudyplan_calendarwriter($studentid);
|
|
||||||
|
|
||||||
print $OUTPUT->header();
|
|
||||||
|
|
||||||
print "<div class='m-buttonbar' style='margin-bottom: 1.5em; height: 1em;'>";
|
|
||||||
if(isset($prevstudent))
|
|
||||||
{
|
|
||||||
print "<a style='float:left;' href='/local/treestudyplan/reports.php?studentid={$prevstudent->id}&cohortid={$cohortid}'><i class='fa fa-arrow-left'></i> {$prevstudent->name} </a>";
|
|
||||||
}
|
|
||||||
if(isset($nextstudent))
|
|
||||||
{
|
|
||||||
print "<a style='float:right;' href='/local/treestudyplan/reports.php?studentid={$nextstudent->id}&cohortid={$cohortid}'>{$nextstudent->name} <i class='fa fa-arrow-right'></i></a>";
|
|
||||||
}
|
|
||||||
print "</div>";
|
|
||||||
print "<ul class='nav nav-tabs' role='tablist'>";
|
|
||||||
print "<li class='nav-item'><a class='nav-link active' href='#link-report' data-toggle='tab' role='tab'>".get_string('nav_report','local_treestudyplan')."</a></li>";
|
|
||||||
print "<li class='nav-item'><a class='nav-link ' href='#link-badges' data-toggle='tab' role='tab'>".get_string('nav_badges','local_treestudyplan')."</a></li>";
|
|
||||||
print "<li class='nav-item'><a class='nav-link ' href='#link-calendar' data-toggle='tab' role='tab'>".get_string('nav_calendar','local_treestudyplan')."</a></li>";
|
|
||||||
print "</ul>";
|
|
||||||
|
|
||||||
print "<div class='tab-content mt-3'>";
|
|
||||||
|
|
||||||
print "<div class='tab-pane active' id='link-report' data-toggle='tab' role='tab'>";
|
|
||||||
print $gradewriter->render(true,false);
|
|
||||||
print "</div>";
|
|
||||||
|
|
||||||
print "<div class='tab-pane ' id='link-badges' data-toggle='tab' role='tab'>";
|
|
||||||
print $badgewriter->render();
|
|
||||||
print "</div>";
|
|
||||||
|
|
||||||
print "<div class='tab-pane' id='link-calendar' data-toggle='tab' role='tab'>";
|
|
||||||
print $calendarwriter->render();
|
|
||||||
print "</div>";
|
|
||||||
|
|
||||||
print "</div>";
|
|
||||||
|
|
||||||
|
|
||||||
print $OUTPUT->footer();
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$PAGE->set_url("/local/treestudyplan/reports.php",array());
|
|
||||||
// show student picker
|
|
||||||
$cohortlist = $DB->get_records("cohort");
|
|
||||||
$cohorts = [];
|
|
||||||
foreach($cohortlist as $c)
|
|
||||||
{
|
|
||||||
if($c->visible)
|
|
||||||
{
|
|
||||||
$cohortcontext = context::instance_by_id($c->contextid);
|
|
||||||
if($cohortcontext) // TODO: add check if user has rights in this context
|
|
||||||
{
|
|
||||||
$users = local_treestudyplan_find_cohortmembers($c->id);
|
|
||||||
|
|
||||||
$cohorts[$c->id] = (object)[
|
|
||||||
'id' => $c->id,
|
|
||||||
'cohort' => $c,
|
|
||||||
'name' => $c->name,
|
|
||||||
'path' => local_treestudyplan_get_cohort_path($c),
|
|
||||||
'users' => $users,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
print $OUTPUT->header();
|
|
||||||
usort($cohorts,function($a,$b){
|
|
||||||
return $a->path <=> $b->path;
|
|
||||||
});
|
|
||||||
|
|
||||||
$regex = get_config('local_treestudyplan', 'cohortidregex');
|
|
||||||
foreach($cohorts as $c)
|
|
||||||
{
|
|
||||||
$m = [];
|
|
||||||
if(preg_match("/".$regex."/",$c->cohort->idnumber,$m) && $c->cohort->visible)
|
|
||||||
{
|
|
||||||
print "<legend class='collapse-header'><a data-toggle='collapse' class='collapsed' href='#cohort-{$c->id}' role='button'>{$c->path}</a></legend>";
|
|
||||||
print "<div id='cohort-{$c->id}' class='collapse'>";
|
|
||||||
print "<div class='card card-body'><ul class='gradecardlist'>";
|
|
||||||
foreach($c->users as $u)
|
|
||||||
{
|
|
||||||
print "<li class='gradestudent'>";
|
|
||||||
print "<a href='/local/treestudyplan/reports.php?studentid={$u->userid}&cohortid={$c->id}'>{$u->firstname} {$u->lastname}</a>";
|
|
||||||
print "</li>";
|
|
||||||
}
|
|
||||||
|
|
||||||
print "</ul>";
|
|
||||||
print "</div></div>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print "</div>";
|
|
||||||
|
|
||||||
print $OUTPUT->footer();
|
|
||||||
}
|
|
38
settings.php
38
settings.php
|
@ -1,17 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
// This file is part of Moodle - http://moodle.org/
|
// This file is part of Moodle - http://moodle.org/.
|
||||||
//
|
//
|
||||||
// Moodle is free software: you can redistribute it and/or modify
|
// Moodle is free software: you can redistribute it and/or modify.
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by.
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
// the Free Software Foundation, either version 3 of the License, or.
|
||||||
// (at your option) any later version.
|
// (at your option) any later version.
|
||||||
//
|
//
|
||||||
// Moodle is distributed in the hope that it will be useful,
|
// Moodle is distributed in the hope that it will be useful,.
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of.
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the.
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License.
|
||||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
*
|
*
|
||||||
* @package local_chronotable
|
* @package local_chronotable
|
||||||
* @copyright 2017 Alexander Bias, Ulm University <alexander.bias@uni-ulm.de>
|
* @copyright 2017 Alexander Bias, Ulm University <alexander.bias@uni-ulm.de>
|
||||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
defined('MOODLE_INTERNAL') || die();
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
@ -43,7 +43,7 @@ if ($hassiteconfig) {
|
||||||
get_string('settingspage', 'local_treestudyplan', null, true));
|
get_string('settingspage', 'local_treestudyplan', null, true));
|
||||||
|
|
||||||
|
|
||||||
// GOAL AGGREGATION SETTINGS
|
// GOAL AGGREGATION SETTINGS.
|
||||||
$page->add(new admin_setting_heading('local_treestudyplan/aggregation_heading',
|
$page->add(new admin_setting_heading('local_treestudyplan/aggregation_heading',
|
||||||
get_string('setting_aggregation_heading', 'local_treestudyplan'),
|
get_string('setting_aggregation_heading', 'local_treestudyplan'),
|
||||||
get_string('settingdesc_aggregation_heading', 'local_treestudyplan')
|
get_string('settingdesc_aggregation_heading', 'local_treestudyplan')
|
||||||
|
@ -61,7 +61,7 @@ if ($hassiteconfig) {
|
||||||
$aggregators
|
$aggregators
|
||||||
));
|
));
|
||||||
|
|
||||||
// DISPLAY COURSE INFO SETTINGS
|
// DISPLAY COURSE INFO SETTINGS.
|
||||||
$page->add(new admin_setting_heading('local_treestudyplan/display_heading',
|
$page->add(new admin_setting_heading('local_treestudyplan/display_heading',
|
||||||
get_string('setting_display_heading', 'local_treestudyplan'),
|
get_string('setting_display_heading', 'local_treestudyplan'),
|
||||||
get_string('settingdesc_display_heading', 'local_treestudyplan')
|
get_string('settingdesc_display_heading', 'local_treestudyplan')
|
||||||
|
@ -86,7 +86,7 @@ if ($hassiteconfig) {
|
||||||
$displayfields
|
$displayfields
|
||||||
));
|
));
|
||||||
|
|
||||||
// BISTATE AGGREGATON DEFAULTS
|
// BISTATE AGGREGATON DEFAULTS.
|
||||||
$page->add(new admin_setting_heading('local_treestudyplan/bistate_aggregation_heading',
|
$page->add(new admin_setting_heading('local_treestudyplan/bistate_aggregation_heading',
|
||||||
get_string('setting_bistate_heading', 'local_treestudyplan'),
|
get_string('setting_bistate_heading', 'local_treestudyplan'),
|
||||||
get_string('settingdesc_bistate_heading', 'local_treestudyplan')
|
get_string('settingdesc_bistate_heading', 'local_treestudyplan')
|
||||||
|
@ -150,48 +150,48 @@ if ($hassiteconfig) {
|
||||||
get_string('settingspage_csync', 'local_treestudyplan', null, true));
|
get_string('settingspage_csync', 'local_treestudyplan', null, true));
|
||||||
|
|
||||||
|
|
||||||
// Description heading
|
// Description heading.
|
||||||
$page_csync->add(new admin_setting_heading('local_treestudyplan/csync_heading',
|
$page_csync->add(new admin_setting_heading('local_treestudyplan/csync_heading',
|
||||||
get_string('setting_csync_heading', 'local_treestudyplan'),
|
get_string('setting_csync_heading', 'local_treestudyplan'),
|
||||||
get_string('settingdesc_csync_heading', 'local_treestudyplan')
|
get_string('settingdesc_csync_heading', 'local_treestudyplan')
|
||||||
));
|
));
|
||||||
|
|
||||||
// Enable/disable cohort sync
|
// Enable/disable cohort sync.
|
||||||
$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_enable',
|
$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_enable',
|
||||||
get_string('setting_csync_enable_field', 'local_treestudyplan'),
|
get_string('setting_csync_enable_field', 'local_treestudyplan'),
|
||||||
get_string('settingdesc_csync_enable_field', 'local_treestudyplan'),
|
get_string('settingdesc_csync_enable_field', 'local_treestudyplan'),
|
||||||
false
|
false
|
||||||
));
|
));
|
||||||
|
|
||||||
// Enable/disable autoremove
|
// Enable/disable autoremove.
|
||||||
$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_autoremove',
|
$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_autoremove',
|
||||||
get_string('setting_csync_autoremove_field', 'local_treestudyplan'),
|
get_string('setting_csync_autoremove_field', 'local_treestudyplan'),
|
||||||
get_string('settingdesc_csync_autoremove_field', 'local_treestudyplan'),
|
get_string('settingdesc_csync_autoremove_field', 'local_treestudyplan'),
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
|
|
||||||
// Enable/disable remembering previously added cohort syncs so they're not automatically deleted
|
// Enable/disable remembering previously added cohort syncs so they're not automatically deleted.
|
||||||
$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_remember_manual_csync',
|
$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_remember_manual_csync',
|
||||||
get_string('setting_csync_remember_manual_csync_field', 'local_treestudyplan'),
|
get_string('setting_csync_remember_manual_csync_field', 'local_treestudyplan'),
|
||||||
get_string('settingdesc_csync_remember_manual_csync_field', 'local_treestudyplan'),
|
get_string('settingdesc_csync_remember_manual_csync_field', 'local_treestudyplan'),
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
|
|
||||||
// Enable/disable group creation
|
// Enable/disable group creation.
|
||||||
$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_creategroup',
|
$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_creategroup',
|
||||||
get_string('setting_csync_creategroup_field', 'local_treestudyplan'),
|
get_string('setting_csync_creategroup_field', 'local_treestudyplan'),
|
||||||
get_string('settingdesc_csync_creategroup_field', 'local_treestudyplan'),
|
get_string('settingdesc_csync_creategroup_field', 'local_treestudyplan'),
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
|
|
||||||
// Sync users too yes/no?
|
// Sync users too yes/no?.
|
||||||
$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_users',
|
$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_users',
|
||||||
get_string('setting_csync_users_field', 'local_treestudyplan'),
|
get_string('setting_csync_users_field', 'local_treestudyplan'),
|
||||||
get_string('settingdesc_csync_users_field', 'local_treestudyplan'),
|
get_string('settingdesc_csync_users_field', 'local_treestudyplan'),
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
|
|
||||||
// Select csync enrol role
|
// Select csync enrol role.
|
||||||
if (!during_initial_install()) {
|
if (!during_initial_install()) {
|
||||||
$options = get_default_enrol_roles(context_system::instance());
|
$options = get_default_enrol_roles(context_system::instance());
|
||||||
$student = get_archetype_roles('student');
|
$student = get_archetype_roles('student');
|
||||||
|
|
|
@ -1,182 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace local_treestudyplan;
|
|
||||||
use \local_treestudyplan\local\aggregators\bistate_aggregator;
|
|
||||||
|
|
||||||
class bistate_aggregator_test extends \basic_testcase {
|
|
||||||
|
|
||||||
private function goalaggregation_test($configstr, $outcome, $completions,$required){
|
|
||||||
$ag = new bistate_aggregator($configstr);
|
|
||||||
// test aggregation with the required data
|
|
||||||
$result = $ag->aggregate_binary_goals($completions,$required);
|
|
||||||
// assert if the test is succesful
|
|
||||||
$this->assertEquals(completion::label($outcome),completion::label($result));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private function junctionaggregation_test($configstr, $outcome, $completions){
|
|
||||||
$ag = new bistate_aggregator($configstr);
|
|
||||||
// test aggregation with the minimum required data
|
|
||||||
$result = $ag->aggregate_junction($completions);
|
|
||||||
// assert if the test is succesful
|
|
||||||
$this->assertEquals(completion::label($outcome),completion::label($result));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function test_goalaggregation_0() {
|
|
||||||
$this->goalaggregation_test(
|
|
||||||
'{"thresh_excellent":100,"thresh_good":85,"thresh_completed":66,"thresh_progress":25,"use_failed":true,"accept_pending_as_submitted":true}',
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
[
|
|
||||||
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function test_goalaggregation_1() {
|
|
||||||
$this->goalaggregation_test(
|
|
||||||
'{"thresh_excellent":100,"thresh_good":85,"thresh_completed":66,"thresh_progress":25,"use_failed":true,"accept_pending_as_submitted":true}',
|
|
||||||
completion::FAILED,
|
|
||||||
[ // completions
|
|
||||||
completion::FAILED,
|
|
||||||
completion::FAILED,
|
|
||||||
completion::FAILED,
|
|
||||||
completion::FAILED,
|
|
||||||
completion::FAILED,
|
|
||||||
],
|
|
||||||
[] // required
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function test_goalaggregation_2() {
|
|
||||||
$this->goalaggregation_test(
|
|
||||||
'{"thresh_excellent":100,"thresh_good":85,"thresh_completed":66,"thresh_progress":25,"use_failed":true,"accept_pending_as_submitted":true}',
|
|
||||||
completion::EXCELLENT,
|
|
||||||
[
|
|
||||||
completion::COMPLETED,
|
|
||||||
completion::COMPLETED,
|
|
||||||
completion::COMPLETED,
|
|
||||||
completion::COMPLETED,
|
|
||||||
completion::COMPLETED,
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function test_goalaggregation_3() {
|
|
||||||
$this->goalaggregation_test(
|
|
||||||
'{"thresh_excellent":100,"thresh_good":85,"thresh_completed":66,"thresh_progress":25,"use_failed":true,"accept_pending_as_submitted":true}',
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
[
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function test_goalaggregation_4() {
|
|
||||||
$this->goalaggregation_test(
|
|
||||||
'{"thresh_excellent":100,"thresh_good":85,"thresh_completed":66,"thresh_progress":25,"use_failed":true,"accept_pending_as_submitted":true}',
|
|
||||||
completion::PROGRESS,
|
|
||||||
[
|
|
||||||
completion::COMPLETED,
|
|
||||||
completion::COMPLETED,
|
|
||||||
completion::COMPLETED,
|
|
||||||
completion::PROGRESS,
|
|
||||||
completion::PROGRESS,
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function test_goalaggregation_5() {
|
|
||||||
$this->goalaggregation_test(
|
|
||||||
'{"thresh_excellent":100,"thresh_good":85,"thresh_completed":66,"thresh_progress":25,"use_failed":true,"accept_pending_as_submitted":true}',
|
|
||||||
completion::COMPLETED,
|
|
||||||
[
|
|
||||||
completion::COMPLETED,
|
|
||||||
completion::COMPLETED,
|
|
||||||
completion::COMPLETED,
|
|
||||||
completion::COMPLETED,
|
|
||||||
completion::PROGRESS,
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function test_goalaggregation_6() {
|
|
||||||
$this->goalaggregation_test(
|
|
||||||
'{"thresh_excellent":100,"thresh_good":85,"thresh_completed":66,"thresh_progress":25,"use_failed":true,"accept_pending_as_submitted":true}',
|
|
||||||
completion::PROGRESS,
|
|
||||||
[
|
|
||||||
completion::PROGRESS,
|
|
||||||
completion::PROGRESS,
|
|
||||||
completion::PROGRESS,
|
|
||||||
completion::PROGRESS,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function test_junctionaggregation_0() {
|
|
||||||
$this->junctionaggregation_test(
|
|
||||||
'{"thresh_excellent":100,"thresh_good":85,"thresh_completed":66,"thresh_progress":25,"use_failed":true,"accept_pending_as_submitted":true}',
|
|
||||||
completion::FAILED,
|
|
||||||
[
|
|
||||||
completion::FAILED,
|
|
||||||
completion::FAILED,
|
|
||||||
completion::FAILED,
|
|
||||||
completion::FAILED,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function test_junctionaggregation_1() {
|
|
||||||
$this->junctionaggregation_test(
|
|
||||||
'{"thresh_excellent":100,"thresh_good":85,"thresh_completed":66,"thresh_progress":25,"use_failed":true,"accept_pending_as_submitted":true}',
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
[
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function test_junctionaggregation_2() {
|
|
||||||
$this->junctionaggregation_test(
|
|
||||||
'{"thresh_excellent":100,"thresh_good":85,"thresh_completed":66,"thresh_progress":25,"use_failed":true,"accept_pending_as_submitted":true}',
|
|
||||||
completion::FAILED,
|
|
||||||
[
|
|
||||||
completion::FAILED,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function test_junctionaggregation_3() {
|
|
||||||
$this->junctionaggregation_test(
|
|
||||||
'{"thresh_excellent":100,"thresh_good":85,"thresh_completed":66,"thresh_progress":25,"use_failed":true,"accept_pending_as_submitted":true}',
|
|
||||||
completion::PROGRESS,
|
|
||||||
[
|
|
||||||
completion::PROGRESS,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
completion::INCOMPLETE,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
28
version.php
28
version.php
|
@ -1,7 +1,29 @@
|
||||||
<?php
|
<?php
|
||||||
$plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494)
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
$plugin->version = 2023082101; // YYYYMMDDHH (year, month, day, iteration)
|
//
|
||||||
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11)
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
|
$plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494).
|
||||||
|
$plugin->version = 2023082101; // YYYYMMDDHH (year, month, day, iteration).
|
||||||
|
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11).
|
||||||
|
|
||||||
$plugin->dependencies = [
|
$plugin->dependencies = [
|
||||||
'theme_boost' => 2019052000,
|
'theme_boost' => 2019052000,
|
||||||
|
|
|
@ -1,4 +1,25 @@
|
||||||
<?php
|
<?php
|
||||||
|
// This file is part of the Studyplan plugin for Moodle
|
||||||
|
//
|
||||||
|
// Moodle is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Moodle is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package local_treestudyplan
|
||||||
|
* @copyright 2023 P.M. Kuipers
|
||||||
|
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||||
|
*/
|
||||||
|
|
||||||
require_once("../../config.php");
|
require_once("../../config.php");
|
||||||
|
|
||||||
use \local_treestudyplan\courseservice;
|
use \local_treestudyplan\courseservice;
|
||||||
|
@ -10,15 +31,14 @@ $systemcontext = context_system::instance();
|
||||||
$PAGE->set_url("/local/treestudyplan/view-plan.php", array());
|
$PAGE->set_url("/local/treestudyplan/view-plan.php", array());
|
||||||
require_login();
|
require_login();
|
||||||
|
|
||||||
// Figure out the context (category or system, based on either category or context parameter)
|
// Figure out the context (category or system, based on either category or context parameter).
|
||||||
$categoryid = optional_param('categoryid', 0, PARAM_INT); // Category id
|
$categoryid = optional_param('categoryid', 0, PARAM_INT); // Category id.
|
||||||
$contextid = optional_param('contextid', 0, PARAM_INT); // Context id
|
$contextid = optional_param('contextid', 0, PARAM_INT); // Context id.
|
||||||
if ($categoryid > 0) {
|
if ($categoryid > 0) {
|
||||||
$studyplancontext = context_coursecat::instance($categoryid);
|
$studyplancontext = context_coursecat::instance($categoryid);
|
||||||
|
|
||||||
}
|
}
|
||||||
elseif($contextid > 0)
|
else if ($contextid > 0) {
|
||||||
{
|
|
||||||
$studyplancontext = context::instance_by_id($contextid);
|
$studyplancontext = context::instance_by_id($contextid);
|
||||||
if (in_array($studyplancontext->contextlevel, [CONTEXT_SYSTEM, CONTEXT_COURSECAT]))
|
if (in_array($studyplancontext->contextlevel, [CONTEXT_SYSTEM, CONTEXT_COURSECAT]))
|
||||||
{
|
{
|
||||||
|
@ -31,16 +51,16 @@ elseif($contextid > 0)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If no context is selected, find the first available one
|
// If no context is selected, find the first available one.
|
||||||
$available_contexts = courseservice::list_accessible_categories_with_usage("view");
|
$available_contexts = courseservice::list_accessible_categories_with_usage("view");
|
||||||
$contextid=1; // fallback to system context
|
$contextid=1; // fallback to system context.
|
||||||
foreach ($available_contexts as $ctx) {
|
foreach ($available_contexts as $ctx) {
|
||||||
if ($ctx->count > 0) {
|
if ($ctx->count > 0) {
|
||||||
$contextid = $ctx->ctxid;
|
$contextid = $ctx->ctxid;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// reload page with selected category
|
// reload page with selected category.
|
||||||
$url = new \moodle_url('/local/treestudyplan/view-plan.php', ["contextid" => $contextid]);
|
$url = new \moodle_url('/local/treestudyplan/view-plan.php', ["contextid" => $contextid]);
|
||||||
header('Location: '.$url->out(false), true, 302);
|
header('Location: '.$url->out(false), true, 302);
|
||||||
exit;
|
exit;
|
||||||
|
@ -59,12 +79,12 @@ if($studyplancontext->id > 1){
|
||||||
$PAGE->navbar->add(get_string('view_plan', 'local_treestudyplan'));
|
$PAGE->navbar->add(get_string('view_plan', 'local_treestudyplan'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load javascripts and specific css
|
// Load javascripts and specific css.
|
||||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue/bootstrap-vue.css'));
|
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue/bootstrap-vue.css'));
|
||||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css'));
|
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css'));
|
||||||
$PAGE->requires->js_call_amd('local_treestudyplan/page-view-plan', 'init', [$studyplancontext->id, $categoryid]);
|
$PAGE->requires->js_call_amd('local_treestudyplan/page-view-plan', 'init', [$studyplancontext->id, $categoryid]);
|
||||||
|
|
||||||
//Local translate function
|
//Local translate function.
|
||||||
function t($str, $param=null, $plugin='local_treestudyplan') {
|
function t($str, $param=null, $plugin='local_treestudyplan') {
|
||||||
print get_string($str, $plugin, $param);
|
print get_string($str, $plugin, $param);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user