PHPDoc documentation

This commit is contained in:
PMKuipers 2023-08-28 11:26:14 +02:00
parent 7de179e6e6
commit 6c7e489956
21 changed files with 553 additions and 219 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,3 @@
define("local_treestudyplan/studyplan-processor",["exports"],(function(_exports){function ProcessStudyplan(studyplan){var connections={};for(var ip in studyplan.pages){var page=studyplan.pages[ip];for(var il in page.studylines){var line=page.studylines[il];for(var is in line.slots){var slot=line.slots[is];if(void 0!==slot.competencies)for(var ic in slot.competencies){var itm=slot.competencies[ic];for(var idx in itm.connections.in){var conn=itm.connections.in[idx];conn.id in connections?itm.connections[idx]=connections[conn.id]:connections[conn.id]=conn}for(var _idx in itm.connections.out){var _conn=itm.connections.out[_idx];_conn.id in connections?itm.connections[_idx]=connections[_conn.id]:connections[_conn.id]=_conn}}if(void 0!==slot.filters)for(var ix in slot.filters){var _itm=slot.filters[ix];for(var _idx2 in _itm.connections.in){var _conn2=_itm.connections.in[_idx2];_conn2.id in connections?_itm.connections[_idx2]=connections[_conn2.id]:connections[_conn2.id]=_conn2}for(var _idx3 in _itm.connections.out){var _conn3=_itm.connections.out[_idx3];_conn3.id in connections?_itm.connections[_idx3]=connections[_conn3.id]:connections[_conn3.id]=_conn3}}}}}return studyplan}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.ProcessStudyplan=ProcessStudyplan,_exports.ProcessStudyplans=function(studyplans){for(var isx in studyplans){ProcessStudyplan(studyplans[isx])}return studyplans},_exports.objCopy=function(target,source,fields){for(var ix in fields){var field=fields[ix];target[field]=source[field]}},_exports.transportItem=function(target,source,identifier,param){param||(param="value");var item,itemindex;for(var ix in source)if(source[ix][param]==identifier){item=source[ix],itemindex=ix;break}item&&(target.push(item),source.splice(itemindex,1))}}));
define("local_treestudyplan/studyplan-processor",["exports"],(function(_exports){function ProcessStudyplan(studyplan){var connections={};for(var ip in studyplan.pages){var page=studyplan.pages[ip];for(var il in page.studylines){var line=page.studylines[il];for(var is in line.slots){var slot=line.slots[is];if(void 0!==slot.courses)for(var ic in slot.courses){var itm=slot.courses[ic];for(var idx in itm.connections.in){var conn=itm.connections.in[idx];conn.id in connections?itm.connections[idx]=connections[conn.id]:connections[conn.id]=conn}for(var _idx in itm.connections.out){var _conn=itm.connections.out[_idx];_conn.id in connections?itm.connections[_idx]=connections[_conn.id]:connections[_conn.id]=_conn}}if(void 0!==slot.filters)for(var ix in slot.filters){var _itm=slot.filters[ix];for(var _idx2 in _itm.connections.in){var _conn2=_itm.connections.in[_idx2];_conn2.id in connections?_itm.connections[_idx2]=connections[_conn2.id]:connections[_conn2.id]=_conn2}for(var _idx3 in _itm.connections.out){var _conn3=_itm.connections.out[_idx3];_conn3.id in connections?_itm.connections[_idx3]=connections[_conn3.id]:connections[_conn3.id]=_conn3}}}}}return studyplan}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.ProcessStudyplan=ProcessStudyplan,_exports.ProcessStudyplans=function(studyplans){for(var isx in studyplans){ProcessStudyplan(studyplans[isx])}return studyplans},_exports.objCopy=function(target,source,fields){for(var ix in fields){var field=fields[ix];target[field]=source[field]}},_exports.transportItem=function(target,source,identifier,param){param||(param="value");var item,itemindex;for(var ix in source)if(source[ix][param]==identifier){item=source[ix],itemindex=ix;break}item&&(target.push(item),source.splice(itemindex,1))}}));
//# sourceMappingURL=studyplan-processor.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -301,8 +301,8 @@ export default {
for(let i = 0; i <= this.page.periods; i++){
const slot = line.slots[i];
// Determine the amount of used layers in a studyline slit
for(const ix in line.slots[i].competencies){
const item = line.slots[i].competencies[ix];
for(const ix in line.slots[i].courses){
const item = line.slots[i].courses[ix];
if(item.layer > maxLayer){
maxLayer = item.layer;
}
@ -323,8 +323,8 @@ export default {
const periods = this.page.periods;
let show = true;
for(let i = 0; i < periods; i++){
if(line.slots[index-i] && line.slots[index-i].competencies){
const list = line.slots[index-i].competencies;
if(line.slots[index-i] && line.slots[index-i].courses){
const list = line.slots[index-i].courses;
for(const ix in list){ // Really wish that 'for of' would work with the minifier moodle uses
const item = list[ix];
if(item.layer == layeridx){
@ -387,7 +387,7 @@ export default {
><r-studyline-slot
v-if="index > 0 && showslot(line, index, layeridx, 'gradable')"
type='gradable'
v-model="line.slots[index].competencies"
v-model="line.slots[index].courses"
:key="'c-'+lineindex+'-'+index+'-'+layernr"
:slotindex="index"
:line="line"

View File

@ -1345,8 +1345,8 @@ export default {
if(line.slots[i]){
const slot = line.slots[i];
// Determine the amount of used layers in a studyline slit
for(const ix in line.slots[i].competencies){
const item = line.slots[i].competencies[ix];
for(const ix in line.slots[i].courses){
const item = line.slots[i].courses[ix];
if(item.layer > maxLayer){
maxLayer = item.layer;
}
@ -1371,8 +1371,8 @@ export default {
if(Array.isArray(slots)){
let count = 0;
for(let i = 0; i < slots.length; i++) {
if(Array.isArray(slots[i].competencies)){
count += slots[i].competencies.length;
if(Array.isArray(slots[i].courses)){
count += slots[i].courses.length;
}
if(Array.isArray(slots[i].filters)){
count += slots[i].filters.length;
@ -1507,8 +1507,8 @@ export default {
const periods = this.page.periods;
let show = true;
for(let i = 0; i < periods; i++){
if(line.slots[index-i] && line.slots[index-i].competencies){
const list = line.slots[index-i].competencies;
if(line.slots[index-i] && line.slots[index-i].courses){
const list = line.slots[index-i].courses;
for(const ix in list){ // Really wish that 'for of' would work with the minifier moodle uses
const item = list[ix];
if(item.layer == layeridx){
@ -1627,7 +1627,7 @@ export default {
<t-studyline-slot
v-if="index > 0 && showslot(line, index, layeridx, 'gradable')"
type='gradable'
v-model="line.slots[index].competencies"
v-model="line.slots[index].courses"
:key="'c-'+lineindex+'-'+index+'-'+layernr"
:slotindex="index"
:line="line"
@ -1822,8 +1822,8 @@ export default {
if(Array.isArray(slots)){
let count = 0;
for(let i = 0; i < slots.length; i++) {
if(Array.isArray(slots[i].competencies)){
count += slots[i].competencies.length;
if(Array.isArray(slots[i].courses)){
count += slots[i].courses.length;
}
if(Array.isArray(slots[i].filters)){
count += slots[i].filters.length;
@ -2119,8 +2119,8 @@ export default {
let freeIndex = this.slotindex;
// Determine last free slot following this one in the layer
for(let i = this.slotindex + 1; i <= this.page.periods; i++){
if(this.line.slots && this.line.slots[i] && this.line.slots[i].competencies){
const l = this.line.slots[i].competencies;
if(this.line.slots && this.line.slots[i] && this.line.slots[i].courses){
const l = this.line.slots[i].courses;
const f = this.line.slots[i-1].filters; // next filter is in the same slot
if(l[this.layer] || f[this.layer]) {
// slot is busy in this layer.

View File

@ -72,9 +72,9 @@ export function ProcessStudyplan(studyplan){
for(const is in line.slots ) {
const slot = line.slots[is];
if(slot.competencies !== undefined){
for(const ic in slot.competencies){
const itm = slot.competencies[ic];
if(slot.courses !== undefined){
for(const ic in slot.courses){
const itm = slot.courses[ic];
for(const idx in itm.connections.in) {
const conn = itm.connections.in[idx];

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
/**
*
* Webservice class for handling associations of cohorts and users to a studyplan
* @package local_treestudyplan
* @copyright 2023 P.M. Kuipers
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -27,11 +27,25 @@ use local_treestudyplan\local\helpers\webservicehelper;
require_once($CFG->libdir.'/externallib.php');
/**
* Webservice class for handling associations of cohorts and users to a studyplan
*/
class associationservice extends \external_api {
/**
* Capability required to edit study plans
* @var string
*/
const CAP_EDIT = "local/treestudyplan:editstudyplan";
/**
* Capability required to view studyplans (for other users)
* @var string
*/
const CAP_VIEW = "local/treestudyplan:viewuserreports";
public static function user_structure() : \external_description {
/**
* Webservice structure to use in describing a user
*/
public static function user_structure() : \external_description {
return new \external_single_structure([
"id" => new \external_value(PARAM_INT, 'user id'),
"username" => new \external_value(PARAM_TEXT, 'username'),
@ -42,6 +56,10 @@ class associationservice extends \external_api {
]);
}
/**
* Make a webservice user model for a given user
* @param stdClass $r User DB record
*/
public static function make_user_model($r) {
return [
"id" => $r->id,
@ -53,7 +71,10 @@ class associationservice extends \external_api {
];
}
public static function cohort_structure() : \external_description {
/**
* Webservice structure to use in describing a cohort
*/
public static function cohort_structure() : \external_description {
return new \external_single_structure([
"id" => new \external_value(PARAM_INT, 'cohort id'),
"name" => new \external_value(PARAM_TEXT, 'name'),
@ -69,6 +90,10 @@ class associationservice extends \external_api {
]);
}
/**
* Make a webservice cohort model for a given cohort
* @param stdClass $r Cohort DB record
*/
public static function make_cohort_model($r) {
global $DB;
@ -114,11 +139,17 @@ class associationservice extends \external_api {
/**
* Return value description for webservice function list_cohort
*/
public static function list_cohort_returns() : \external_description {
public static function list_cohort_returns() : \external_description {
return new \external_multiple_structure(self::cohort_structure());
}
// Actual functions.
/**
* Search cohorts for matching string
* @param string $like String to match cohorts with
* @param null $excludeid Do not include these cohorts
* @param int $contextid Context to search (default system)
* @return array
*/
public static function list_cohort($like = '', $excludeid = null, $contextid = 1) {
global $CFG, $DB;
@ -166,11 +197,17 @@ class associationservice extends \external_api {
/**
* Return value description for webservice function find_user
*/
public static function find_user_returns() : \external_description {
public static function find_user_returns() : \external_description {
return new \external_multiple_structure(self::user_structure());
}
// Actual functions.
/**
* Search users for match
* @param string $like String to match user firstname/lastname with
* @param null $excludeid Do not include these users
* @param int $contextid Context to search (default system)
* @return array
*/
public static function find_user($like, $excludeid = null, $contextid = 1) {
global $CFG, $DB;
@ -214,14 +251,19 @@ class associationservice extends \external_api {
/**
* Return value description for webservice function connect_cohort
*/
public static function connect_cohort_returns() : \external_description {
public static function connect_cohort_returns() : \external_description {
return new \external_single_structure([
"success" => new \external_value(PARAM_BOOL, 'operation completed succesfully'),
"msg" => new \external_value(PARAM_TEXT, 'message'),
]);
}
// Actual functions.
/**
* Connect a cohort to a studyplan
* @param mixed $studyplanid Id of studyplan
* @param mixed $cohortid Id of cohort
* @return array Success/fail model
*/
public static function connect_cohort($studyplanid, $cohortid) {
global $CFG, $DB;
@ -256,14 +298,19 @@ class associationservice extends \external_api {
/**
* Return value description for webservice function disconnect_cohort
*/
public static function disconnect_cohort_returns() : \external_description {
public static function disconnect_cohort_returns() : \external_description {
return new \external_single_structure([
"success" => new \external_value(PARAM_BOOL, 'operation completed succesfully'),
"msg" => new \external_value(PARAM_TEXT, 'message'),
]);
}
// Actual functions.
/**
* Disconnect a cohort from a studyplan
* @param mixed $studyplanid Id of studyplan
* @param mixed $cohortid Id of cohort
* @return array Success/fail model
*/
public static function disconnect_cohort($studyplanid, $cohortid) {
global $CFG, $DB;
@ -298,14 +345,19 @@ class associationservice extends \external_api {
/**
* Return value description for webservice function connect_user
*/
public static function connect_user_returns() : \external_description {
public static function connect_user_returns() : \external_description {
return new \external_single_structure([
"success" => new \external_value(PARAM_BOOL, 'operation completed succesfully'),
"msg" => new \external_value(PARAM_TEXT, 'message'),
]);
}
// Actual functions.
/**
* Connect a user to a studyplan
* @param mixed $studyplanid Id of studyplan
* @param mixed $userid Id of user
* @return array Success/fail model
*/
public static function connect_user($studyplanid, $userid) {
global $CFG, $DB;
@ -339,14 +391,19 @@ class associationservice extends \external_api {
/**
* Return value description for webservice function disconnect_user
*/
public static function disconnect_user_returns() : \external_description {
public static function disconnect_user_returns() : \external_description {
return new \external_single_structure([
"success" => new \external_value(PARAM_BOOL, 'operation completed succesfully'),
"msg" => new \external_value(PARAM_TEXT, 'message'),
]);
}
// Actual functions.
/**
* Disconnect a user from a studyplan
* @param mixed $studyplanid Id of studyplan
* @param mixed $userid Id of user
* @return array Success/fail model
*/
public static function disconnect_user($studyplanid, $userid) {
global $CFG, $DB;
$studyplan = studyplan::find_by_id($studyplanid);
@ -378,11 +435,15 @@ class associationservice extends \external_api {
/**
* Return value description for webservice function associated_users
*/
public static function associated_users_returns() : \external_description {
public static function associated_users_returns() : \external_description {
return new \external_multiple_structure(self::user_structure());
}
// Actual functions.
/**
* List all users associated to a studyplan
* @param mixed $studyplanid Id of studyplan
* @return array
*/
public static function associated_users($studyplanid) {
global $CFG, $DB;
$studyplan = studyplan::find_by_id($studyplanid);
@ -413,11 +474,15 @@ class associationservice extends \external_api {
/**
* Return value description for webservice function associated_cohorts
*/
public static function associated_cohorts_returns() : \external_description {
public static function associated_cohorts_returns() : \external_description {
return new \external_multiple_structure(self::cohort_structure());
}
// Actual functions.
/**
* List all cohorts associated to a studyplan
* @param mixed $studyplanid Id of studyplan
* @return array
*/
public static function associated_cohorts($studyplanid) {
global $CFG, $DB;
$studyplan = studyplan::find_by_id($studyplanid);
@ -446,11 +511,15 @@ class associationservice extends \external_api {
/**
* Return value description for webservice function all_associated
*/
public static function all_associated_returns() : \external_description {
public static function all_associated_returns() : \external_description {
return new \external_multiple_structure(self::user_structure());
}
// Actual functions.
/**
* List all users associated to a studyplan through either a cohort or directly
* @param mixed $studyplanid Id of studyplan
* @return array
*/
public static function all_associated($studyplanid) {
global $CFG, $DB;
@ -479,6 +548,10 @@ class associationservice extends \external_api {
return $users;
}
/**
* Sort a list of user models by firstname->lastname
* @param array $list Reference to list of user models
*/
public static function sortusermodels(&$list) {
return usort($list, function($a, $b) {
$m = [];
@ -509,11 +582,16 @@ class associationservice extends \external_api {
/**
* Return value description for webservice function cascade_cohortsync
*/
public static function cascade_cohortsync_returns() : \external_description {
public static function cascade_cohortsync_returns() : \external_description {
return success::structure();
}
// Actual functions.
/**
* Perform cascading cohort sync for a given studyplan
* This adds a cohort sync enrolment to all linked cohorts for each course listed in the studyplan
* @param mixed $studyplanid Id of studyplan
* @return array Success/fail model
*/
public static function cascade_cohortsync($studyplanid) {
$studyplan = studyplan::find_by_id($studyplanid);
webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context());

View File

@ -34,7 +34,7 @@ use \completion_criteria;
class completionscanner {
/**
* Cache of supported mods
* @var array
* @var array
*/
private static $modsupported = [];
/**
@ -46,7 +46,7 @@ class completionscanner {
* @var local\ungradedscanners\scanner_base
*/
private $scanner = null;
/**
/**
* Course module
* @var \cm_info
*/
@ -70,7 +70,7 @@ class completionscanner {
return self::$modsupported[$mod];
}
/**
/**
* List all users enrolled in a course as student by userid
* @param int $courseid Course id of the course to check
* @return int[] Array if user ids

View File

@ -60,7 +60,7 @@ class courseservice extends \external_api {
/**
* Parameter description for map_categories function
*/
public static function map_categories_returns() : \external_description {
public static function map_categories_returns() : \external_description {
return new \external_multiple_structure(static::map_category_structure(false));
}
@ -133,7 +133,7 @@ class courseservice extends \external_api {
/**
* Parameter description for get_category function
*/
public static function get_category_returns() : \external_description {
public static function get_category_returns() : \external_description {
return static::map_category_structure(false);
}
@ -195,7 +195,7 @@ class courseservice extends \external_api {
/**
* Parameter description for list_accessible_categories function
*/
public static function list_accessible_categories_returns() : \external_description {
public static function list_accessible_categories_returns() : \external_description {
return new \external_multiple_structure(static::map_category_structure(true));
}
@ -286,7 +286,7 @@ class courseservice extends \external_api {
/**
* Parameter description for list_used_categories function
*/
public static function list_used_categories_returns() : \external_description {
public static function list_used_categories_returns() : \external_description {
return new \external_multiple_structure(static::map_category_structure(true));
}
@ -392,7 +392,7 @@ class courseservice extends \external_api {
/**
* Parameter description for scan_grade_progress function
*/
public static function scan_grade_progress_returns() : \external_description {
public static function scan_grade_progress_returns() : \external_description {
return gradingscanner::structure(VALUE_REQUIRED);
}
@ -437,7 +437,7 @@ class courseservice extends \external_api {
/**
* Parameter description for scan_completion_progress function
*/
public static function scan_completion_progress_returns() : \external_description {
public static function scan_completion_progress_returns() : \external_description {
return completionscanner::structure(VALUE_REQUIRED);
}
@ -477,7 +477,7 @@ class courseservice extends \external_api {
/**
* Parameter description for scan_badge_progress function
*/
public static function scan_badge_progress_returns() : \external_description {
public static function scan_badge_progress_returns() : \external_description {
return new \external_single_structure([
"total" => new \external_value(PARAM_INT, 'Total number of students scanned'),
"issued" => new \external_value(PARAM_INT, 'Number of issued badges'),

View File

@ -33,7 +33,7 @@ use \grade_item;
class gradingscanner {
/**
* Cache of supported mods
* @var array
* @var array
*/
private static $modsupported = [];
/**
@ -64,7 +64,7 @@ class gradingscanner {
return self::$modsupported[$mod];
}
/**
/**
* List all users enrolled in a course as student by userid
* @param int $courseid Course id of the course to check
* @return int[] Array if user ids
@ -96,7 +96,7 @@ class gradingscanner {
}
}
/**
/**
* Check if this scanner is usable (has an internal activity specific scanner)
*/
public function is_available() : bool {
@ -171,7 +171,7 @@ class gradingscanner {
/**
* Check if a grade is considered passed according to the rules
* @param grade_grade $grade
* @param grade_grade $grade
*/
private function grade_passed($grade) : bool {
// Function copied from bistate aggregator to avoid reference mazes.

View File

@ -31,11 +31,11 @@ require_once($CFG->libdir.'/externallib.php');
class period {
/** @var string */
const TABLE = "local_treestudyplan_period";
/**
/**
* Cache all retrieved periods in this session
* @var array */
private static $cache = [];
/**
/**
* Cache the collection of periods per page retrieved this session
* @var array */
private static $pagecache = [];
@ -127,7 +127,7 @@ class period {
return $period;
}
/**
* Find all periods registered to a studyplan in sequence
* @param studyplanpage $page Studyplan page to find periods for
@ -165,7 +165,7 @@ class period {
return $this->id;
}
/**
/**
* Return associated studyplan
* @return studyplan
*/
@ -173,7 +173,7 @@ class period {
return $this->page->studyplan();
}
/**
/**
* Return associated studyplan page
* @return studyplanpage
*/
@ -257,12 +257,11 @@ class period {
}
/**
* Add a new period for a studyplan page
* Add a new period for a studyplan page
* Use only when performing import! The static find() and find_for_page() functions create the period during normal operation
* @param array $fields Properties for ['page_id', 'fullname', 'shortname', 'period', 'startdate', 'enddate']
* @return period
*/
public static function add($fields) {
public static function add($fields) : self {
global $DB;
if (!isset($fields['page_id'])) {

View File

@ -55,7 +55,7 @@ class studentstudyplanservice extends \external_api {
/**
* Return value description for webservice function list_user_studyplans
*/
public static function list_user_studyplans_returns() : \external_description {
public static function list_user_studyplans_returns() : \external_description {
return new \external_multiple_structure(
studyplan::simple_structure()
);
@ -98,7 +98,7 @@ class studentstudyplanservice extends \external_api {
/**
* Return value description for webservice function get_user_studyplans
*/
public static function get_user_studyplans_returns() : \external_description {
public static function get_user_studyplans_returns() : \external_description {
return new \external_multiple_structure(
studyplan::user_structure()
);
@ -144,7 +144,7 @@ class studentstudyplanservice extends \external_api {
/**
* Return value description for webservice function get_user_studyplan
*/
public static function get_user_studyplan_returns() : \external_description {
public static function get_user_studyplan_returns() : \external_description {
return studyplan::user_structure();
}
@ -185,7 +185,7 @@ class studentstudyplanservice extends \external_api {
/**
* Return value description for webservice function get_invited_studyplan
*/
public static function get_invited_studyplan_returns() : \external_description {
public static function get_invited_studyplan_returns() : \external_description {
return new \external_multiple_structure(
studyplan::user_structure()
);
@ -238,7 +238,7 @@ class studentstudyplanservice extends \external_api {
/**
* Return value description for webservice function list_own_studyplans
*/
public static function list_own_studyplans_returns() : \external_description {
public static function list_own_studyplans_returns() : \external_description {
return new \external_multiple_structure(
studyplan::simple_structure()
);
@ -278,7 +278,7 @@ class studentstudyplanservice extends \external_api {
/**
* Return value description for webservice function get_own_studyplan
*/
public static function get_own_studyplan_returns() : \external_description {
public static function get_own_studyplan_returns() : \external_description {
return new \external_multiple_structure(
studyplan::user_structure()
);
@ -333,7 +333,7 @@ class studentstudyplanservice extends \external_api {
/**
* Return value description for webservice function get_teaching_studyplans
*/
public static function get_teaching_studyplans_returns() : \external_description {
public static function get_teaching_studyplans_returns() : \external_description {
return new \external_multiple_structure(
studyplan::editor_structure()
);

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
/**
*
* Model class for study items
* @package local_treestudyplan
* @copyright 2023 P.M. Kuipers
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -25,19 +25,31 @@ defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/externallib.php');
/**
* Model class for study items
*/
class studyitem {
public const COMPETENCY = 'competency';
/** @var string */
public const COURSE = 'course';
/** @var string */
public const JUNCTION = 'junction';
/** @var string */
public const BADGE = 'badge';
/** @var string */
public const FINISH = 'finish';
/** @var string */
public const START = 'start';
/** @var string */
public const INVALID = 'invalid';
/** @var string */
public const TABLE = "local_treestudyplan_item";
private static $studyitemcache = [];
/**
* Cache retrieved studyitems in this session
* @var array */
private static $cache = [];
/**
* Holds database record
* @var stdClass
@ -46,26 +58,32 @@ class studyitem {
/** @var int */
private $id;
/** @var courseinfo */
private $courseinfo = null;
/** @var studyline */
private $studyline;
/** @var aggregator[] */
/** @var aggregator */
private $aggregator;
/**
* Return the context the studyplan is associated to
* @return \context
*/
public function context(): \context {
return $this->studyline->context();
}
/**
* Return the studyline for this item
*/
public function studyline(): studyline {
return $this->studyline;
}
public function conditions() {
/**
* Return the condition string for this item
*/
public function conditions() : string {
return $this->r->conditions;
}
@ -74,12 +92,16 @@ class studyitem {
* @param int $id Id of database record
*/
public static function find_by_id($id): self {
if (!array_key_exists($id, self::$studyitemcache)) {
self::$studyitemcache[$id] = new self($id);
if (!array_key_exists($id, self::$cache)) {
self::$cache[$id] = new self($id);
}
return self::$studyitemcache[$id];
return self::$cache[$id];
}
/**
* Construct a new model based on study item id
* @param int $id Study item id
*/
public function __construct($id) {
global $DB;
$this->id = $id;
@ -91,29 +113,44 @@ class studyitem {
/**
* Return database identifier
* @return int
*/
public function id() {
public function id() : int {
return $this->id;
}
public function slot() {
/**
* Return period slot for this item
*/
public function slot() : int {
return $this->r->slot;
}
public function layer() {
/**
* Return layer (order within a line and slot) for this item
*/
public function layer() : int {
return $this->r->layer;
}
public function type() {
/**
* Return study item type (see constants above)
*/
public function type() : string {
return $this->r->type;
}
public function courseid() {
/**
* Return id of linked course (only relevant on COURSE types) or 0 if none
*/
public function courseid() : int {
return $this->r->course_id;
}
public static function exists($id) {
/**
* Check if a studyitem with the given id exists
* @param int $id Id of studyplan
*/
public static function exists($id) : bool {
global $DB;
return is_numeric($id) && $DB->record_exists(self::TABLE, array('id' => $id));
}
@ -149,6 +186,10 @@ class studyitem {
return $this->generate_model("editor");
}
/**
* Create a model for the given type of operation
* @param string $mode One of [ 'editor', 'export']
*/
private function generate_model($mode) {
// 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).
@ -234,7 +275,13 @@ class studyitem {
}
public static function add($fields, $import = false) {
/**
* Add a new item
* @param array $fields Properties for study line ['line_id', 'type', 'layer', 'conditions', 'slot',
* 'competency_id', 'course_id', 'badge_id', 'continuation_id', 'span']
* @param bool $import Set tot true if calling on import
*/
public static function add($fields, $import = false) : self {
global $DB;
$addable = ['line_id', 'type', 'layer', 'conditions', 'slot',
'competency_id', 'course_id', 'badge_id', 'continuation_id', 'span'];
@ -253,7 +300,11 @@ class studyitem {
return $item;
}
public function edit($fields) {
/**
* Edit study item properties
* @param array $fields Changed roperties for study line ['conditions', 'course_id', 'continuation_id', 'span']
*/
public function edit($fields) : self {
global $DB;
$editable = ['conditions', 'course_id', 'continuation_id', 'span'];
@ -270,8 +321,11 @@ class studyitem {
return $this;
}
public function valid() {
// Check if referenced courses, badges and/or competencies still exist.
/**
* Check if references course and badges are still available
*/
public function valid() : bool {
// Check if referenced courses and/or badges still exist.
if ($this->r->type == static::COURSE) {
return courseinfo::exists($this->r->course_id);
} else if ($this->r->type == static::BADGE) {
@ -281,6 +335,10 @@ class studyitem {
}
}
/**
* Delete studyitem
* @param bool $force Force deletion even if item is referenced
*/
public function delete($force = false) {
global $DB;
@ -308,13 +366,11 @@ class studyitem {
}
}
/************************
* *
* reorder_studyitems *
* *
************************/
public static function reorder($resequence) {
/**
* Reposition study items in line, layer and/or slot
* @param mixed $resequence Array of item info [id, line_id, slot, layer]
*/
public static function reorder($resequence) : success {
global $DB;
foreach ($resequence as $sq) {
@ -333,7 +389,12 @@ class studyitem {
return success::success();
}
public static function find_studyline_children(studyline $line) {
/**
* Find all studyitems associated with a studyline
* @param studyline $line The studyline to search for
* @return studyitem[]
*/
public static function find_studyline_children(studyline $line) : array {
global $DB;
$list = [];
$ids = $DB->get_fieldset_select(self::TABLE, "id", "line_id = :line_id ORDER BY layer", ['line_id' => $line->id()]);
@ -344,6 +405,10 @@ class studyitem {
return $list;
}
/**
* Webservice structure for linking between plans
* @param int $value Webservice requirement constant
*/
private static function link_structure($value = VALUE_REQUIRED) : \external_description {
return new \external_single_structure([
"id" => new \external_value(PARAM_INT, 'id of study item'),
@ -354,7 +419,11 @@ class studyitem {
], 'basic info of referenced studyitem', $value);
}
private function link_model($userid) {
/**
* Webservice model for linking between plans
* @param int $userid ID for user to links completion from
*/
private function link_model($userid) : array {
global $DB;
$line = $DB->get_record(studyline::TABLE, ['id' => $this->r->line_id]);
$plan = $DB->get_record(studyplan::TABLE, ['id' => $line->studyplan_id]);
@ -445,14 +514,22 @@ class studyitem {
}
public function getcourseinfo() {
/**
* Get courseinfo for studyitem if it references a course
*/
public function getcourseinfo() : courseinfo {
if (empty($this->courseinfo) && courseinfo::exists($this->r->course_id)) {
$this->courseinfo = new courseinfo($this->r->course_id, $this);
}
return $this->courseinfo;
}
private function completion($userid) {
/**
* Determine completion for a particular user
* @param int $userid User id
* @return int completion:: constant
*/
private function completion($userid) : int {
global $DB;
if ($this->valid()) {
@ -518,7 +595,11 @@ class studyitem {
}
}
public function duplicate($newline) {
/**
* Duplicate this studyitem
* @param studyline $newline Study line to add duplicate to
*/
public function duplicate($newline) : self {
global $DB;
// Clone the database fields.
$fields = clone $this->r;
@ -545,7 +626,12 @@ class studyitem {
return $this->generate_model("export");
}
public static function import_item($model) {
/**
* Import studyitems from model
* @param array $model Decoded array
*/
public static function import_item($model) : self {
unset($model["course_id"]);
unset($model["competency_id"]);
unset($model["badge_id"]);

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
/**
*
* Model class for study lines
* @package local_treestudyplan
* @copyright 2023 P.M. Kuipers
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -24,28 +24,55 @@ namespace local_treestudyplan;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/externallib.php');
/**
* Model class for study lines
*/
class studyline {
public const SLOTSET_COMPETENCY = 'competencies';
/**
* Handle for course slots in the period for webservice export
* @var string
*/
public const SLOTSET_COURSES = 'courses';
/**
* Handle for filter slots around the periods for webservice export
* @var string
*/
public const SLOTSET_FILTER = 'filters';
public const COMPETENCY_TYPES = [
studyitem::COMPETENCY,
/**
* List of item types allowed in the course slot
* @var array
*/
public const COURSE_TYPES = [
studyitem::COURSE,
];
/**
* List of item types allowed in the filter slot
* @var array
*/
public const FILTER_TYPES = [
studyitem::JUNCTION,
studyitem::BADGE,
studyitem::FINISH,
studyitem::START,
];
/**
* List of item types allowed in the first filter slot
* @var array
*/
public const FILTER0_TYPES = [
studyitem::START,
];
/** @var string */
public const TABLE = "local_treestudyplan_line";
private static $studylinecache = [];
/**
* Cache retrieved studylines for optimization
* @var array
*/
private static $cache = [];
/**
* Holds database record
@ -62,16 +89,21 @@ class studyline {
/**
* Return the context the studyplan is associated to
* @return \context
*/
public function context(): \context {
return $this->studyplan->context();
}
/**
* Return the studyplan for this line
*/
public function studyplan() : studyplan {
return $this->studyplan;
}
/**
* Return the studyplan page for this line
*/
public function page() : studyplanpage {
return $this->page;
}
@ -81,10 +113,10 @@ class studyline {
* @param int $id Id of database record
*/
public static function find_by_id($id): self {
if (!array_key_exists($id, self::$studylinecache)) {
self::$studylinecache[$id] = new self($id);
if (!array_key_exists($id, self::$cache)) {
self::$cache[$id] = new self($id);
}
return self::$studylinecache[$id];
return self::$cache[$id];
}
/**
@ -101,20 +133,22 @@ class studyline {
/**
* Return database identifier
* @return int
*/
public function id() {
public function id() : int {
return $this->id;
}
/**
* Return full name
* @return string
*/
public function name() {
public function name() : string {
return $this->r->name;
}
public function shortname() {
/**
* Return short name
*/
public function shortname() : string {
return $this->r->shortname;
}
@ -131,7 +165,7 @@ class studyline {
"sequence" => new \external_value(PARAM_INT, 'order of studyline'),
"slots" => new \external_multiple_structure(
new \external_single_structure([
self::SLOTSET_COMPETENCY => new \external_multiple_structure(
self::SLOTSET_COURSES => new \external_multiple_structure(
studyitem::editor_structure(), 'competency items', VALUE_OPTIONAL),
self::SLOTSET_FILTER => new \external_multiple_structure(
studyitem::editor_structure(), 'filter items'),
@ -144,11 +178,15 @@ class studyline {
* Webservice model for editor info
* @return array Webservice data model
*/
public function editor_model() {
public function editor_model() : array {
return $this->generate_model("editor");
}
protected function generate_model($mode) {
/**
* Create a model for the given type of operation
* @param string $mode One of [ 'editor', 'export']
*/
protected function generate_model($mode) : array {
// 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).
global $DB;
@ -182,7 +220,7 @@ class studyline {
$slots = [];
} else {
if ($i > 0) {
$slots = [self::SLOTSET_COMPETENCY => [], self::SLOTSET_FILTER => []];
$slots = [self::SLOTSET_COURSES => [], self::SLOTSET_FILTER => []];
} else {
$slots = [self::SLOTSET_FILTER => []];
}
@ -197,8 +235,8 @@ class studyline {
} else {
$slotset = null;
if ($c->slot() > 0) {
if (in_array($c->type(), self::COMPETENCY_TYPES)) {
$slotset = self::SLOTSET_COMPETENCY;
if (in_array($c->type(), self::COURSE_TYPES)) {
$slotset = self::SLOTSET_COURSES;
} else if (in_array($c->type(), self::FILTER_TYPES)) {
$slotset = self::SLOTSET_FILTER;
}
@ -213,7 +251,12 @@ class studyline {
return $model;
}
public static function add($fields) {
/**
* Add a new study line
* @param array $fields Properties for study line ['page_id', 'name', 'shortname', 'color']
*/
public static function add($fields) : self {
global $DB;
if (!isset($fields['page_id'])) {
@ -233,7 +276,11 @@ class studyline {
return self::find_by_id($id);
}
public function edit($fields) {
/**
* Edit study line properties
* @param array $fields Changed roperties for study line ['name', 'shortname', 'color']
*/
public function edit($fields) : self {
global $DB;
$editable = ['name', 'shortname', 'color'];
$info = ['id' => $this->id, ];
@ -248,7 +295,11 @@ class studyline {
return $this;
}
public function delete($force = false) {
/**
* Delete studyline
* @param bool $force Force deletion even if study line contains items
*/
public function delete($force = false) : success {
global $DB;
if ($force) {
@ -266,7 +317,11 @@ class studyline {
}
}
public static function reorder($resequence) {
/**
* Reorder study lines
* @param int[] $resequence New order of study lines by id
*/
public static function reorder($resequence) : success {
global $DB;
foreach ($resequence as $sq) {
@ -279,7 +334,12 @@ class studyline {
return success::success();
}
public static function find_page_children(studyplanpage $page) {
/**
* Find all studylines associated with a studyplan page
* @param studyplanpage $page The studyplanpage to search for
* @return studyline[]
*/
public static function find_page_children(studyplanpage $page) : array {
global $DB;
$list = [];
$ids = $DB->get_fieldset_select(self::TABLE, "id", "page_id = :page_id ORDER BY sequence",
@ -303,7 +363,7 @@ class studyline {
"sequence" => new \external_value(PARAM_INT, 'order of studyline'),
"slots" => new \external_multiple_structure(
new \external_single_structure([
self::SLOTSET_COMPETENCY => new \external_multiple_structure(
self::SLOTSET_COURSES => new \external_multiple_structure(
studyitem::user_structure(), 'competency items', VALUE_OPTIONAL),
self::SLOTSET_FILTER => new \external_multiple_structure(
studyitem::user_structure(), 'filter items'),
@ -341,7 +401,7 @@ class studyline {
// Create the required amount of slots.
for ($i = 0; $i < $numslots + 1; $i++) {
if ($i > 0) {
$slots = [self::SLOTSET_COMPETENCY => [], self::SLOTSET_FILTER => []];
$slots = [self::SLOTSET_COURSES => [], self::SLOTSET_FILTER => []];
} else {
$slots = [self::SLOTSET_FILTER => []];
}
@ -353,8 +413,8 @@ class studyline {
if ($c->valid()) {
$slotset = null;
if ($c->slot() > 0) {
if (in_array($c->type(), self::COMPETENCY_TYPES)) {
$slotset = self::SLOTSET_COMPETENCY;
if (in_array($c->type(), self::COURSE_TYPES)) {
$slotset = self::SLOTSET_COURSES;
} else if (in_array($c->type(), self::FILTER_TYPES)) {
$slotset = self::SLOTSET_FILTER;
}
@ -371,7 +431,12 @@ class studyline {
}
public function duplicate($newstudyplan, &$translation) {
/**
* Duplicate this studyplan page
* @param studyplan $newstudyplan Studyplan to copy the line into
* @param array $translation Mapping array of old item ids to new item ids for connection matching
*/
public function duplicate($newstudyplan, &$translation) : self {
global $DB;
// Clone the database fields.
@ -403,7 +468,14 @@ class studyline {
return $this->generate_model("export");
}
public function import_studyitems($model, &$itemtranslation, &$connections) {
/**
* Import study items into line from decoded array model
* @param array $model Decoded array
* @param array $itemtranslation Link to array to map old item ids to new item ids for connection matching
* @param array $connections Link to array of connections between item
* @return null
*/
public function import_studyitems(array $model, array &$itemtranslation, array &$connections) {
global $DB;
foreach ($model as $slot => $slotmodel) {
$courselayer = 0;

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
/**
*
* Model class for study plan
* @package local_treestudyplan
* @copyright 2023 P.M. Kuipers
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -24,12 +24,23 @@ namespace local_treestudyplan;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/externallib.php');
/**
* Model class for study plan
*/
class studyplan {
/** @var string */
const TABLE = "local_treestudyplan";
private static $studyplancache = [];
/**
* Cache retrieved studyitems in this session
* @var array */
private static $cache = [];
/**
* Cache retrieved pages for the studyplan in this session
* @var array */
private static $pagecache = [];
/**
* Holds database record
@ -40,25 +51,35 @@ class studyplan {
private $id;
/** @var aggregator */
private $aggregator;
private $context = null; // Hold context object once retrieved.
private $linkeduserids = null; // Cache lookup of linked users (saves queries).
/** @var studyplanpage[] */
private $pagecache = null;
public function aggregator() {
/**
* Hold context object once retrieved.
* @var \context
*/
private $context = null;
/**
* Cache lookup of linked users (saves queries).
* @var int[]
*/
private $linkeduserids = null;
/**
* Return configured aggregator for this studyplan
*/
public function aggregator() : aggregator {
return $this->aggregator;
}
// Cache constructors to avoid multiple creation events in one session.
/**
* Find record in database and return management object
* Cache objects to avoid multiple creation events in one session.
* @param int $id Id of database record
*/
public static function find_by_id($id): self {
if (!array_key_exists($id, self::$studyplancache)) {
self::$studyplancache[$id] = new self($id);
if (!array_key_exists($id, self::$cache)) {
self::$cache[$id] = new self($id);
}
return self::$studyplancache[$id];
return self::$cache[$id];
}
/**
@ -97,14 +118,16 @@ class studyplan {
return $this->r->name;
}
public function pages() {
// Cached version of find_studyplan_children.
// (may be premature optimization, since .
// Find_studyplan_children also does some caching).
if (empty($this->page_cache)) {
$this->page_cache = studyplanpage::find_studyplan_children($this);
/**
* Return the studyplan pages associated with this plan
* @return studyplanpage[]
*/
public function pages() : array {
if (empty($this->pagecache)) {
$this->pagecache = studyplanpage::find_studyplan_children($this);
}
return $this->page_cache;
return $this->pagecache;
}
/**
@ -238,7 +261,13 @@ class studyplan {
return $model;
}
public static function add($fields, $bare = false) {
/**
* Add a new studyplan
* @param array $fields Properties for study line ['name', 'shortname', 'description', 'idnumber', 'context_id', 'aggregation',
* 'aggregation_config', 'periods', 'startdate', 'enddate'];
* @param bool $bare If true, do not create a first page with copy of studyplan names
*/
public static function add($fields, $bare = false) : self {
global $CFG, $DB;
$addable = ['name', 'shortname', 'description', 'idnumber', 'context_id', 'aggregation', 'aggregation_config'];
@ -278,7 +307,12 @@ class studyplan {
return $plan;
}
public function edit($fields) {
/**
* Edit study line properties
* @param array $fields Changed roperties for study line ['name', 'shortname', 'description', 'idnumber',
* 'context_id', 'aggregation', 'aggregation_config']
*/
public function edit($fields) : self {
global $DB;
$editable = ['name', 'shortname', 'description', 'idnumber', 'context_id', 'aggregation', 'aggregation_config'];
$info = ['id' => $this->id, ];
@ -321,7 +355,11 @@ class studyplan {
return $this;
}
public function delete($force = false) {
/**
* Delete studyline
* @param bool $force Force deletion even if study line contains items
*/
public function delete($force = false) : success {
global $DB;
if ($force) {
@ -339,7 +377,12 @@ class studyplan {
}
}
public static function find_all($contextid = -1) {
/**
* Find all studyplans in a given context or the system context
* @param int $contextid Optional contextid to search in. System context used if left empty
* @return studyplan[]
*/
public static function find_all($contextid = -1) : array {
global $DB, $USER;
$list = [];
@ -361,6 +404,13 @@ class studyplan {
return $list;
}
/**
* Find all studyplans in a given context or the system context with a specific short name
* (Used in generating random grades for development)
* @param string $shortname Shortname to match
* @param int $contextid Optional contextid to search in. System context used if left empty
* @return studyplan[]
*/
public static function find_by_shortname($shortname, $contextid = 0): array {
global $DB;
$list = [];
@ -376,7 +426,12 @@ class studyplan {
return $list;
}
public static function find_for_user($userid) {
/**
* Find all studyplans for a given user
* @param int $userid Id of the user to search for
* @return studyplan[]
*/
public static function find_for_user($userid) : array {
global $DB;
$sql = "SELECT s.id FROM {local_treestudyplan} s
@ -404,7 +459,11 @@ class studyplan {
}
public static function exist_for_user($userid) {
/**
* Check if a given user has associated studyplans
* @param int $userid Id of the user to search for
*/
public static function exist_for_user($userid) : bool {
global $DB;
$count = 0;
$sql = "SELECT s.* FROM {local_treestudyplan} s
@ -423,9 +482,9 @@ class studyplan {
/**
* Retrieve the users linked to this studyplan.
* @return array of User objects
* @return stdClass[] User objects
*/
public function find_linked_users() {
public function find_linked_users() : array {
global $DB;
$users = [];
@ -446,11 +505,11 @@ class studyplan {
public function find_linked_userids(): array {
global $DB;
if ($this->linked_userids === null) {
if ($this->linkeduserids === null) {
$uids = [];
// First get directly linked userids.
$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]);
$uids = array_merge($uids, $ulist);
@ -459,16 +518,16 @@ class studyplan {
}
// 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
WHERE j.studyplan_id = :planid";
$ulist = $DB->get_fieldset_sql($sql, ['planid' => $this->id]);
$uids = array_merge($uids, $ulist);
$this->linked_userids = array_unique($uids);
$this->linkeduserids = array_unique($uids);
}
return $this->linked_userids;
return $this->linkeduserids;
}
/** Check if this studyplan is linked to a particular user
@ -528,13 +587,26 @@ class studyplan {
return $model;
}
public static function duplicate_plan($planid, $name, $shortname) {
/**
* Duplicate a studyplan by id
* Function used by webservices and returns webservices model
* @param int $planid Id if studyplan
* @param string $name New fullname of studyplan
* @param string $shortname New shortname of studyplan
* @return array Simple webservices model of plan
*/
public static function duplicate_plan($planid, $name, $shortname) : array {
$ori = self::find_by_id($planid);
$new = $ori->duplicate($name, $shortname);
return $new->simple_model();
}
public function duplicate($name, $shortname) {
/**
* Duplicate this studyplan
* @param string $name New fullname of studyplan
* @param string $shortname New shortname of studyplan
*/
public function duplicate($name, $shortname) : self {
// First duplicate the studyplan structure.
$newplan = self::add([
'name' => $name,
@ -561,6 +633,10 @@ class studyplan {
], 'Exported studyplan');
}
/**
* Export this page into a json model
* @return array
*/
public function export_plan() {
$model = $this->export_model();
$json = json_encode([
@ -600,6 +676,12 @@ class studyplan {
return $pages;
}
/**
* Import studyplan from file contents
* @param string $content String
* @param string $format Format description
* @param int $contextid The context to import into
*/
public static function import_studyplan($content, $format = "application/json", $contextid = 1) {
if ($format != "application/json") {
return false;
@ -625,6 +707,11 @@ class studyplan {
}
}
/**
* Import studyplan pages from file contents
* @param string $content String
* @param string $format Format description
*/
public function import_pages($content, $format = "application/json") {
if ($format != "application/json") {
return false;
@ -643,7 +730,12 @@ class studyplan {
}
}
protected function import_pages_model($model) {
/**
* Import pages from decoded array model
* @param array $model Decoded array
*/
protected function import_pages_model($model) : bool {
$this->pages(); // Make sure the page cache is initialized, since we will be adding to it.
foreach ($model as $p) {
$p["studyplan_id"] = $this->id();
@ -666,7 +758,7 @@ class studyplan {
}
/**
* Clear the csync mark
* Clear the studyplan as changed regarding courses and associated cohorts
*/
public function clear_csync_changed() {
global $DB;
@ -675,14 +767,18 @@ class studyplan {
$this->r->csync_flag = 0;
}
public function has_csync_changed() {
/**
* Check if the studyplan as changed regarding courses and associated cohorts
*/
public function has_csync_changed() : bool {
return ($this->r->csync_flag > 0) ? true : false;
}
/**
* See if the specified course id is linked in this studyplan
* @param int $courseid Id of course to check
*/
public function course_linked($courseid) {
public function course_linked($courseid) : bool {
global $DB;
$sql = "SELECT COUNT(i.id)
@ -699,8 +795,9 @@ class studyplan {
/**
* List the course id is linked in this studyplan
* Used for cohort enrolment cascading
* @return int[]
*/
public function get_linked_course_ids() {
public function get_linked_course_ids() : array {
global $DB;
$sql = "SELECT i.course_id
@ -728,8 +825,9 @@ class studyplan {
/**
* List the user id's explicitly associated with this studyplan
* @return int[]
*/
public function get_linked_user_ids() {
public function get_linked_user_ids() : array {
global $CFG, $DB;
$sql = "SELECT DISTINCT j.user_id FROM {local_treestudyplan_user} j
@ -738,9 +836,10 @@ class studyplan {
return $fields;
}
/**
* See if the specified course id is linked in this studyplan
* See if the specified badge is linked in this studyplan
* @param int $badgeid Badge id
*/
public function badge_linked($badgeid) {
public function badge_linked($badgeid) : bool {
global $DB;
$sql = "SELECT COUNT(i.id)

View File

@ -449,7 +449,7 @@ class studyplanpage {
for ($i = 1; $i <= $periods; $i++) {
if (count($line["slots"]) > $i) {
$ct = 0;
foreach ($line["slots"][$i][studyline::SLOTSET_COMPETENCY] as $itm) {
foreach ($line["slots"][$i][studyline::SLOTSET_COURSES] as $itm) {
if ($itm["type"] == "course") {
$ct += 1;
}
@ -467,7 +467,7 @@ class studyplanpage {
$filled = false;
if (count($line["slots"]) > $i) {
$ct = 0;
foreach ($line["slots"][$i][studyline::SLOTSET_COMPETENCY] as $itm) {
foreach ($line["slots"][$i][studyline::SLOTSET_COURSES] as $itm) {
if ($itm["type"] == "course") {
if ($ct == $lct) {
$csv .= ", \"";

View File

@ -63,7 +63,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function list_studyplans
*/
public static function list_studyplans_returns() : \external_description {
public static function list_studyplans_returns() : \external_description {
return new \external_multiple_structure( studyplan::simple_structure() );
}
@ -107,7 +107,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function get_studyplan_map
*/
public static function get_studyplan_map_returns() : \external_description {
public static function get_studyplan_map_returns() : \external_description {
return studyplan::editor_structure();
}
@ -144,7 +144,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function get_studyline_map
*/
public static function get_studyline_map_returns() : \external_description {
public static function get_studyline_map_returns() : \external_description {
return new \external_multiple_structure( studyline::editor_structure() );
}
@ -187,7 +187,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function add_studyplan
*/
public static function add_studyplan_returns() : \external_description {
public static function add_studyplan_returns() : \external_description {
return studyplan::simple_structure();
}
@ -254,7 +254,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function edit_studyplan
*/
public static function edit_studyplan_returns() : \external_description {
public static function edit_studyplan_returns() : \external_description {
return studyplan::simple_structure();
}
@ -317,7 +317,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function delete_studyplan
*/
public static function delete_studyplan_returns() : \external_description {
public static function delete_studyplan_returns() : \external_description {
return success::structure();
}
@ -356,7 +356,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function add_studyline
*/
public static function add_studyline_returns() : \external_description {
public static function add_studyline_returns() : \external_description {
return studyline::editor_structure();
}
@ -405,7 +405,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function edit_studyline
*/
public static function edit_studyline_returns() : \external_description {
public static function edit_studyline_returns() : \external_description {
return studyline::editor_structure();
}
@ -448,7 +448,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function delete_studyline
*/
public static function delete_studyline_returns() : \external_description {
public static function delete_studyline_returns() : \external_description {
return success::structure();
}
@ -488,14 +488,14 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function reorder_studylines
*/
public static function reorder_studylines_returns() : \external_description {
public static function reorder_studylines_returns() : \external_description {
return success::structure();
}
/**
* Reorder study lines
* @param int[] $resequence New order of study lines by id
* @return [type]
* @return array
*/
public static function reorder_studylines($resequence) {
// Validate if the requesting user has the right to edit the lines in it's current context.
@ -529,7 +529,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function get_studyitem
*/
public static function get_studyitem_returns() : \external_description {
public static function get_studyitem_returns() : \external_description {
return studyitem::editor_structure();
}
@ -573,7 +573,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function add_studyitem
*/
public static function add_studyitem_returns() : \external_description {
public static function add_studyitem_returns() : \external_description {
return studyitem::editor_structure();
}
@ -622,7 +622,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function edit_studyitem
*/
public static function edit_studyitem_returns() : \external_description {
public static function edit_studyitem_returns() : \external_description {
return studyitem::editor_structure();
}
@ -675,7 +675,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function reorder_studyitems
*/
public static function reorder_studyitems_returns() : \external_description {
public static function reorder_studyitems_returns() : \external_description {
return success::structure();
}
@ -711,7 +711,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function delete_studyitem
*/
public static function delete_studyitem_returns() : \external_description {
public static function delete_studyitem_returns() : \external_description {
return success::structure();
}
@ -746,7 +746,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function connect_studyitems
*/
public static function connect_studyitems_returns() : \external_description {
public static function connect_studyitems_returns() : \external_description {
return studyitemconnection::structure();
}
@ -784,7 +784,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function disconnect_studyitems
*/
public static function disconnect_studyitems_returns() : \external_description {
public static function disconnect_studyitems_returns() : \external_description {
return success::structure();
}
@ -817,7 +817,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function list_badges
*/
public static function list_badges_returns() : \external_description {
public static function list_badges_returns() : \external_description {
return new \external_multiple_structure(badgeinfo::editor_structure());
}
@ -862,7 +862,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function include_grade
*/
public static function include_grade_returns() : \external_description {
public static function include_grade_returns() : \external_description {
return success::structure();
}
@ -910,7 +910,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function list_aggregators
*/
public static function list_aggregators_returns() : \external_description {
public static function list_aggregators_returns() : \external_description {
return aggregator::list_structure();
}
@ -1070,7 +1070,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function list_scales
*/
public static function list_scales_returns() : \external_description {
public static function list_scales_returns() : \external_description {
return new \external_multiple_structure(new \external_single_structure([
"id" => new \external_value(PARAM_INT, 'id of scale'),
"name" => new \external_value(PARAM_TEXT, 'scale name'),
@ -1115,7 +1115,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function disable_autoenddate
*/
public static function disable_autoenddate_returns() : \external_description {
public static function disable_autoenddate_returns() : \external_description {
return success::structure();
}
@ -1171,7 +1171,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function duplicate_plan
*/
public static function duplicate_plan_returns() : \external_description {
public static function duplicate_plan_returns() : \external_description {
return studyplan::simple_structure();
}
@ -1208,7 +1208,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function export_plan
*/
public static function export_plan_returns() : \external_description {
public static function export_plan_returns() : \external_description {
return studyplan::export_structure();
}
@ -1248,7 +1248,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function export_studylines
*/
public static function export_studylines_returns() : \external_description {
public static function export_studylines_returns() : \external_description {
return studyplan::export_structure();
}
@ -1287,7 +1287,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function import_plan
*/
public static function import_plan_returns() : \external_description {
public static function import_plan_returns() : \external_description {
return success::structure();
}
@ -1326,7 +1326,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function import_studylines
*/
public static function import_studylines_returns() : \external_description {
public static function import_studylines_returns() : \external_description {
return success::structure();
}
@ -1372,7 +1372,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function submit_cm_editform
*/
public static function submit_cm_editform_returns() : \external_description {
public static function submit_cm_editform_returns() : \external_description {
return success::structure();
}
@ -1464,7 +1464,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function edit_period
*/
public static function edit_period_returns() : \external_description {
public static function edit_period_returns() : \external_description {
return period::structure();
}
@ -1512,7 +1512,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function course_period_timing
*/
public static function course_period_timing_returns() : \external_description {
public static function course_period_timing_returns() : \external_description {
return courseinfo::editor_structure();
}
@ -1589,7 +1589,7 @@ class studyplanservice extends \external_api {
/**
* Return value description for webservice function set_studyitem_span
*/
public static function set_studyitem_span_returns() : \external_description {
public static function set_studyitem_span_returns() : \external_description {
return studyitem::editor_structure();
}

View File

@ -67,7 +67,7 @@ class success {
/**
* Describe the result for the webservice model
*/
public static function structure() : \external_description {
public static function structure() : \external_description {
return new \external_single_structure([
"success" => new \external_value(PARAM_BOOL, 'operation completed succesfully'),
"msg" => new \external_value(PARAM_TEXT, 'message'),