Code style
This commit is contained in:
parent
4c669ff08c
commit
e72be595aa
|
@ -80,7 +80,7 @@ abstract class aggregator {
|
|||
* @param mixed $configstr Configuration string for aggregator
|
||||
* @throws ValueError If method is not found
|
||||
*/
|
||||
public static function create($method, $configstr) : self {
|
||||
public static function create($method, $configstr): self {
|
||||
if (self::supported($method)) {
|
||||
$agclass = self::aggregator_name($method);
|
||||
return new $agclass($configstr);
|
||||
|
@ -95,7 +95,7 @@ abstract class aggregator {
|
|||
* @param mixed $method Aggregation method
|
||||
* @param mixed $configstr Configuration string for aggregator
|
||||
*/
|
||||
public static function create_or_default($method, $configstr) : self {
|
||||
public static function create_or_default($method, $configstr): self {
|
||||
try {
|
||||
return self::create($method, $configstr);
|
||||
} catch (\ValueError $x) {
|
||||
|
@ -190,7 +190,7 @@ abstract class aggregator {
|
|||
* Determine if Aggregation method makes use of "required grades" in a course/module.
|
||||
* @return bool True if Aggregation method makes use of "required grades" in a course/module.
|
||||
*/
|
||||
public function use_required_grades(){
|
||||
public function use_required_grades() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -198,11 +198,10 @@ abstract class aggregator {
|
|||
* Determine if aggregation method makes use of item conditions
|
||||
* @return bool True if aggregation method makes use of
|
||||
*/
|
||||
public function use_item_conditions(){
|
||||
public function use_item_conditions() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the current configuration string.
|
||||
* @return string Configuration string
|
||||
|
@ -211,12 +210,11 @@ abstract class aggregator {
|
|||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Webservice structure for basic aggregator info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function basic_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function basic_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"useRequiredGrades" => new \external_value(PARAM_BOOL, 'id of studyplan'),
|
||||
"useItemConditions" => new \external_value(PARAM_BOOL, 'name of studyplan'),
|
||||
|
@ -239,7 +237,7 @@ abstract class aggregator {
|
|||
* @param int $value Webservice requirement constant
|
||||
* @return mixed Webservice output structure
|
||||
*/
|
||||
public static function list_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function list_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_multiple_structure(new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_TEXT, 'id of aggregator'),
|
||||
"name" => new \external_value(PARAM_TEXT, 'name of agregator'),
|
||||
|
|
|
@ -50,7 +50,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Webservice structure to use in describing a user
|
||||
*/
|
||||
public static function user_structure() : \external_description {
|
||||
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'),
|
||||
|
@ -80,7 +80,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Webservice structure to use in describing a cohort
|
||||
*/
|
||||
public static function cohort_structure() : \external_description {
|
||||
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'),
|
||||
|
@ -124,14 +124,14 @@ class associationservice extends \external_api {
|
|||
"shortpath" => array_map(function($c) {
|
||||
return \context::instance_by_id($c)->get_context_name(false, true);
|
||||
}, $ctxpath),
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
public static function user_lastaccess($userid,$studyplanid=null) {
|
||||
public static function user_lastaccess($userid, $studyplanid=null) {
|
||||
global $DB;
|
||||
if (!empty($studyplanid)) {
|
||||
$lasql = "SELECT MAX(a.timeaccess) FROM {user_lastaccess} a
|
||||
|
@ -139,22 +139,20 @@ class associationservice extends \external_api {
|
|||
INNER JOIN {local_treestudyplan_line} l ON l.id = i.line_id
|
||||
INNER JOIN {local_treestudyplan_page} p ON l.page_id = p.id
|
||||
WHERE a.userid = :userid AND p.studyplan_id = :studyplanid";
|
||||
$lastaccess = $DB->get_field_sql($lasql,["userid" => $userid, "studyplanid" => $studyplanid]);
|
||||
$lastaccess = $DB->get_field_sql($lasql, ["userid" => $userid, "studyplanid" => $studyplanid]);
|
||||
} else {
|
||||
$lasql = "SELECT MAX(a.timeaccess) FROM {user_lastaccess} a
|
||||
WHERE a.userid = :userid";
|
||||
$lastaccess = $DB->get_field_sql($lasql,["userid" => $userid]);
|
||||
$lastaccess = $DB->get_field_sql($lasql, ["userid" => $userid]);
|
||||
}
|
||||
|
||||
|
||||
return $lastaccess;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parameter description for webservice function list_cohort
|
||||
*/
|
||||
public static function list_cohort_parameters() : \external_function_parameters {
|
||||
public static function list_cohort_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
'like' => new \external_value(PARAM_TEXT, 'search text'),
|
||||
'studyplan_id' => new \external_value(PARAM_INT, 'id of studyplan to list for'),
|
||||
|
@ -164,32 +162,32 @@ 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* Search cohorts for matching string
|
||||
* @param string $like String to match cohorts with
|
||||
* @param int $studyplan_id Do not include these cohorts
|
||||
* @param int $studyplanid Do not include these cohorts
|
||||
* @return array
|
||||
*/
|
||||
public static function list_cohort($like, $studyplan_id) {
|
||||
public static function list_cohort($like, $studyplanid) {
|
||||
global $CFG, $DB;
|
||||
|
||||
// Only allow this if the user has the right to edit in this context.
|
||||
$studyplan = studyplan::find_by_id($studyplan_id);
|
||||
$studyplan = studyplan::find_by_id($studyplanid);
|
||||
$context = $studyplan->context();
|
||||
webservicehelper::require_capabilities(self::CAP_EDIT, $context);
|
||||
|
||||
$pattern = "%{$like}%";
|
||||
|
||||
$params = ["pattern_nm" => $pattern, "pattern_id" => $pattern, ];
|
||||
$params = ["pattern_nm" => $pattern, "pattern_id" => $pattern ];
|
||||
|
||||
$sql = "SELECT DISTINCT c.* from {cohort} c LEFT JOIN {local_treestudyplan_cohort} j ON c.id = j.cohort_id
|
||||
WHERE c.visible = 1 AND(name LIKE :pattern_nm OR idnumber LIKE :pattern_id)
|
||||
AND (j.studyplan_id IS NULL OR j.studyplan_id != :exclude_id)";
|
||||
$params['exclude_id'] = $studyplan_id;
|
||||
$params['exclude_id'] = $studyplanid;
|
||||
|
||||
$cohorts = [];
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
|
@ -203,7 +201,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function find_user
|
||||
*/
|
||||
public static function find_user_parameters() : \external_function_parameters {
|
||||
public static function find_user_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
'like' => new \external_value(PARAM_TEXT, 'search text'),
|
||||
'studyplan_id' => new \external_value(PARAM_INT, 'id of studyplan to list for'),
|
||||
|
@ -213,7 +211,7 @@ 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());
|
||||
}
|
||||
|
||||
|
@ -224,11 +222,11 @@ class associationservice extends \external_api {
|
|||
* @param int $contextid Context to search (default system)
|
||||
* @return array
|
||||
*/
|
||||
public static function find_user($like, $studyplan_id) {
|
||||
public static function find_user($like, $studyplanid) {
|
||||
global $CFG, $DB;
|
||||
|
||||
// Only allow this if the user has the right to edit in this context.
|
||||
$studyplan = studyplan::find_by_id($studyplan_id);
|
||||
$studyplan = studyplan::find_by_id($studyplanid);
|
||||
$context = $studyplan->context();
|
||||
webservicehelper::require_capabilities(self::CAP_EDIT, $context);
|
||||
|
||||
|
@ -240,7 +238,7 @@ class associationservice extends \external_api {
|
|||
$sql = "SELECT DISTINCT u.* from {user} u LEFT JOIN {local_treestudyplan_user} j ON u.id = j.user_id
|
||||
WHERE u.deleted != 1 AND (firstname LIKE :pattern_fn OR lastname LIKE :pattern_ln OR username LIKE :pattern_un)
|
||||
AND (j.studyplan_id IS NULL OR j.studyplan_id != :exclude_id)";
|
||||
$params['exclude_id'] = $studyplan_id;
|
||||
$params['exclude_id'] = $studyplanid;
|
||||
|
||||
$users = [];
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
|
@ -256,7 +254,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function connect_cohort
|
||||
*/
|
||||
public static function connect_cohort_parameters() : \external_function_parameters {
|
||||
public static function connect_cohort_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan', VALUE_OPTIONAL),
|
||||
"cohort_id" => new \external_value(PARAM_INT, 'id of cohort to link', VALUE_OPTIONAL),
|
||||
|
@ -266,7 +264,7 @@ 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'),
|
||||
|
@ -303,7 +301,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function disconnect_cohort
|
||||
*/
|
||||
public static function disconnect_cohort_parameters() : \external_function_parameters {
|
||||
public static function disconnect_cohort_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan', VALUE_OPTIONAL),
|
||||
"cohort_id" => new \external_value(PARAM_INT, 'id of cohort to link', VALUE_OPTIONAL),
|
||||
|
@ -313,7 +311,7 @@ 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'),
|
||||
|
@ -350,7 +348,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function connect_user
|
||||
*/
|
||||
public static function connect_user_parameters() : \external_function_parameters {
|
||||
public static function connect_user_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan', VALUE_OPTIONAL),
|
||||
"user_id" => new \external_value(PARAM_INT, 'id of user to link', VALUE_OPTIONAL),
|
||||
|
@ -360,7 +358,7 @@ 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'),
|
||||
|
@ -396,7 +394,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function disconnect_user
|
||||
*/
|
||||
public static function disconnect_user_parameters() : \external_function_parameters {
|
||||
public static function disconnect_user_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan', VALUE_OPTIONAL),
|
||||
"user_id" => new \external_value(PARAM_INT, 'id of user to link', VALUE_OPTIONAL),
|
||||
|
@ -406,7 +404,7 @@ 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'),
|
||||
|
@ -441,7 +439,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function associated_users
|
||||
*/
|
||||
public static function associated_users_parameters() : \external_function_parameters {
|
||||
public static function associated_users_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan', VALUE_OPTIONAL),
|
||||
] );
|
||||
|
@ -450,7 +448,7 @@ 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());
|
||||
}
|
||||
|
||||
|
@ -481,7 +479,7 @@ class associationservice extends \external_api {
|
|||
$users = [];
|
||||
foreach ($rs as $u) {
|
||||
$user = self::make_user_model($u);
|
||||
$user["lastaccess"] = self::user_lastaccess($u->id,$studyplanid);
|
||||
$user["lastaccess"] = self::user_lastaccess($u->id, $studyplanid);
|
||||
$users[] = $user;
|
||||
|
||||
}
|
||||
|
@ -493,7 +491,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function associated_cohorts
|
||||
*/
|
||||
public static function associated_cohorts_parameters() : \external_function_parameters {
|
||||
public static function associated_cohorts_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan', VALUE_OPTIONAL),
|
||||
] );
|
||||
|
@ -502,7 +500,7 @@ 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());
|
||||
}
|
||||
|
||||
|
@ -530,7 +528,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function all_associated
|
||||
*/
|
||||
public static function all_associated_parameters() : \external_function_parameters {
|
||||
public static function all_associated_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan', VALUE_OPTIONAL),
|
||||
] );
|
||||
|
@ -539,7 +537,7 @@ 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());
|
||||
}
|
||||
|
||||
|
@ -577,10 +575,10 @@ class associationservice extends \external_api {
|
|||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parameter description for webservice function all_associated
|
||||
*/
|
||||
public static function all_associated_grouped_parameters() : \external_function_parameters {
|
||||
public static function all_associated_grouped_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan', VALUE_OPTIONAL),
|
||||
] );
|
||||
|
@ -589,10 +587,10 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function all_associated
|
||||
*/
|
||||
public static function all_associated_grouped_returns() : \external_description {
|
||||
public static function all_associated_grouped_returns(): \external_description {
|
||||
return new \external_multiple_structure(new \external_single_structure([
|
||||
'id' => new \external_value(PARAM_INT, 'id of group'),
|
||||
'label' => new \external_value(PARAM_TEXT,'group label'),
|
||||
'label' => new \external_value(PARAM_TEXT, 'group label'),
|
||||
'users' => new \external_multiple_structure(self::user_structure()),
|
||||
]));
|
||||
}
|
||||
|
@ -615,9 +613,9 @@ class associationservice extends \external_api {
|
|||
$userlist = [
|
||||
[
|
||||
'id' => 0,
|
||||
'label' => get_string("individuals",'local_treestudyplan'),
|
||||
'label' => get_string("individuals", 'local_treestudyplan'),
|
||||
'users' => self::associated_users($studyplanid),
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
$sql = "SELECT DISTINCT c.* FROM {cohort} c INNER JOIN {local_treestudyplan_cohort} j ON j.cohort_id = c.id
|
||||
|
@ -634,7 +632,7 @@ class associationservice extends \external_api {
|
|||
|
||||
foreach ($rs as $u) {
|
||||
$user = self::make_user_model($u);
|
||||
$user["lastaccess"] = self::user_lastaccess($u->id,$studyplanid);
|
||||
$user["lastaccess"] = self::user_lastaccess($u->id, $studyplanid);
|
||||
$users[] = $user;
|
||||
}
|
||||
$rs->close();
|
||||
|
@ -650,7 +648,6 @@ class associationservice extends \external_api {
|
|||
return $userlist;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sort a list of user models by firstname->lastname
|
||||
* @param array $list Reference to list of user models
|
||||
|
@ -676,7 +673,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function cascade_cohortsync
|
||||
*/
|
||||
public static function cascade_cohortsync_parameters() : \external_function_parameters {
|
||||
public static function cascade_cohortsync_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan', VALUE_OPTIONAL),
|
||||
] );
|
||||
|
@ -685,7 +682,7 @@ 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();
|
||||
}
|
||||
|
||||
|
@ -705,11 +702,10 @@ class associationservice extends \external_api {
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parameter description for webservice function connect_user
|
||||
*/
|
||||
public static function connect_coach_parameters() : \external_function_parameters {
|
||||
public static function connect_coach_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan', VALUE_OPTIONAL),
|
||||
"user_id" => new \external_value(PARAM_INT, 'id of user to link', VALUE_OPTIONAL),
|
||||
|
@ -719,7 +715,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function connect_user
|
||||
*/
|
||||
public static function connect_coach_returns() : \external_description {
|
||||
public static function connect_coach_returns(): \external_description {
|
||||
return new \external_single_structure([
|
||||
"success" => new \external_value(PARAM_BOOL, 'operation completed succesfully'),
|
||||
"msg" => new \external_value(PARAM_TEXT, 'message'),
|
||||
|
@ -738,8 +734,8 @@ class associationservice extends \external_api {
|
|||
$studyplan = studyplan::find_by_id($studyplanid);
|
||||
webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context());
|
||||
|
||||
$user = $DB->get_record("user",["id" => $userid]);
|
||||
if( has_capability(self::CAP_COACH,$studyplan->context(),$user)) {
|
||||
$user = $DB->get_record("user", ["id" => $userid]);
|
||||
if ( has_capability(self::CAP_COACH, $studyplan->context(), $user)) {
|
||||
if (!$DB->record_exists('local_treestudyplan_coach', ['studyplan_id' => $studyplanid, 'user_id' => $userid])) {
|
||||
$id = $DB->insert_record('local_treestudyplan_coach', [
|
||||
'studyplan_id' => $studyplanid,
|
||||
|
@ -759,7 +755,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function disconnect_user
|
||||
*/
|
||||
public static function disconnect_coach_parameters() : \external_function_parameters {
|
||||
public static function disconnect_coach_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan', VALUE_OPTIONAL),
|
||||
"user_id" => new \external_value(PARAM_INT, 'id of user to link', VALUE_OPTIONAL),
|
||||
|
@ -769,7 +765,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function disconnect_user
|
||||
*/
|
||||
public static function disconnect_coach_returns() : \external_description {
|
||||
public static function disconnect_coach_returns(): \external_description {
|
||||
return new \external_single_structure([
|
||||
"success" => new \external_value(PARAM_BOOL, 'operation completed succesfully'),
|
||||
"msg" => new \external_value(PARAM_TEXT, 'message'),
|
||||
|
@ -793,18 +789,16 @@ class associationservice extends \external_api {
|
|||
'user_id' => $userid,
|
||||
]);
|
||||
|
||||
|
||||
return ['success' => true, 'msg' => 'User Disconnected as coach'];
|
||||
} else {
|
||||
return ['success' => true, 'msg' => 'Connection does not exist'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Parameter description for webservice function find_user
|
||||
*/
|
||||
public static function find_coach_parameters() : \external_function_parameters {
|
||||
public static function find_coach_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
'like' => new \external_value(PARAM_TEXT, 'search text'),
|
||||
'studyplan_id' => new \external_value(PARAM_INT, 'studyplan id to associate for', VALUE_OPTIONAL),
|
||||
|
@ -814,7 +808,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function find_user
|
||||
*/
|
||||
public static function find_coach_returns() : \external_description {
|
||||
public static function find_coach_returns(): \external_description {
|
||||
return new \external_multiple_structure(self::user_structure());
|
||||
}
|
||||
|
||||
|
@ -825,12 +819,11 @@ class associationservice extends \external_api {
|
|||
* @param int $contextid Context to search (default system)
|
||||
* @return array
|
||||
*/
|
||||
public static function find_coach($like, $studyplan_id) {
|
||||
public static function find_coach($like, $studyplanid) {
|
||||
global $CFG, $DB;
|
||||
|
||||
|
||||
// Only allow this if the user has the right to edit in this context.
|
||||
$studyplan = studyplan::find_by_id($studyplan_id);
|
||||
$studyplan = studyplan::find_by_id($studyplanid);
|
||||
$context = $studyplan->context();
|
||||
webservicehelper::require_capabilities(self::CAP_EDIT, $context);
|
||||
|
||||
|
@ -849,7 +842,7 @@ class associationservice extends \external_api {
|
|||
$users = [];
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
foreach ($rs as $r) {
|
||||
if (has_capability(self::CAP_COACH,$context,$r)) {
|
||||
if (has_capability(self::CAP_COACH, $context, $r)) {
|
||||
$users[] = static::make_user_model($r);
|
||||
}
|
||||
}
|
||||
|
@ -861,7 +854,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function associated_users
|
||||
*/
|
||||
public static function associated_coaches_parameters() : \external_function_parameters {
|
||||
public static function associated_coaches_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan', VALUE_OPTIONAL),
|
||||
] );
|
||||
|
@ -870,7 +863,7 @@ class associationservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function associated_users
|
||||
*/
|
||||
public static function associated_coaches_returns() : \external_description {
|
||||
public static function associated_coaches_returns(): \external_description {
|
||||
return new \external_multiple_structure(self::user_structure());
|
||||
}
|
||||
|
||||
|
|
|
@ -97,15 +97,14 @@ class badgeinfo {
|
|||
*/
|
||||
public static function exists($id) {
|
||||
global $DB;
|
||||
return is_numeric($id) && $DB->record_exists('badge', array('id' => $id));
|
||||
return is_numeric($id) && $DB->record_exists('badge', ['id' => $id]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Webservice structure for editor info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function simple_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function simple_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of badge'),
|
||||
"infolink" => new \external_value(PARAM_RAW, 'badge issue information link', VALUE_OPTIONAL),
|
||||
|
@ -147,7 +146,7 @@ class badgeinfo {
|
|||
* Webservice structure for editor info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function editor_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function editor_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of badge'),
|
||||
"infolink" => new \external_value(PARAM_RAW, 'badge issue information link', VALUE_OPTIONAL),
|
||||
|
@ -209,7 +208,7 @@ class badgeinfo {
|
|||
* Webservice structure for userinfo
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function user_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function user_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of badge'),
|
||||
"infolink" => new \external_value(PARAM_TEXT, 'badge issue information link', VALUE_OPTIONAL),
|
||||
|
@ -258,9 +257,8 @@ class badgeinfo {
|
|||
"active" => $this->badge->is_active(),
|
||||
];
|
||||
|
||||
|
||||
if ($issued) {
|
||||
$issueinfo = $DB->get_record('badge_issued', array('badgeid' => $this->badge->id, 'userid' => $userid));
|
||||
$issueinfo = $DB->get_record('badge_issued', ['badgeid' => $this->badge->id, 'userid' => $userid]);
|
||||
$badge['dateissued'] = date("Y-m-d", $issueinfo->dateissued);
|
||||
if ($issueinfo->expiredate) {
|
||||
$badge['dateexpire'] = date("Y-m-d", $issueinfo->dateexpire);
|
||||
|
@ -272,48 +270,47 @@ class badgeinfo {
|
|||
return $badge;
|
||||
}
|
||||
|
||||
|
||||
protected static function badge_completion_structure($value) {
|
||||
return new \external_single_structure([
|
||||
"types" => new \external_multiple_structure(new \external_single_structure([
|
||||
'criteria' => new \external_multiple_structure(new \external_single_structure([
|
||||
"title" => new \external_value(PARAM_RAW, 'criterion title'),
|
||||
"description" => new \external_value(PARAM_RAW, 'criterion description'),
|
||||
"link"=> new \external_value(PARAM_RAW, 'link to criterion resource',VALUE_OPTIONAL),
|
||||
"link"=> new \external_value(PARAM_RAW, 'link to criterion resource', VALUE_OPTIONAL),
|
||||
"requirements" => new \external_multiple_structure(new \external_single_structure([
|
||||
"title" => new \external_value(PARAM_RAW, 'requirment title'),
|
||||
"completed" => new \external_value(PARAM_BOOL, 'criterion is completed or not', VALUE_OPTIONAL),
|
||||
]), "criterion specific requirements", VALUE_OPTIONAL),
|
||||
"completed" => new \external_value(PARAM_BOOL, 'criterion is completed or not'),
|
||||
]),'specific criteria'),
|
||||
]), 'specific criteria'),
|
||||
"title" => new \external_value(PARAM_RAW, 'type title'),
|
||||
"aggregation" => new \external_value(PARAM_TEXT, 'any|all'),
|
||||
"count" => new \external_value(PARAM_INT, 'effective number of critera for type progress'),
|
||||
"progress" => new \external_value(PARAM_INT, 'effective number of completed criteria for type progress'),
|
||||
"fraction" => new \external_value(PARAM_FLOAT, 'fraction of completed type criteria as float'),
|
||||
]), "criteria types",VALUE_OPTIONAL),
|
||||
]), "criteria types", VALUE_OPTIONAL),
|
||||
"aggregation" => new \external_value(PARAM_TEXT, 'any|all'),
|
||||
"count" => new \external_value(PARAM_INT, 'total number of critera for progress'),
|
||||
"progress" => new \external_value(PARAM_INT, 'number of completed criteria for progress'),
|
||||
"fraction" => new \external_value(PARAM_FLOAT, 'fraction of completed criteria as float'),
|
||||
"title" => new \external_value(PARAM_RAW, 'completion title'),
|
||||
],'badge completion information', $value);
|
||||
], 'badge completion information', $value);
|
||||
}
|
||||
|
||||
protected function badge_completion_data($userid) : array {
|
||||
protected function badge_completion_data($userid): array {
|
||||
|
||||
$count = 0;
|
||||
$progress = 0;
|
||||
$fraction = 0;
|
||||
|
||||
|
||||
$badgeagg = $this->badge->get_aggregation_method();
|
||||
$types = [];
|
||||
|
||||
foreach ($this->badge->criteria as $type => $bc) {
|
||||
if ($type != BADGE_CRITERIA_TYPE_OVERALL) {
|
||||
$typeagg = $this->badge->get_aggregation_method($type);
|
||||
$typecrit = $this->get_award_subcriteria($bc,$userid);
|
||||
|
||||
$typecrit = $this->get_award_subcriteria($bc, $userid);
|
||||
|
||||
$typecount = count($typecrit);
|
||||
$typeprogress = 0;
|
||||
foreach ($typecrit as $subcrit) {
|
||||
|
@ -330,10 +327,10 @@ class badgeinfo {
|
|||
}
|
||||
|
||||
// Determine how to patch this data into the overall progress numbers, depending on the OVERALL aggregation.
|
||||
if($badgeagg == BADGE_CRITERIA_AGGREGATION_ANY) {
|
||||
if ($badgeagg == BADGE_CRITERIA_AGGREGATION_ANY) {
|
||||
/* If ANY completion overall, count only the criteria type with the highest completion percentage -.
|
||||
Overwrite data if current type is more complete */
|
||||
$typefraction = ($typecount > 0)?($typeprogress / $typecount):0;
|
||||
$typefraction = ($typecount > 0) ? ($typeprogress / $typecount):0;
|
||||
if ($typefraction > $fraction || ($fraction == 0 && $typecount > $count)) {
|
||||
$fraction = $typefraction;
|
||||
$count = $typecount;
|
||||
|
@ -345,10 +342,10 @@ class badgeinfo {
|
|||
$progress += $typeprogress;
|
||||
}
|
||||
|
||||
$aggrgation_handle = ($typeagg == BADGE_CRITERIA_AGGREGATION_ALL)?"all":"any";
|
||||
$aggrgationhandle = ($typeagg == BADGE_CRITERIA_AGGREGATION_ALL)?"all":"any";
|
||||
$typeinfo = [
|
||||
'title' => ucfirst(get_string("criteria_descr_$type","badges", get_string($aggrgation_handle,"core"))),
|
||||
'aggregation' => $aggrgation_handle,
|
||||
'title' => ucfirst(get_string("criteria_descr_$type", "badges", get_string($aggrgationhandle, "core"))),
|
||||
'aggregation' => $aggrgationhandle,
|
||||
'criteria' => $typecrit,
|
||||
'count' => $typecount,
|
||||
'progress' => $typeprogress,
|
||||
|
@ -358,11 +355,11 @@ class badgeinfo {
|
|||
}
|
||||
}
|
||||
|
||||
$aggrgation_handle = ($badgeagg == BADGE_CRITERIA_AGGREGATION_ALL)?"all":"any";
|
||||
$aggrgationhandle = ($badgeagg == BADGE_CRITERIA_AGGREGATION_ALL)?"all":"any";
|
||||
return [
|
||||
"types" => $types,
|
||||
"title" => ucfirst(get_string("criteria_descr_0","badges", mb_strtolower(get_string($aggrgation_handle,"core")))),
|
||||
"aggregation" => $aggrgation_handle,
|
||||
"title" => ucfirst(get_string("criteria_descr_0", "badges", mb_strtolower(get_string($aggrgationhandle, "core")))),
|
||||
"aggregation" => $aggrgationhandle,
|
||||
"count" => $count,
|
||||
"progress" => $progress,
|
||||
"fraction" => $fraction,
|
||||
|
@ -386,7 +383,6 @@ class badgeinfo {
|
|||
return $issuecount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets the module instance from the database and returns it.
|
||||
|
@ -400,7 +396,7 @@ class badgeinfo {
|
|||
FROM {course_modules} cm,
|
||||
{modules} md
|
||||
WHERE cm.id = ? AND
|
||||
md.id = cm.module", array($cmid));
|
||||
md.id = cm.module", [$cmid]);
|
||||
|
||||
if ($rec) {
|
||||
return get_coursemodule_from_id($rec->name, $cmid);
|
||||
|
@ -417,7 +413,7 @@ class badgeinfo {
|
|||
*/
|
||||
private static function get_role_name($rid) {
|
||||
global $DB, $PAGE;
|
||||
$rec = $DB->get_record('role', array('id' => $rid));
|
||||
$rec = $DB->get_record('role', ['id' => $rid]);
|
||||
|
||||
if ($rec) {
|
||||
return role_get_name($rec, \context_system::instance(), ROLENAME_BOTH);
|
||||
|
@ -430,18 +426,18 @@ class badgeinfo {
|
|||
* [Description for get_award_subcriteria]
|
||||
*
|
||||
* @param award_criteria $crit
|
||||
*
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*
|
||||
*/
|
||||
protected function get_award_subcriteria(award_criteria $crit, $userid = null) : array {
|
||||
protected function get_award_subcriteria(award_criteria $crit, $userid = null): array {
|
||||
global $DB, $CFG;
|
||||
$list = [];
|
||||
|
||||
if ($crit->criteriatype == BADGE_CRITERIA_TYPE_ACTIVITY) {
|
||||
foreach ($crit->params as $p) {
|
||||
$mod = self::get_mod_instance($p["module"]);
|
||||
if(!$mod) {
|
||||
if (!$mod) {
|
||||
$title = get_string('error:nosuchmod', 'badges');
|
||||
$description = get_string('error:nosuchmod', 'badges');
|
||||
} else {
|
||||
|
@ -457,9 +453,9 @@ class badgeinfo {
|
|||
"description" => $description,
|
||||
"requirements" => [
|
||||
'completion' => [
|
||||
'title' => get_string('completeactivity','core').
|
||||
'title' => get_string('completeactivity', 'core').
|
||||
get_string('modulename', $mod->modname) . ' - ' . $mod->name,
|
||||
]
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
|
@ -469,7 +465,7 @@ class badgeinfo {
|
|||
];
|
||||
}
|
||||
|
||||
if(isset($userid)) {
|
||||
if (isset($userid)) {
|
||||
$info = new \completion_info($crit->course);
|
||||
$cm = new \stdClass();
|
||||
$cm->id = $p['module'];
|
||||
|
@ -482,27 +478,27 @@ class badgeinfo {
|
|||
// Any grade is required. Issue a badge even when state is COMPLETION_COMPLETE_FAIL.
|
||||
$completionstates = [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS, COMPLETION_COMPLETE_FAIL];
|
||||
}
|
||||
|
||||
|
||||
$modcompleted = in_array($data->completionstate, $completionstates);
|
||||
|
||||
$subcrit["requirements"]["completion"]["completed"] = $modcompleted;
|
||||
|
||||
$check_date = true;
|
||||
$checkdate = true;
|
||||
if (isset($p["bydate"])) {
|
||||
$date = $data->timemodified;
|
||||
$check_date = ($date <= $p['bydate']);
|
||||
$subcrit["requirements"]["bydate"]["completed"] = $check_date;
|
||||
$checkdate = ($date <= $p['bydate']);
|
||||
$subcrit["requirements"]["bydate"]["completed"] = $checkdate;
|
||||
}
|
||||
|
||||
$subcrit["completed"] = $modcompleted && $check_date;
|
||||
|
||||
$subcrit["completed"] = $modcompleted && $checkdate;
|
||||
}
|
||||
$list[] = $subcrit;
|
||||
}
|
||||
} else if ($crit->criteriatype == BADGE_CRITERIA_TYPE_MANUAL) {
|
||||
foreach ($crit->params as $p) {
|
||||
$role = self::get_role_name($p['role']);
|
||||
|
||||
if(!$role) {
|
||||
|
||||
if (!$role) {
|
||||
$title = get_string('error:nosuchrole', 'badges');
|
||||
$description = get_string('error:nosuchrole', 'badges');
|
||||
} else {
|
||||
|
@ -513,11 +509,11 @@ class badgeinfo {
|
|||
$subcrit = [
|
||||
"title" => $title,
|
||||
"description" => $description,
|
||||
"requirements" => []
|
||||
"requirements" => [],
|
||||
];
|
||||
|
||||
if(isset($userid)) {
|
||||
$crit = $DB->get_record('badge_manual_award', array('issuerrole' => $p['role'], 'recipientid' => $userid, 'badgeid' => $crit->badgeid));
|
||||
if (isset($userid)) {
|
||||
$crit = $DB->get_record('badge_manual_award', ['issuerrole' => $p['role'], 'recipientid' => $userid, 'badgeid' => $crit->badgeid]);
|
||||
$subcrit["completed"] = $crit !== false;
|
||||
}
|
||||
$list[] = $subcrit;
|
||||
|
@ -533,8 +529,8 @@ class badgeinfo {
|
|||
|
||||
foreach ($params as $p) {
|
||||
$course = get_course($p["course"]);
|
||||
if(!$course) {
|
||||
$description = get_string('error:nosuchcourse',"badges");
|
||||
if (!$course) {
|
||||
$description = get_string('error:nosuchcourse', "badges");
|
||||
} else {
|
||||
$description = \html_writer::tag('b', '"' . $course->fullname . '"');
|
||||
if (isset($p['bydate'])) {
|
||||
|
@ -547,18 +543,18 @@ class badgeinfo {
|
|||
|
||||
$subcrit = [
|
||||
"title" => $course->fullname,
|
||||
"link" => (new moodle_url($CFG->wwwroot."/course/view.php",["id" => $course->id]))->out(),
|
||||
"link" => (new moodle_url($CFG->wwwroot."/course/view.php", ["id" => $course->id]))->out(),
|
||||
"description" => $description,
|
||||
"requirements" => [
|
||||
'completion' => [
|
||||
'title' => get_string('coursecompleted','completion'),
|
||||
]
|
||||
'title' => get_string('coursecompleted', 'completion'),
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
if (isset($p["grade"])) {
|
||||
$subcrit["requirements"]["grade"] = [
|
||||
'title' => get_string('criteria_descr_grade','badges',$p["grade"]),
|
||||
'title' => get_string('criteria_descr_grade', 'badges', $p["grade"]),
|
||||
|
||||
];
|
||||
}
|
||||
|
@ -568,24 +564,24 @@ class badgeinfo {
|
|||
];
|
||||
}
|
||||
|
||||
if(isset($userid)) {
|
||||
if (isset($userid)) {
|
||||
$coursecompletion = new \completion_completion(["userid" => $userid, "course" => $course->id]);
|
||||
$coursecompleted = $coursecompletion->is_complete();
|
||||
$subcrit["requirements"]["completion"]["completed"] = (bool) $coursecompleted;
|
||||
|
||||
$check_grade = true;
|
||||
$checkgrade = true;
|
||||
if (isset($p["grade"])) {
|
||||
$grade = \grade_get_course_grade($userid,$course->id);
|
||||
$check_grade = ($grade->grade >= $p['grade']);
|
||||
$subcrit["requirements"]["grade"]["completed"] = (bool) $check_grade;
|
||||
$grade = \grade_get_course_grade($userid, $course->id);
|
||||
$checkgrade = ($grade->grade >= $p['grade']);
|
||||
$subcrit["requirements"]["grade"]["completed"] = (bool) $checkgrade;
|
||||
}
|
||||
$check_date = true;
|
||||
$checkdate = true;
|
||||
if (isset($p["bydate"])) {
|
||||
$check_date = ((bool) $coursecompletion->timecompleted) && ($coursecompletion->timecompleted <= $p["bydate"]);
|
||||
$subcrit["requirements"]["bydate"]["completed"] = (bool) $check_date;
|
||||
$checkdate = ((bool) $coursecompletion->timecompleted) && ($coursecompletion->timecompleted <= $p["bydate"]);
|
||||
$subcrit["requirements"]["bydate"]["completed"] = (bool) $checkdate;
|
||||
}
|
||||
|
||||
$subcrit["completed"] = $coursecompleted && $check_grade && $check_date;
|
||||
|
||||
$subcrit["completed"] = $coursecompleted && $checkgrade && $checkdate;
|
||||
}
|
||||
$list[] = $subcrit;
|
||||
}
|
||||
|
@ -596,12 +592,12 @@ class badgeinfo {
|
|||
$fields = profile_get_custom_fields();
|
||||
// Get formatted field name if such field exists.
|
||||
$fieldname = isset($fields[$p['field']]->name) ?
|
||||
format_string($fields[$p['field']]->name) : null;
|
||||
format_string($fields[$p['field']]->name): null;
|
||||
} else {
|
||||
$fieldname = \core_user\fields::get_display_name($p['field']);
|
||||
}
|
||||
|
||||
if(!$fieldname) {
|
||||
if (!$fieldname) {
|
||||
$title = get_string('error:nosuchfield', 'badges');
|
||||
$description = get_string('error:nosuchfield', 'badges');
|
||||
} else {
|
||||
|
@ -612,10 +608,10 @@ class badgeinfo {
|
|||
$subcrit = [
|
||||
"title" => $title,
|
||||
"description" => $description,
|
||||
"requirements" => []
|
||||
"requirements" => [],
|
||||
];
|
||||
|
||||
if(isset($userid)) {
|
||||
if (isset($userid)) {
|
||||
$join = '';
|
||||
$where = '';
|
||||
$sqlparams = [ 'userid'=> $userid];
|
||||
|
@ -643,8 +639,8 @@ class badgeinfo {
|
|||
}
|
||||
} else if ($crit->criteriatype == BADGE_CRITERIA_TYPE_BADGE) {
|
||||
foreach ($crit->params as $p) {
|
||||
$badgename = $DB->get_field('badge', 'name', array('id' => $p['badge']));
|
||||
if(!$badgename) {
|
||||
$badgename = $DB->get_field('badge', 'name', ['id' => $p['badge']]);
|
||||
if (!$badgename) {
|
||||
$title = get_string('error:nosuchbadge', 'badges');
|
||||
$description = get_string('error:nosuchbadge', 'badges');
|
||||
} else {
|
||||
|
@ -655,15 +651,15 @@ class badgeinfo {
|
|||
$subcrit = [
|
||||
"title" => $title,
|
||||
"description" => $description,
|
||||
"link" => (new \moodle_url($CFG->wwwroot."/badges/overview.php",["id" => $p["badge"]]))->out(),
|
||||
"requirements" => []
|
||||
"link" => (new \moodle_url($CFG->wwwroot."/badges/overview.php", ["id" => $p["badge"]]))->out(),
|
||||
"requirements" => [],
|
||||
];
|
||||
|
||||
if(isset($userid)) {
|
||||
$badge = $DB->get_record('badge', array('id' => $p['badge']));
|
||||
if (isset($userid)) {
|
||||
$badge = $DB->get_record('badge', ['id' => $p['badge']]);
|
||||
// See if the user has earned this badge.
|
||||
if($badge) {
|
||||
$awarded = $DB->get_record('badge_issued', array('badgeid' => $p['badge'], 'userid' => $userid));
|
||||
if ($badge) {
|
||||
$awarded = $DB->get_record('badge_issued', ['badgeid' => $p['badge'], 'userid' => $userid]);
|
||||
$awarded = isset($awarded);
|
||||
} else {
|
||||
$awarded = false;
|
||||
|
@ -674,8 +670,8 @@ class badgeinfo {
|
|||
}
|
||||
} else if ($crit->criteriatype == BADGE_CRITERIA_TYPE_COHORT) {
|
||||
foreach ($crit->params as $p) {
|
||||
$cohortname = $DB->get_field('cohort', 'name', array('id' => $p['cohort']));
|
||||
if(!$cohortname) {
|
||||
$cohortname = $DB->get_field('cohort', 'name', ['id' => $p['cohort']]);
|
||||
if (!$cohortname) {
|
||||
$title = get_string('error:nosuchcohort', 'badges');
|
||||
$description = get_string('error:nosuchcohort', 'badges');
|
||||
} else {
|
||||
|
@ -686,11 +682,11 @@ class badgeinfo {
|
|||
$subcrit = [
|
||||
"title" => $title,
|
||||
"description" => $description,
|
||||
"requirements" => []
|
||||
"requirements" => [],
|
||||
];
|
||||
|
||||
if(isset($userid)) {
|
||||
$cohort = $DB->get_record('cohort', array('id' => $p['cohort']));
|
||||
if (isset($userid)) {
|
||||
$cohort = $DB->get_record('cohort', ['id' => $p['cohort']]);
|
||||
$ismember = (bool) \cohort_is_member($cohort->id, $userid);
|
||||
$subcrit["completed"] = $ismember;
|
||||
}
|
||||
|
@ -700,11 +696,11 @@ class badgeinfo {
|
|||
foreach ($crit->params as $p) {
|
||||
$competency = new \core_competency\competency($p['competency']);
|
||||
$competency->set('description', ''); // Will use 'short' description.
|
||||
|
||||
|
||||
/* Below must be one of the most convoluted ways of calling tool_lp_render_competency_summary.
|
||||
Since I'm pretty sure it's not an actually good idea to implement <plugin>_render_competency_summary
|
||||
Since I'm pretty sure it's not an actually good idea to implement <plugin>_render_competency_summary
|
||||
in a custom plugin, even though the system appearently allows you to add competency descriptions,
|
||||
it's probably a case of premature optimization. Still, since this is the way that
|
||||
it's probably a case of premature optimization. Still, since this is the way that
|
||||
'badges/criteria/award_criteria_competency.php does it, we'll copy its example, to avoid
|
||||
differences in display....
|
||||
*/
|
||||
|
@ -720,34 +716,34 @@ class badgeinfo {
|
|||
}
|
||||
\core_competency\api::check_enabled();
|
||||
|
||||
if(count($output) < 1) {
|
||||
if (count($output) < 1) {
|
||||
$title = get_string('error:nosuchcompetency', 'local_treestudyplan');
|
||||
$description = get_string('error:nosuchcompetency', 'local_treestudyplan');
|
||||
} else {
|
||||
/* Might as wel implode the output, just in case someone was actually stupid enough to implement
|
||||
/* Might as wel implode the output, just in case someone was actually stupid enough to implement
|
||||
<plugin>_render_competency_summary in a custom plugin...
|
||||
*/
|
||||
$title = implode(" ",$output);
|
||||
$description = implode(" ",$output);
|
||||
$title = implode(" ", $output);
|
||||
$description = implode(" ", $output);
|
||||
}
|
||||
|
||||
$subcrit = [
|
||||
"title" => $title,
|
||||
"description" => $description,
|
||||
"requirements" => []
|
||||
"requirements" => [],
|
||||
];
|
||||
|
||||
if(isset($userid)) {
|
||||
if (isset($userid)) {
|
||||
/* Slightly modified from award_criteria_competency.php::review()
|
||||
to use criteria api class instead of direct calls....
|
||||
*/
|
||||
$proficiency = false;
|
||||
$badge = $DB->get_record('badge', array('id' => $crit->badgeid));
|
||||
$badge = $DB->get_record('badge', ['id' => $crit->badgeid]);
|
||||
if ($badge->type == BADGE_TYPE_SITE) {
|
||||
$uc = \core_competency\api::get_user_competency($userid,$p['competency']);
|
||||
$uc = \core_competency\api::get_user_competency($userid, $p['competency']);
|
||||
$proficiency = $uc->get('proficiency');
|
||||
} else if ($badge->type == BADGE_TYPE_COURSE) {
|
||||
$uc = \core_competency\api::get_user_competency_in_course($badge->courseid,$userid,$p['competency']);
|
||||
$uc = \core_competency\api::get_user_competency_in_course($badge->courseid, $userid, $p['competency']);
|
||||
$proficiency = $uc->get('proficiency');
|
||||
}
|
||||
|
||||
|
@ -755,7 +751,7 @@ class badgeinfo {
|
|||
}
|
||||
$list[] = $subcrit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
@ -767,17 +763,17 @@ class badgeinfo {
|
|||
* @param bool $active Only list active badges
|
||||
* @return array of int
|
||||
*/
|
||||
public static function find_badges_by_course_relation($course,$search='', $active=false) {
|
||||
public static function find_badges_by_course_relation($course, $search='', $active=false) {
|
||||
global $DB;
|
||||
if (is_int($course)) {
|
||||
$courseid = $course;
|
||||
} else if(is_object($course)) {
|
||||
} else if (is_object($course)) {
|
||||
$courseid = $course->id;
|
||||
} else {
|
||||
throw new \moodle_exception("\$course argument must be course id or course object","local_treestudyplan");
|
||||
throw new \moodle_exception("\$course argument must be course id or course object", "local_treestudyplan");
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
$crit->citeriatype = BADGE_CRITERIA_TYPE_COURSE
|
||||
$badge->params[0] = ["course"=> $courseid]
|
||||
$crit->citeriatype = BADGE_CRITERIA_TYPE_COURSESET
|
||||
|
@ -793,41 +789,38 @@ class badgeinfo {
|
|||
$basesqlparams = ['courseid' => $courseid];
|
||||
|
||||
if (strlen($search) > 0) {
|
||||
$conditions .= " AND ".$DB->sql_like('b.name',':search');
|
||||
$conditions .= " AND ".$DB->sql_like('b.name', ':search');
|
||||
$basesqlparams["search"] = "%$search%";
|
||||
}
|
||||
if ($active) {
|
||||
[$insql, $inparams] = $DB->get_in_or_equal([BADGE_STATUS_ACTIVE, BADGE_STATUS_ACTIVE_LOCKED],SQL_PARAMS_NAMED);
|
||||
[$insql, $inparams] = $DB->get_in_or_equal([BADGE_STATUS_ACTIVE, BADGE_STATUS_ACTIVE_LOCKED], SQL_PARAMS_NAMED);
|
||||
$conditions .= " AND b.status $insql";
|
||||
$basesqlparams = array_merge($basesqlparams,$inparams);
|
||||
$basesqlparams = array_merge($basesqlparams, $inparams);
|
||||
|
||||
}
|
||||
|
||||
[$ctypesql, $ctypeinparams] = $DB->get_in_or_equal([BADGE_CRITERIA_TYPE_COURSESET,BADGE_CRITERIA_TYPE_COURSE],SQL_PARAMS_NAMED);
|
||||
[$ctypesql, $ctypeinparams] = $DB->get_in_or_equal([BADGE_CRITERIA_TYPE_COURSESET, BADGE_CRITERIA_TYPE_COURSE], SQL_PARAMS_NAMED);
|
||||
$sqlparams = array_merge($basesqlparams, $ctypeinparams);
|
||||
|
||||
$sql = "SELECT DISTINCT b.id from {badge} b
|
||||
$sql = "SELECT DISTINCT b.id from {badge} b
|
||||
INNER JOIN {badge_criteria} crit ON b.id = crit.badgeid
|
||||
INNER JOIN {badge_criteria_param} p on p.critid = crit.id
|
||||
WHERE p.value = :courseid AND crit.criteriatype $ctypesql $conditions";
|
||||
|
||||
|
||||
$courserelids = $DB->get_fieldset_sql($sql, $sqlparams);
|
||||
|
||||
[$ctypesql, $ctypeinparams] = $DB->get_in_or_equal([BADGE_CRITERIA_TYPE_COMPETENCY],SQL_PARAMS_NAMED);
|
||||
$sqlparams = array_merge($basesqlparams,$ctypeinparams);
|
||||
$sql = "SELECT DISTINCT b.id from {badge} b
|
||||
[$ctypesql, $ctypeinparams] = $DB->get_in_or_equal([BADGE_CRITERIA_TYPE_COMPETENCY], SQL_PARAMS_NAMED);
|
||||
$sqlparams = array_merge($basesqlparams, $ctypeinparams);
|
||||
$sql = "SELECT DISTINCT b.id from {badge} b
|
||||
INNER JOIN {badge_criteria} crit ON b.id = crit.badgeid
|
||||
INNER JOIN {badge_criteria_param} p on p.critid = crit.id
|
||||
INNER JOIN {competency_coursecomp} cc on cc.competencyid = p.value
|
||||
WHERE cc.courseid = :courseid AND crit.criteriatype $ctypesql $conditions";
|
||||
|
||||
|
||||
$competencyrelids = $DB->get_fieldset_sql($sql,$sqlparams);
|
||||
|
||||
$competencyrelids = $DB->get_fieldset_sql($sql, $sqlparams);
|
||||
|
||||
$badgeids = [];
|
||||
foreach ([$courserelids,$competencyrelids] as $list) {
|
||||
foreach ([$courserelids, $competencyrelids] as $list) {
|
||||
foreach ($list as $id) {
|
||||
$badgeids[] = $id;
|
||||
}
|
||||
|
@ -843,38 +836,37 @@ class badgeinfo {
|
|||
* @param bool $active Only list active badges
|
||||
* @return array of int
|
||||
*/
|
||||
public static function find_course_badges($course,$search='', $active=false) {
|
||||
public static function find_course_badges($course, $search='', $active=false) {
|
||||
global $DB;
|
||||
if (is_int($course)) {
|
||||
$courseid = $course;
|
||||
} else if(is_object($course)) {
|
||||
} else if (is_object($course)) {
|
||||
$courseid = $course->id;
|
||||
} else {
|
||||
throw new \moodle_exception("\$course argument must be course id or course object","local_treestudyplan");
|
||||
throw new \moodle_exception("\$course argument must be course id or course object", "local_treestudyplan");
|
||||
}
|
||||
|
||||
|
||||
$search = trim($search);
|
||||
$conditions = "";
|
||||
$basesqlparams = ['courseid' => $courseid];
|
||||
|
||||
if (strlen($search) > 0) {
|
||||
$conditions .= " AND ".$DB->sql_like('b.name',':search');
|
||||
$conditions .= " AND ".$DB->sql_like('b.name', ':search');
|
||||
$basesqlparams["search"] = "%$search%";
|
||||
}
|
||||
if ($active) {
|
||||
[$insql, $inparams] = $DB->get_in_or_equal([BADGE_STATUS_ACTIVE, BADGE_STATUS_ACTIVE_LOCKED]);
|
||||
$conditions .= " AND b.status $insql";
|
||||
$basesqlparams = array_merge($basesqlparams,$inparams);
|
||||
$basesqlparams = array_merge($basesqlparams, $inparams);
|
||||
}
|
||||
|
||||
|
||||
// Get all course badges for this course
|
||||
$badgesids = [];
|
||||
$sql = "SELECT DISTINCT b.id from {badge} b
|
||||
$sql = "SELECT DISTINCT b.id from {badge} b
|
||||
WHERE b.courseid = :courseid AND $conditions";
|
||||
|
||||
$badgesids = $DB->get_fieldset_sql($sql,$basesqlparams);
|
||||
|
||||
$badgesids = $DB->get_fieldset_sql($sql, $basesqlparams);
|
||||
|
||||
return $badgesids;
|
||||
}
|
||||
|
||||
|
@ -885,23 +877,23 @@ class badgeinfo {
|
|||
* @param mixed $search=""
|
||||
* @param mixed $active=false
|
||||
* @param mixed $includecoursebadges=true
|
||||
*
|
||||
*
|
||||
* @return array of badgeinfo
|
||||
*
|
||||
*
|
||||
*/
|
||||
public static function find_page_related_badges(studyplanpage $page,$search="",$active=false,$includecoursebadges=true) {
|
||||
|
||||
public static function find_page_related_badges(studyplanpage $page, $search="", $active=false, $includecoursebadges=true) {
|
||||
|
||||
$badgeids = [];
|
||||
foreach (studyline::find_page_children($page) as $line) {
|
||||
foreach (studyitem::find_studyline_children($line) as $item) {
|
||||
if ($item->type() == studyitem::COURSE && $item->courseid() ) {
|
||||
$courseid = $item->courseid();
|
||||
$relatedbadges = badgeinfo::find_badges_by_course_relation($courseid,$search,$active);
|
||||
$relatedbadges = badgeinfo::find_badges_by_course_relation($courseid, $search, $active);
|
||||
foreach ($relatedbadges as $id) {
|
||||
$badgeids[] = $id;
|
||||
}
|
||||
if ($includecoursebadges) {
|
||||
$coursebadges = badgeinfo::find_course_badges($courseid,$search,$active);
|
||||
$coursebadges = badgeinfo::find_course_badges($courseid, $search, $active);
|
||||
foreach ($coursebadges as $id) {
|
||||
$badgeids[] = $id;
|
||||
}
|
||||
|
@ -914,7 +906,7 @@ class badgeinfo {
|
|||
$badges[] = new self(new badge($id));
|
||||
}
|
||||
|
||||
usort($badges,function($a,$b) {
|
||||
usort($badges, function($a, $b) {
|
||||
return $a->name() <=> $b->name();
|
||||
});
|
||||
|
||||
|
@ -929,38 +921,37 @@ class badgeinfo {
|
|||
*/
|
||||
public static function search_site_badges($search='', $active=false) {
|
||||
global $DB;
|
||||
|
||||
|
||||
$search = trim($search);
|
||||
$conditions = "TRUE";
|
||||
$basesqlparams = ['type' => \BADGE_TYPE_SITE];
|
||||
|
||||
if (strlen($search) > 0) {
|
||||
$conditions .= " AND ".$DB->sql_like('b.name',':search');
|
||||
$conditions .= " AND ".$DB->sql_like('b.name', ':search');
|
||||
$basesqlparams["search"] = "%$search%";
|
||||
}
|
||||
if ($active) {
|
||||
[$insql, $inparams] = $DB->get_in_or_equal([BADGE_STATUS_ACTIVE, BADGE_STATUS_ACTIVE_LOCKED]);
|
||||
$conditions .= " AND b.status $insql";
|
||||
$basesqlparams = array_merge($basesqlparams,$inparams);
|
||||
$basesqlparams = array_merge($basesqlparams, $inparams);
|
||||
}
|
||||
|
||||
|
||||
// Get all course badges for this course
|
||||
$sql = "SELECT DISTINCT b.id from {badge} b
|
||||
$sql = "SELECT DISTINCT b.id from {badge} b
|
||||
WHERE $conditions";
|
||||
|
||||
$badgeids = $DB->get_fieldset_sql($sql,$basesqlparams);
|
||||
|
||||
$badgeids = $DB->get_fieldset_sql($sql, $basesqlparams);
|
||||
|
||||
$badges = [];
|
||||
foreach (array_unique($badgeids) as $id) {
|
||||
$badges[] = new self(new badge($id));
|
||||
}
|
||||
|
||||
usort($badges,function($a,$b) {
|
||||
usort($badges, function($a, $b) {
|
||||
return $a->name() <=> $b->name();
|
||||
});
|
||||
|
||||
return $badges;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -92,8 +92,8 @@ class cascadecohortsync {
|
|||
require_once($CFG->dirroot.'/group/lib.php');
|
||||
|
||||
// Check to see if the group name already exists in this course.
|
||||
if ($DB->record_exists('groups', array('name' => $groupname, 'courseid' => $courseid))) {
|
||||
$group = $DB->get_record('groups', array('name' => $groupname, 'courseid' => $courseid));
|
||||
if ($DB->record_exists('groups', ['name' => $groupname, 'courseid' => $courseid])) {
|
||||
$group = $DB->get_record('groups', ['name' => $groupname, 'courseid' => $courseid]);
|
||||
return $group->id;
|
||||
}
|
||||
// The named group doesn't exist, so create a new one in the course.
|
||||
|
@ -129,7 +129,7 @@ class cascadecohortsync {
|
|||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Remove this studyplan reference from cohort sync
|
||||
* @param object $enrollinstance
|
||||
*/
|
||||
|
@ -175,17 +175,16 @@ class cascadecohortsync {
|
|||
// Find the study lines associated to this studyplan.
|
||||
$lines = $this->studyplan->get_all_studylines();
|
||||
|
||||
|
||||
foreach($lines as $line) {
|
||||
$this->syncline($line);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Enroll all cohorts associated to the studyplan in the courses linked to the specified study line
|
||||
*/
|
||||
public function syncline(studyline $line){
|
||||
public function syncline(studyline $line) {
|
||||
global $DB;
|
||||
// Find the courses that need to be synced to the associated cohorts.
|
||||
$courseids = $line->get_linked_course_ids();
|
||||
|
@ -201,7 +200,7 @@ class cascadecohortsync {
|
|||
$instanceparams = ['courseid' => $courseid, 'enrol' => 'manual'];
|
||||
if (!($instance = $DB->get_record('enrol', $instanceparams))) {
|
||||
if ($instanceid = $this->manualenrol->add_default_instance($course)) {
|
||||
$instance = $DB->get_record('enrol', array('id' => $instanceid));
|
||||
$instance = $DB->get_record('enrol', ['id' => $instanceid]);
|
||||
} else {
|
||||
// Instance not added for some reason, so report an error somewhere.
|
||||
// (or not).
|
||||
|
@ -297,7 +296,7 @@ class cascadecohortsync {
|
|||
// Also record the (as of yet only) studyplans id requiring this association.
|
||||
// In the customtext4 field in json format.
|
||||
|
||||
$instance = $DB->get_record('enrol', array('id' => $instanceid));
|
||||
$instance = $DB->get_record('enrol', ['id' => $instanceid]);
|
||||
$this->enrol->update_instance($instance, (object)["customtext4" => json_encode([(int)($this->studyplanid)])]);
|
||||
|
||||
// Successfully added a valid new instance, so now instantiate it.
|
||||
|
@ -323,7 +322,7 @@ class cascadecohortsync {
|
|||
if (get_config("local_treestudyplan", "csync_autoremove")) {
|
||||
// Only try the autoremove if the option is enabled.
|
||||
|
||||
foreach($this->list_cohortsyncs($courseid) as $instance){
|
||||
foreach($this->list_cohortsyncs($courseid) as $instance) {
|
||||
// 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.
|
||||
if (!in_array($instance->customint1, $this->cohortids)) {
|
||||
|
|
|
@ -58,7 +58,6 @@ class cascadeusersync {
|
|||
$this->userids = $this->studyplan->get_linked_user_ids();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enroll all users associated to the studyplan in the courses linked to this studyplan
|
||||
*/
|
||||
|
@ -84,33 +83,33 @@ class cascadeusersync {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Enroll all cohorts associated to the studyplan in the courses linked to the specified study line
|
||||
*/
|
||||
public function syncline(studyline $line){
|
||||
public function syncline(studyline $line) {
|
||||
// Find the courses that need to be synced to the associated cohorts.
|
||||
$courseids = $line->get_linked_course_ids();
|
||||
if ($line->enrollable()) {
|
||||
$lineuids = $line->get_enrolled_userids();
|
||||
// Next, for each course that is linked:.
|
||||
foreach ($courseids as $courseid) {
|
||||
$this->perform_enrol($courseid,$lineuids);
|
||||
$this->perform_enrol($courseid, $lineuids);
|
||||
// We do not do any autoremoval for user syncs, to avoid students losing access to the course data.
|
||||
}
|
||||
} else {
|
||||
// Next, for each course that is linked:.
|
||||
foreach ($courseids as $courseid) {
|
||||
$this->perform_enrol($courseid,$this->userids);
|
||||
$this->perform_enrol($courseid, $this->userids);
|
||||
// We do not do any autoremoval for user syncs, to avoid students losing access to the course data.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Enrol a list of users into a specific course
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
private function perform_enrol($courseid,$userids) {
|
||||
private function perform_enrol($courseid, $userids) {
|
||||
global $DB;
|
||||
$course = \get_course($courseid);
|
||||
if (count($userids) > 0) {
|
||||
|
@ -118,7 +117,7 @@ class cascadeusersync {
|
|||
$instanceparams = ['courseid' => $courseid, 'enrol' => 'manual'];
|
||||
if (!($instance = $DB->get_record('enrol', $instanceparams))) {
|
||||
if ($instanceid = $this->enrol->add_default_instance($course)) {
|
||||
$instance = $DB->get_record('enrol', array('id' => $instanceid));
|
||||
$instance = $DB->get_record('enrol', ['id' => $instanceid]);
|
||||
} else {
|
||||
// Instance not added for some reason, so report an error somewhere.
|
||||
// (or not).
|
||||
|
|
|
@ -75,7 +75,7 @@ class completion {
|
|||
* Webservice structure for basic info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_value( PARAM_TEXT,
|
||||
'completion state (failed|incomplete|pending|progress|completed|good|excellent)',
|
||||
$value);
|
||||
|
|
|
@ -69,7 +69,7 @@ class completionscanner {
|
|||
* Check if a certain activity type is supported for scanning pending results
|
||||
* @param string $mod name of activity module
|
||||
*/
|
||||
public static function supported($mod) : bool {
|
||||
public static function supported($mod): bool {
|
||||
if (!array_key_exists($mod, self::$modsupported)) {
|
||||
self::$modsupported[$mod] = class_exists("\local_treestudyplan\\local\\ungradedscanners\\{$mod}_scanner");
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ class completionscanner {
|
|||
* @param int[] $studentlist Array of student id's
|
||||
* @return int[]
|
||||
*/
|
||||
private function filter_studentlist(array $studentlist) : array {
|
||||
private function filter_studentlist(array $studentlist): array {
|
||||
$coursestudents = courseinfo::get_course_students($this->courseid);
|
||||
return array_intersect($studentlist, $coursestudents);
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ class completionscanner {
|
|||
* Check if the criteria this scanner scans has pending submissions for a specific user
|
||||
* @param int $userid ID of the user to check for
|
||||
*/
|
||||
public function pending($userid) : bool {
|
||||
public function pending($userid): bool {
|
||||
if (!array_key_exists($userid, $this->pendingcache)) {
|
||||
if ($this->scanner === null) {
|
||||
$this->pendingcache[$userid] = false;
|
||||
|
@ -145,7 +145,7 @@ class completionscanner {
|
|||
* Webservice structure for basic info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function structure($value = VALUE_OPTIONAL) : \external_description {
|
||||
public static function structure($value = VALUE_OPTIONAL): \external_description {
|
||||
return new \external_single_structure([
|
||||
"ungraded" => new \external_value(PARAM_INT, 'number of ungraded submissions'),
|
||||
"completed" => new \external_value(PARAM_INT, 'number of completed students'),
|
||||
|
@ -159,7 +159,7 @@ class completionscanner {
|
|||
* Webservice model for basic info
|
||||
* @param int[]|null $studentlist Array of student userids to use for checking. Leave empty to use all course students
|
||||
*/
|
||||
public function model(array $studentlist = null) : array {
|
||||
public function model(array $studentlist = null): array {
|
||||
/*
|
||||
If an array of students is provided (usually the case if called from a courecompletioninfo object),
|
||||
make sure to filter it out, so only the students enrolled in the course are included.. Otherwise
|
||||
|
|
|
@ -46,7 +46,7 @@ class contextinfo {
|
|||
* Describe the result for the webservice model
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"name" => new \external_value(PARAM_TEXT, 'context name'),
|
||||
"shortname" => new \external_value(PARAM_TEXT, 'context short name'),
|
||||
|
@ -61,7 +61,6 @@ class contextinfo {
|
|||
*/
|
||||
public function model() {
|
||||
|
||||
|
||||
return [
|
||||
"name" => $this->context->get_context_name(false, false),
|
||||
"shortname" => $this->context->get_context_name(false, true),
|
||||
|
@ -75,7 +74,7 @@ class contextinfo {
|
|||
* @param $short Use short names of contexts in path
|
||||
* @return array of context path names
|
||||
*/
|
||||
public function path($short=false){
|
||||
public function path($short=false) {
|
||||
if ($short) {
|
||||
return array_map(function($c) {
|
||||
return \context::instance_by_id($c)->get_context_name(false, true);
|
||||
|
@ -92,11 +91,10 @@ class contextinfo {
|
|||
* @param $short Use short names of contexts in path
|
||||
* @return string Concatenated string of paths
|
||||
*/
|
||||
public function pathstr($short=false){
|
||||
public function pathstr($short=false) {
|
||||
return implode(" / ", $this->path($short));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make new Contextinfo for context id
|
||||
* @param int $contextid Context id
|
||||
|
|
|
@ -123,7 +123,7 @@ class corecompletioninfo {
|
|||
* Webservice editor structure for completion_item
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function completion_item_editor_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function completion_item_editor_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'criteria id', VALUE_OPTIONAL),
|
||||
"title" => new \external_value(PARAM_RAW, 'name of subitem', VALUE_OPTIONAL),
|
||||
|
@ -142,7 +142,7 @@ class corecompletioninfo {
|
|||
* Webservice editor structure for completion_type
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function completion_type_editor_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function completion_type_editor_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"items" => new \external_multiple_structure(self::completion_item_editor_structure(), 'subitems', VALUE_OPTIONAL),
|
||||
"title" => new \external_value(PARAM_RAW, 'optional title', VALUE_OPTIONAL),
|
||||
|
@ -160,7 +160,7 @@ class corecompletioninfo {
|
|||
* Webservice structure for editor info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function editor_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function editor_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"conditions" => new \external_multiple_structure(self::completion_type_editor_structure(), 'completion conditions'),
|
||||
"aggregation" => new \external_value(PARAM_TEXT, 'completion aggregation ["all", "any"]'),
|
||||
|
@ -172,7 +172,7 @@ class corecompletioninfo {
|
|||
* Webservice user view structure for completion_item
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function completion_item_user_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function completion_item_user_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of completion', VALUE_OPTIONAL),
|
||||
"title" => new \external_value(PARAM_RAW, 'name of subitem', VALUE_OPTIONAL),
|
||||
|
@ -198,7 +198,7 @@ class corecompletioninfo {
|
|||
* Webservice user view structure for completion_type
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function completion_type_user_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function completion_type_user_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"items" => new \external_multiple_structure(self::completion_item_user_structure(), 'subitems', VALUE_OPTIONAL),
|
||||
"title" => new \external_value(PARAM_RAW, 'optional title', VALUE_OPTIONAL),
|
||||
|
@ -217,7 +217,7 @@ class corecompletioninfo {
|
|||
* Webservice structure for userinfo
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function user_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function user_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"progress" => new \external_value(PARAM_INT, 'completed sub-conditions'),
|
||||
"enabled" => new \external_value(PARAM_BOOL, "whether completion is enabled here"),
|
||||
|
@ -314,10 +314,10 @@ class corecompletioninfo {
|
|||
} else {
|
||||
$details['criteria'] = $cm->get_formatted_name();
|
||||
}
|
||||
// Set title based on cm formatted name
|
||||
// Set title based on cm formatted name
|
||||
$title = $cm->get_formatted_name();
|
||||
// Build requirements.
|
||||
$details['requirement'] = array();
|
||||
$details['requirement'] = [];
|
||||
|
||||
if ($cm->completion == COMPLETION_TRACKING_MANUAL) {
|
||||
$details['requirement'][] = get_string('markingyourselfcomplete', 'completion');
|
||||
|
@ -349,8 +349,8 @@ class corecompletioninfo {
|
|||
$displaytype = \grade_get_setting($this->course->id, 'displaytype', $CFG->grade_displaytype);
|
||||
$gradepass = $criteria->gradepass;
|
||||
// Find grade item for course result.
|
||||
$gi = new \grade_item(['courseid' => $this->course->id,'itemtype' => 'course']);
|
||||
$displaygrade = \grade_format_gradevalue($gradepass,$gi,true,$displaytype,1);
|
||||
$gi = new \grade_item(['courseid' => $this->course->id, 'itemtype' => 'course']);
|
||||
$displaygrade = \grade_format_gradevalue($gradepass, $gi, true, $displaytype, 1);
|
||||
$details = [
|
||||
"type" => get_string('coursegrade', 'completion'),
|
||||
"criteria" => get_string('graderequired', 'completion'),
|
||||
|
@ -359,7 +359,7 @@ class corecompletioninfo {
|
|||
.": ".$displaygrade,
|
||||
"status" => "",
|
||||
];
|
||||
$title = get_string('graderequired','completion').': '.$displaygrade;
|
||||
$title = get_string('graderequired', 'completion').': '.$displaygrade;
|
||||
|
||||
} else if ($type == COMPLETION_CRITERIA_TYPE_ROLE) {
|
||||
$details = [
|
||||
|
@ -371,7 +371,7 @@ class corecompletioninfo {
|
|||
} else if ($type == COMPLETION_CRITERIA_TYPE_COURSE) {
|
||||
$prereq = get_course($criteria->courseinstance);
|
||||
$coursecontext = \context_course::instance($prereq->id, MUST_EXIST);
|
||||
$fullname = format_string($prereq->fullname, true, array('context' => $coursecontext));
|
||||
$fullname = format_string($prereq->fullname, true, ['context' => $coursecontext]);
|
||||
$details = [
|
||||
"type" => $criteria->get_title(),
|
||||
"criteria" => '<a href="'.$CFG->wwwroot.'/course/view.php?id='.
|
||||
|
@ -394,7 +394,7 @@ class corecompletioninfo {
|
|||
// Only add the items list if we actually have items...
|
||||
$cinfo["items"][] = [
|
||||
"id" => $criteria->id,
|
||||
"title" => isset($title)?$title:$criteria->get_title_detailed(),
|
||||
"title" => isset($title) ? $title : $criteria->get_title_detailed(),
|
||||
"details" => $details,
|
||||
"progress" => $scanner->model($studentlist),
|
||||
];
|
||||
|
@ -479,7 +479,7 @@ class corecompletioninfo {
|
|||
"details" => $criteria->get_details($completion),
|
||||
"completed" => $completion->is_complete(), // Make sure to override for activi.
|
||||
"status" => self::completion_handle(
|
||||
$completion->is_complete() ? COMPLETION_COMPLETE : COMPLETION_INCOMPLETE),
|
||||
$completion->is_complete() ? COMPLETION_COMPLETE : COMPLETION_INCOMPLETE),
|
||||
];
|
||||
|
||||
if ($type == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
|
||||
|
@ -544,7 +544,7 @@ class corecompletioninfo {
|
|||
$rq = floatval($iinfo['details']['requirement']);
|
||||
$iinfo['details']['requirement'] = $this->format_course_grade($rq);
|
||||
;
|
||||
$iinfo["status"] = $completion->is_complete() ? "complete-pass" : "complete-fail";
|
||||
$iinfo["status"] = $completion->is_complete() ? "complete-pass" : "complete-fail";
|
||||
if ($cinfo["status"] == "incomplete") {
|
||||
$cinfo["status"] = "progress";
|
||||
}
|
||||
|
@ -603,7 +603,7 @@ class corecompletioninfo {
|
|||
$result = new \stdClass;
|
||||
// Check if the final grade is available and numeric (safety check).
|
||||
if (!empty($grade) && !empty($grade->finalgrade) && is_numeric($grade->finalgrade)) {
|
||||
$result->grade = \grade_format_gradevalue($grade->finalgrade,$gi,true,null,1);
|
||||
$result->grade = \grade_format_gradevalue($grade->finalgrade, $gi, true, null, 1);
|
||||
$result->feedback = \trim($grade->feedback);
|
||||
$result->pending = (new gradingscanner($gi))->pending($userid);
|
||||
} else {
|
||||
|
@ -629,7 +629,7 @@ class corecompletioninfo {
|
|||
'courseid' => $this->course->id]);
|
||||
|
||||
if ($gi) {
|
||||
return \grade_format_gradevalue($grade,$gi,true,null,1);
|
||||
return \grade_format_gradevalue($grade, $gi, true, null, 1);
|
||||
}
|
||||
|
||||
return "x"; // Course cannot be graded (Shouldn't be happening, but still....).
|
||||
|
@ -740,7 +740,7 @@ class corecompletioninfo {
|
|||
$result = new \stdClass;
|
||||
$result->count = $count;
|
||||
$result->completed = $completed;
|
||||
$result->percentage = ($count > 0) ? (($completed / $count) * 100) : 0;
|
||||
$result->percentage = ($count > 0) ? (($completed / $count) * 100): 0;
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ class coursecompetencyinfo {
|
|||
* Webservice structure for completion stats
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function completionstats_structure($value = VALUE_OPTIONAL) : \external_description {
|
||||
public static function completionstats_structure($value = VALUE_OPTIONAL): \external_description {
|
||||
return new \external_single_structure([
|
||||
"ungraded" => new \external_value(PARAM_INT, 'number of ungraded submissions'),
|
||||
"completed" => new \external_value(PARAM_INT, 'number of completed students'),
|
||||
|
@ -79,7 +79,7 @@ class coursecompetencyinfo {
|
|||
], "details about gradable submissions", $value);
|
||||
}
|
||||
|
||||
protected static function completionstats($stats){
|
||||
protected static function completionstats($stats) {
|
||||
return [
|
||||
"students" => $stats->count,
|
||||
"completed" => 0,
|
||||
|
@ -93,7 +93,7 @@ class coursecompetencyinfo {
|
|||
* Generic competency info structure for individual competency stats
|
||||
* @param $recurse True if child competencies may be included
|
||||
*/
|
||||
public static function competencyinfo_structure($recurse=true) : \external_description {
|
||||
public static function competencyinfo_structure($recurse=true): \external_description {
|
||||
$struct = [
|
||||
"id" => new \external_value(PARAM_INT, 'competency id'),
|
||||
"title" => new \external_value(PARAM_RAW, 'competency display title'),
|
||||
|
@ -106,22 +106,22 @@ class coursecompetencyinfo {
|
|||
"title" => new \external_value(PARAM_RAW),
|
||||
"type" => new \external_value(PARAM_TEXT),
|
||||
]), 'competency path'),
|
||||
'ucid' => new \external_value(PARAM_INT, 'user competencyid',VALUE_OPTIONAL),
|
||||
'ucid' => new \external_value(PARAM_INT, 'user competencyid', VALUE_OPTIONAL),
|
||||
"grade" => new \external_value(PARAM_TEXT, 'competency grade', VALUE_OPTIONAL),
|
||||
"coursegrade" => new \external_value(PARAM_TEXT, 'course competency grade', VALUE_OPTIONAL),
|
||||
"proficient" => new \external_value(PARAM_BOOL, 'competency proficiency',VALUE_OPTIONAL),
|
||||
"courseproficient" => new \external_value(PARAM_BOOL, 'course competency proficiency',VALUE_OPTIONAL),
|
||||
"needreview" => new \external_value(PARAM_BOOL, 'waiting for review or review in progress',VALUE_OPTIONAL),
|
||||
"proficient" => new \external_value(PARAM_BOOL, 'competency proficiency', VALUE_OPTIONAL),
|
||||
"courseproficient" => new \external_value(PARAM_BOOL, 'course competency proficiency', VALUE_OPTIONAL),
|
||||
"needreview" => new \external_value(PARAM_BOOL, 'waiting for review or review in progress', VALUE_OPTIONAL),
|
||||
"completionstats" => static::completionstats_structure(VALUE_OPTIONAL),
|
||||
"count" => new \external_value(PARAM_INT, 'number of students in stats',VALUE_OPTIONAL),
|
||||
"required" => new \external_value(PARAM_BOOL, 'if required in parent competency rule',VALUE_OPTIONAL),
|
||||
"points" => new \external_value(PARAM_INT, 'number of points in parent competency rule',VALUE_OPTIONAL),
|
||||
"progress" => new \external_value(PARAM_INT, 'number completed child competencies/points',VALUE_OPTIONAL),
|
||||
"count" => new \external_value(PARAM_INT, 'number of child competencies/points required',VALUE_OPTIONAL),
|
||||
"feedback" => new \external_value(PARAM_RAW, 'feedback provided with this competency',VALUE_OPTIONAL),
|
||||
"count" => new \external_value(PARAM_INT, 'number of students in stats', VALUE_OPTIONAL),
|
||||
"required" => new \external_value(PARAM_BOOL, 'if required in parent competency rule', VALUE_OPTIONAL),
|
||||
"points" => new \external_value(PARAM_INT, 'number of points in parent competency rule', VALUE_OPTIONAL),
|
||||
"progress" => new \external_value(PARAM_INT, 'number completed child competencies/points', VALUE_OPTIONAL),
|
||||
"count" => new \external_value(PARAM_INT, 'number of child competencies/points required', VALUE_OPTIONAL),
|
||||
"feedback" => new \external_value(PARAM_RAW, 'feedback provided with this competency', VALUE_OPTIONAL),
|
||||
];
|
||||
if($recurse) {
|
||||
$struct["children"] = new \external_multiple_structure(self::competencyinfo_structure(false),'child competencies',VALUE_OPTIONAL);
|
||||
if ($recurse) {
|
||||
$struct["children"] = new \external_multiple_structure(self::competencyinfo_structure(false), 'child competencies', VALUE_OPTIONAL);
|
||||
}
|
||||
return new \external_single_structure($struct, 'course completion info');
|
||||
}
|
||||
|
@ -130,11 +130,11 @@ class coursecompetencyinfo {
|
|||
* Webservice structure for editor info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function editor_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function editor_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"competencies" => new \external_multiple_structure(self::competencyinfo_structure(), 'competencies'),
|
||||
"proficient" => new \external_value(PARAM_INT, 'number of proficient user/competencys ',VALUE_OPTIONAL),
|
||||
"total" => new \external_value(PARAM_INT, 'total number of gradable user/competencies',VALUE_OPTIONAL),
|
||||
"proficient" => new \external_value(PARAM_INT, 'number of proficient user/competencys ', VALUE_OPTIONAL),
|
||||
"total" => new \external_value(PARAM_INT, 'total number of gradable user/competencies', VALUE_OPTIONAL),
|
||||
], 'course completion info', $value);
|
||||
}
|
||||
|
||||
|
@ -142,11 +142,11 @@ class coursecompetencyinfo {
|
|||
* Webservice structure for userinfo
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function user_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function user_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"competencies" => new \external_multiple_structure(self::competencyinfo_structure(), 'competencies'),
|
||||
"progress" => new \external_value(PARAM_INT, 'number completed competencies'),
|
||||
"count" => new \external_value(PARAM_INT, 'number of competencies',VALUE_OPTIONAL),
|
||||
"count" => new \external_value(PARAM_INT, 'number of competencies', VALUE_OPTIONAL),
|
||||
], 'course completion info', $value);
|
||||
}
|
||||
|
||||
|
@ -154,14 +154,14 @@ class coursecompetencyinfo {
|
|||
* Create basic competency information model from competency
|
||||
* @param Object $competency
|
||||
*/
|
||||
private function competencyinfo_model($competency,$userid=null) : array {
|
||||
$displayfield = get_config("local_treestudyplan","competency_displayname");
|
||||
$detailfield = get_config("local_treestudyplan","competency_detailfield");
|
||||
private function competencyinfo_model($competency, $userid=null): array {
|
||||
$displayfield = get_config("local_treestudyplan", "competency_displayname");
|
||||
$detailfield = get_config("local_treestudyplan", "competency_detailfield");
|
||||
$headingfield = ($displayfield != 'description')?$displayfield:"shortname";
|
||||
$framework = $competency->get_framework();
|
||||
|
||||
$heading = $framework->get($headingfield);
|
||||
if(empty(trim($heading))) {
|
||||
if (empty(trim($heading))) {
|
||||
$heading = $framework->get('shortname'); // Fall back to shortname if heading field is empty
|
||||
}
|
||||
$path = [[
|
||||
|
@ -173,7 +173,7 @@ class coursecompetencyinfo {
|
|||
foreach ($competency->get_ancestors() as $c) {
|
||||
$competencypath[] = $c->get('shortname');
|
||||
$heading = $c->get($headingfield);
|
||||
if(empty(trim($heading))) {
|
||||
if (empty(trim($heading))) {
|
||||
$heading = $c->get('shortname'); // Fall back to shortname if heading field is empty
|
||||
}
|
||||
$path[] = [
|
||||
|
@ -183,9 +183,9 @@ class coursecompetencyinfo {
|
|||
'type' => 'competency',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
$heading = $competency->get($headingfield);
|
||||
if(empty(trim($heading))) {
|
||||
if (empty(trim($heading))) {
|
||||
$heading = $competency->get('shortname'); // Fall back to shortname if heading field is empty
|
||||
}
|
||||
$path[] = [
|
||||
|
@ -196,7 +196,7 @@ class coursecompetencyinfo {
|
|||
];
|
||||
|
||||
$title = $competency->get($displayfield);
|
||||
if(empty(trim($title))) {
|
||||
if (empty(trim($title))) {
|
||||
$title = $competency->get('shortname'); // Fall back to shortname if heading field is empty
|
||||
}
|
||||
$model = [
|
||||
|
@ -224,12 +224,12 @@ class coursecompetencyinfo {
|
|||
|
||||
$count = 0;
|
||||
$nproficient = 0;
|
||||
|
||||
|
||||
$cis = [];
|
||||
foreach($coursecompetencies as $c) {
|
||||
$ci = $this->competencyinfo_model($c);
|
||||
if(!empty($studentlist)){
|
||||
$stats = $this->proficiency_stats($c,$studentlist);
|
||||
if (!empty($studentlist)) {
|
||||
$stats = $this->proficiency_stats($c, $studentlist);
|
||||
$count += $stats->count;
|
||||
$nproficient += $stats->nproficient;
|
||||
// Copy proficiency stats to model.
|
||||
|
@ -243,10 +243,10 @@ class coursecompetencyinfo {
|
|||
|
||||
$rule = $c->get_rule_object();
|
||||
$ruleoutcome = $c->get('ruleoutcome');
|
||||
if($rule && $ruleoutcome != competency::OUTCOME_NONE) {
|
||||
if ($rule && $ruleoutcome != competency::OUTCOME_NONE) {
|
||||
$ruletext = $rule->get_name();
|
||||
$ruleconfig = $c->get('ruleconfig');
|
||||
|
||||
|
||||
if ($ruleoutcome == competency::OUTCOME_EVIDENCE) {
|
||||
$outcometag = "evidence";
|
||||
} else if ($ruleoutcome == competency::OUTCOME_COMPLETE) {
|
||||
|
@ -256,35 +256,35 @@ class coursecompetencyinfo {
|
|||
} else {
|
||||
$outcometag = "none";
|
||||
}
|
||||
$ci["ruleoutcome"] = get_string("coursemodulecompetencyoutcome_{$outcometag}","core_competency");
|
||||
|
||||
$ci["ruleoutcome"] = get_string("coursemodulecompetencyoutcome_{$outcometag}", "core_competency");
|
||||
|
||||
if ($rule instanceof competency_rule_points) {
|
||||
$ruleconfig = json_decode($ruleconfig);
|
||||
$points = $ruleconfig->base->points;
|
||||
|
||||
|
||||
// Make a nice map of the competency rule config
|
||||
$crlist = [];
|
||||
foreach($ruleconfig->competencies as $cr){
|
||||
foreach($ruleconfig->competencies as $cr) {
|
||||
$crlist[$cr->id] = $cr;
|
||||
}
|
||||
$ci["rule"] = $ruletext . " ({$points} ".get_string("points","core_grades").")";
|
||||
$ci["rule"] = $ruletext . " ({$points} ".get_string("points", "core_grades").")";
|
||||
} else {
|
||||
$ci["rule"] = $ruletext;
|
||||
}
|
||||
|
||||
// get one level of children
|
||||
$dids = competency::get_descendants_ids($c);
|
||||
if(count($dids) > 0) {
|
||||
if (count($dids) > 0) {
|
||||
$children = [];
|
||||
foreach($dids as $did) {
|
||||
$cc = new competency($did);
|
||||
$cci = $this->competencyinfo_model($cc);
|
||||
if(!empty($studentlist)){
|
||||
$stats = $this->proficiency_stats($cc,$studentlist);
|
||||
if (!empty($studentlist)) {
|
||||
$stats = $this->proficiency_stats($cc, $studentlist);
|
||||
$cci['completionstats'] = self::completionstats($stats);
|
||||
}
|
||||
if($rule instanceof competency_rule_points) {
|
||||
if(array_key_exists($did,$crlist)) {
|
||||
if ($rule instanceof competency_rule_points) {
|
||||
if (array_key_exists($did, $crlist)) {
|
||||
$cr = $crlist[$did];
|
||||
$cci["points"] = (int) $cr->points;
|
||||
$cci["required"] = (int) $cr->required;
|
||||
|
@ -292,7 +292,7 @@ class coursecompetencyinfo {
|
|||
}
|
||||
$children[] = $cci;
|
||||
}
|
||||
|
||||
|
||||
$ci["children"] = $children;
|
||||
}
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ class coursecompetencyinfo {
|
|||
$info = [
|
||||
"competencies" => $cis,
|
||||
];
|
||||
if(!empty($studentlist)){
|
||||
if (!empty($studentlist)) {
|
||||
$info["proficient"] = $nproficient;
|
||||
$info["total"] = $count;
|
||||
}
|
||||
|
@ -319,9 +319,9 @@ class coursecompetencyinfo {
|
|||
|
||||
$cis = [];
|
||||
foreach ($competencies as $c) {
|
||||
$ci = $this->competencyinfo_model($c,$userid);
|
||||
$ci = $this->competencyinfo_model($c, $userid);
|
||||
// Add user info if $userid is set.
|
||||
$p = $this->proficiency($c,$userid);
|
||||
$p = $this->proficiency($c, $userid);
|
||||
// Copy proficiency info to model.
|
||||
foreach ((array)$p as $key => $value) {
|
||||
$ci[$key] = $value;
|
||||
|
@ -332,15 +332,14 @@ class coursecompetencyinfo {
|
|||
}
|
||||
|
||||
// Retrieve feedback.
|
||||
$ci["feedback"] = $this->retrievefeedback($c,$userid);
|
||||
|
||||
$ci["feedback"] = $this->retrievefeedback($c, $userid);
|
||||
|
||||
$rule = $c->get_rule_object();
|
||||
$ruleoutcome = $c->get('ruleoutcome');
|
||||
if($rule && $ruleoutcome != competency::OUTCOME_NONE) {
|
||||
if ($rule && $ruleoutcome != competency::OUTCOME_NONE) {
|
||||
$ruletext = $rule->get_name();
|
||||
$ruleconfig = $c->get('ruleconfig');
|
||||
|
||||
|
||||
if ($ruleoutcome == competency::OUTCOME_EVIDENCE) {
|
||||
$outcometag = "evidence";
|
||||
} else if ($ruleoutcome == competency::OUTCOME_COMPLETE) {
|
||||
|
@ -350,15 +349,15 @@ class coursecompetencyinfo {
|
|||
} else {
|
||||
$outcometag = "none";
|
||||
}
|
||||
$ci["ruleoutcome"] = get_string("coursemodulecompetencyoutcome_{$outcometag}","core_competency");
|
||||
|
||||
$ci["ruleoutcome"] = get_string("coursemodulecompetencyoutcome_{$outcometag}", "core_competency");
|
||||
|
||||
if ($rule instanceof competency_rule_points) {
|
||||
$ruleconfig = json_decode($ruleconfig);
|
||||
$pointsreq = $ruleconfig->base->points;
|
||||
$points = 0;
|
||||
// Make a nice map of the competency rule config
|
||||
$crlist = [];
|
||||
foreach($ruleconfig->competencies as $cr){
|
||||
foreach($ruleconfig->competencies as $cr) {
|
||||
$crlist[$cr->id] = $cr;
|
||||
}
|
||||
|
||||
|
@ -366,27 +365,27 @@ class coursecompetencyinfo {
|
|||
|
||||
// get one level of children
|
||||
$dids = competency::get_descendants_ids($c);
|
||||
if(count($dids) > 0) {
|
||||
if (count($dids) > 0) {
|
||||
$dcount = 0;
|
||||
$dprogress = 0;
|
||||
$children = [];
|
||||
foreach($dids as $did) {
|
||||
$cc = new competency($did);
|
||||
$cci = $this->competencyinfo_model($cc,$userid);
|
||||
$cp = $p = $this->proficiency($cc,$userid);
|
||||
$cci = $this->competencyinfo_model($cc, $userid);
|
||||
$cp = $p = $this->proficiency($cc, $userid);
|
||||
// Copy proficiency info to model.
|
||||
foreach ((array)$cp as $key => $value) {
|
||||
$cci[$key] = $value;
|
||||
}
|
||||
// Retrieve feedback.
|
||||
$cci["feedback"] = $this->retrievefeedback($cc,$userid);
|
||||
$cci["feedback"] = $this->retrievefeedback($cc, $userid);
|
||||
|
||||
if($rule instanceof competency_rule_points) {
|
||||
if(array_key_exists($did,$crlist)) {
|
||||
if ($rule instanceof competency_rule_points) {
|
||||
if (array_key_exists($did, $crlist)) {
|
||||
$cr = $crlist[$did];
|
||||
$cci["points"] = (int) $cr->points;
|
||||
$cci["required"] = (int) $cr->required;
|
||||
if($cp->proficient) {
|
||||
if ($cp->proficient) {
|
||||
$points += (int) $cr->points;
|
||||
}
|
||||
}
|
||||
|
@ -398,13 +397,13 @@ class coursecompetencyinfo {
|
|||
}
|
||||
$children[] = $cci;
|
||||
}
|
||||
|
||||
|
||||
$ci["children"] = $children;
|
||||
|
||||
}
|
||||
|
||||
if ($rule instanceof competency_rule_points) {
|
||||
$ci["rule"] = $ruletext . " ({$points} / {$pointsreq} ".get_string("points","core_grades").")";
|
||||
$ci["rule"] = $ruletext . " ({$points} / {$pointsreq} ".get_string("points", "core_grades").")";
|
||||
$ci["count"] = $pointsreq;
|
||||
$ci["progress"] = $points;
|
||||
} else {
|
||||
|
@ -413,7 +412,6 @@ class coursecompetencyinfo {
|
|||
$ci["progress"] = $dprogress;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
$cis[] = $ci;
|
||||
}
|
||||
|
@ -444,7 +442,7 @@ class coursecompetencyinfo {
|
|||
return $list;
|
||||
}
|
||||
|
||||
protected function proficiency_stats($competency,$studentlist) {
|
||||
protected function proficiency_stats($competency, $studentlist) {
|
||||
$r = new \stdClass();
|
||||
$r->count = 0;
|
||||
$r->nproficient = 0;
|
||||
|
@ -453,12 +451,12 @@ class coursecompetencyinfo {
|
|||
$r->nfailed = 0;
|
||||
|
||||
foreach ($studentlist as $sid) {
|
||||
$p = $this->proficiency($competency,$sid);
|
||||
$p = $this->proficiency($competency, $sid);
|
||||
$r->count += 1;
|
||||
$r->nproficient += ($p->proficient === true)?1:0;
|
||||
$r->nfailed += ($p->proficient === false)?1:0;
|
||||
$r->ncourseproficient += ($p->courseproficient)?1:0;
|
||||
$r->nneedreview += ($p->needreview)?1:0;
|
||||
$r->ncourseproficient += ($p->courseproficient) ? 1 : 0;
|
||||
$r->nneedreview += ($p->needreview) ? 1 : 0;
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
@ -472,7 +470,7 @@ class coursecompetencyinfo {
|
|||
*/
|
||||
public static function get_user_competency($userid, $competencyid) {
|
||||
c_api::require_enabled();
|
||||
$existing = user_competency::get_multiple($userid, array($competencyid));
|
||||
$existing = user_competency::get_multiple($userid, [$competencyid]);
|
||||
$uc = array_pop($existing);
|
||||
|
||||
if (!$uc) {
|
||||
|
@ -499,7 +497,7 @@ class coursecompetencyinfo {
|
|||
// This will throw an exception if the competency does not belong to the course.
|
||||
$competency = course_competency::get_competency($courseid, $competencyid);
|
||||
|
||||
$params = array('courseid' => $courseid, 'userid' => $userid, 'competencyid' => $competencyid);
|
||||
$params = ['courseid' => $courseid, 'userid' => $userid, 'competencyid' => $competencyid];
|
||||
$exists = user_competency_course::get_record($params);
|
||||
// Create missing.
|
||||
if ($exists) {
|
||||
|
@ -512,15 +510,14 @@ class coursecompetencyinfo {
|
|||
return $ucc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve course proficiency and overall proficiency for a competency and user
|
||||
*
|
||||
* @param \core_competency\competency $competency
|
||||
* @param int $userid
|
||||
*
|
||||
* @return stdClass
|
||||
*
|
||||
*
|
||||
* @return stdClass
|
||||
*
|
||||
*/
|
||||
public function proficiency($competency, $userid) {
|
||||
$scale = $competency->get_scale();
|
||||
|
@ -535,7 +532,7 @@ class coursecompetencyinfo {
|
|||
$r->failed = $proficiency === false;
|
||||
try {
|
||||
// Only add course grade and proficiency if the competency is included in the course.
|
||||
$ucc = self::get_user_competency_in_course($this->course->id,$userid,$competencyid);
|
||||
$ucc = self::get_user_competency_in_course($this->course->id, $userid, $competencyid);
|
||||
$r->courseproficient = $ucc->get('proficiency');
|
||||
$r->coursegrade = $scale->get_nearest_item($ucc->get('grade'));
|
||||
} catch (\Exception $x) {}
|
||||
|
@ -547,20 +544,20 @@ class coursecompetencyinfo {
|
|||
*
|
||||
* @param \core_competency\competency $competency
|
||||
* @param int $userid
|
||||
*
|
||||
* @return stdClass
|
||||
*
|
||||
*
|
||||
* @return stdClass
|
||||
*
|
||||
*/
|
||||
public function retrievefeedback($competency, $userid) {
|
||||
$competencyid = $competency->get('id');
|
||||
$uc = self::get_user_competency($userid, $competencyid);
|
||||
|
||||
// Get evidences and sort by creation date (newest first)
|
||||
$evidence = evidence::get_records_for_usercompetency($uc->get('id'),\context_system::instance(),'timecreated', "DESC");
|
||||
$evidence = evidence::get_records_for_usercompetency($uc->get('id'), \context_system::instance(), 'timecreated', "DESC");
|
||||
|
||||
// Get the first valid note and return it;
|
||||
foreach($evidence as $e) {
|
||||
if ( in_array($e->get('action'),[evidence::ACTION_OVERRIDE,evidence::ACTION_COMPLETE] )) {
|
||||
if ( in_array($e->get('action'), [evidence::ACTION_OVERRIDE, evidence::ACTION_COMPLETE] )) {
|
||||
return $e->get('note');
|
||||
break;
|
||||
}
|
||||
|
@ -581,7 +578,7 @@ class coursecompetencyinfo {
|
|||
// Make sure conditions are properly configured;
|
||||
$conditions = [];
|
||||
try {
|
||||
$conditions = json_decode($item->conditions(),true);
|
||||
$conditions = json_decode($item->conditions(), true);
|
||||
} catch (\Exception $x) {}
|
||||
|
||||
// Make sure the competencied field exists
|
||||
|
@ -590,7 +587,7 @@ class coursecompetencyinfo {
|
|||
}
|
||||
|
||||
// Make sure a record exits.
|
||||
if (!array_key_exists($competencyid,$conditions["competencies"])){
|
||||
if (!array_key_exists($competencyid, $conditions["competencies"])) {
|
||||
$conditions["competencies"][$competencyid] = [
|
||||
"required" => boolval($required),
|
||||
];
|
||||
|
@ -611,11 +608,11 @@ class coursecompetencyinfo {
|
|||
if ($this->studyitem) {
|
||||
$conditions = [];
|
||||
try {
|
||||
$conditions = json_decode($this->studyitem->conditions(),true);
|
||||
$conditions = json_decode($this->studyitem->conditions(), true);
|
||||
} catch (\Exception $x) {}
|
||||
|
||||
|
||||
// Make sure the competencied field exists
|
||||
if ( isset($conditions["competencies"])
|
||||
if ( isset($conditions["competencies"])
|
||||
&& is_array($conditions["competencies"])
|
||||
&& isset($conditions["competencies"][$competency->get("id")])
|
||||
&& isset($conditions["competencies"][$competency->get("id")]["required"])
|
||||
|
|
|
@ -114,7 +114,7 @@ class courseinfo {
|
|||
* Check if current user is teacher in this course
|
||||
* @return book
|
||||
*/
|
||||
protected function am_teacher() : bool {
|
||||
protected function am_teacher(): bool {
|
||||
global $USER;
|
||||
return is_enrolled($this->coursecontext, $USER, 'mod/assign:grade');
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ class courseinfo {
|
|||
* Webservice structure for basic info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function simple_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function simple_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'linked course id'),
|
||||
"fullname" => new \external_value(PARAM_TEXT, 'linked course name'),
|
||||
|
@ -277,7 +277,7 @@ class courseinfo {
|
|||
* Webservice structure for editor info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function editor_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function editor_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'linked course id'),
|
||||
"fullname" => new \external_value(PARAM_TEXT, 'linked course name'),
|
||||
|
@ -343,7 +343,7 @@ class courseinfo {
|
|||
foreach ($gradables as $gradable) {
|
||||
$info['grades'][] = $gradable->editor_model($this->studyitem);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($aggregator->use_corecompletioninfo()) {
|
||||
$cc = new corecompletioninfo($this->course, $this->studyitem);
|
||||
$studentlist = $this->studyitem->studyline()->studyplan()->find_linked_userids();
|
||||
|
@ -353,7 +353,7 @@ class courseinfo {
|
|||
$ci = new coursecompetencyinfo($this->course, $this->studyitem);
|
||||
$studentlist = $this->studyitem->studyline()->studyplan()->find_linked_userids();
|
||||
$info['competency'] = $ci->editor_model($studentlist);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
@ -362,7 +362,7 @@ class courseinfo {
|
|||
* Webservice structure for userinfo
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function user_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function user_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'linked course id'),
|
||||
"fullname" => new \external_value(PARAM_TEXT, 'linked course name'),
|
||||
|
@ -387,7 +387,7 @@ class courseinfo {
|
|||
* @param int $courseid Course id of the course to check
|
||||
* @return int[] Array if user ids
|
||||
*/
|
||||
public static function get_course_students($courseid) : array {
|
||||
public static function get_course_students($courseid): array {
|
||||
global $CFG;
|
||||
if (!array_key_exists($courseid, self::$coursestudents)) {
|
||||
$students = [];
|
||||
|
@ -406,9 +406,9 @@ class courseinfo {
|
|||
* (Has a gradebook role)
|
||||
* @param int $userid The user Id to check
|
||||
*/
|
||||
public function is_enrolled_student($userid) : bool {
|
||||
public function is_enrolled_student($userid): bool {
|
||||
global $CFG;
|
||||
foreach (explode(',', $CFG->gradebookroles) as $roleid) {
|
||||
foreach (explode(', ', $CFG->gradebookroles) as $roleid) {
|
||||
if (user_has_role_assignment($userid, $roleid, $this->coursecontext->id)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -455,10 +455,9 @@ class courseinfo {
|
|||
'grades' => [],
|
||||
'enrolled' => $this->is_enrolled_student($userid),
|
||||
'extrafields' => $this->extrafields_model(),
|
||||
'showprogressbar' => get_config("local_treestudyplan","courseprogressbar"),
|
||||
'showprogressbar' => get_config("local_treestudyplan", "courseprogressbar"),
|
||||
];
|
||||
|
||||
|
||||
if (isset($this->studyitem)) {
|
||||
$aggregator = $this->studyitem->studyline()->studyplan()->aggregator();
|
||||
|
||||
|
@ -467,7 +466,7 @@ class courseinfo {
|
|||
foreach ($gradables as $gi) {
|
||||
$info['grades'][] = $gi->user_model($userid);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($aggregator->use_corecompletioninfo()) {
|
||||
$cc = new corecompletioninfo($this->course, $this->studyitem);
|
||||
$info['completion'] = $cc->user_model($userid);
|
||||
|
@ -475,24 +474,23 @@ class courseinfo {
|
|||
if ($aggregator->use_coursecompetencies()) {
|
||||
$ci = new coursecompetencyinfo($this->course, $this->studyitem);
|
||||
$info['competency'] = $ci->user_model($userid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Webservice structure for extra fields
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function extrafields_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function extrafields_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_multiple_structure(new \external_single_structure([
|
||||
"title" => new \external_value(PARAM_RAW, 'title'),
|
||||
"value" => new \external_value(PARAM_RAW, 'value'),
|
||||
"position" => new \external_value(PARAM_TEXT, 'position'),
|
||||
"type" => new \external_value(PARAM_TEXT, 'value type'),
|
||||
"fieldname" => new \external_value(PARAM_TEXT, 'field name'),
|
||||
"checked" => new \external_value(PARAM_BOOL, 'checkbox value',VALUE_OPTIONAL),
|
||||
"checked" => new \external_value(PARAM_BOOL, 'checkbox value', VALUE_OPTIONAL),
|
||||
"courseid" => new \external_value(PARAM_TEXT, 'course id number'),
|
||||
], 'referenced course information'), $value);
|
||||
}
|
||||
|
@ -505,11 +503,11 @@ class courseinfo {
|
|||
public function extrafields_model($includeteachervisible=false) {
|
||||
$list = [];
|
||||
for ($i=1; $i <= 5; $i++) {
|
||||
$field = get_config('local_treestudyplan','courseinfo'.$i.'_field');
|
||||
$field = get_config('local_treestudyplan', 'courseinfo'.$i.'_field');
|
||||
if ($field) {
|
||||
$title = self::extrafields_localize_title(get_config('local_treestudyplan','courseinfo'.$i.'_title'));
|
||||
$pos = get_config('local_treestudyplan','courseinfo'.$i.'_position');
|
||||
[$value,$type, $raw] = $this->extrafields_value($field,$includeteachervisible);
|
||||
$title = self::extrafields_localize_title(get_config('local_treestudyplan', 'courseinfo'.$i.'_title'));
|
||||
$pos = get_config('local_treestudyplan', 'courseinfo'.$i.'_position');
|
||||
[$value, $type, $raw] = $this->extrafields_value($field, $includeteachervisible);
|
||||
if ($type) {
|
||||
$list[] = [
|
||||
"title" => $title,
|
||||
|
@ -518,7 +516,7 @@ class courseinfo {
|
|||
"type" => $type,
|
||||
"fieldname" => $field,
|
||||
"courseid" => $this->course->id,
|
||||
"checked" => ($type=="checkbox")?($raw?true:false):null,
|
||||
"checked" => ($type=="checkbox") ? ($raw ? true : false):null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -528,11 +526,11 @@ class courseinfo {
|
|||
|
||||
protected static function extrafields_localize_title($field) {
|
||||
$lang = trim(current_language());
|
||||
$lines = explode("\n",$field);
|
||||
$lines = explode("\n", $field);
|
||||
$title = "";
|
||||
$fallback = ""; // Fallback to first title
|
||||
foreach ($lines as $l) {
|
||||
$parts = explode("|",$l,2);
|
||||
$parts = explode("|", $l, 2);
|
||||
if (count($parts) > 0) {
|
||||
// Set the first line as fallback.
|
||||
if (empty($firsttitle) && !empty($parts[0])) {
|
||||
|
@ -543,7 +541,7 @@ class courseinfo {
|
|||
$title = trim($parts[0]);
|
||||
} else if (trim($parts[1]) == $lang) {
|
||||
return trim($parts[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -553,9 +551,9 @@ class courseinfo {
|
|||
|
||||
/**
|
||||
* Determine value and type of an extra field for this course
|
||||
* @return array [value,type] of the field for this
|
||||
* @return array [value, type] of the field for this
|
||||
*/
|
||||
protected function extrafields_value($fieldname,$includeteachervisible=false) {
|
||||
protected function extrafields_value($fieldname, $includeteachervisible=false) {
|
||||
global $PAGE;
|
||||
if ($fieldname == "description") {
|
||||
// Process embedded files.
|
||||
|
@ -580,7 +578,7 @@ class courseinfo {
|
|||
$contacts = $cle->get_course_contacts();
|
||||
$value = "";
|
||||
foreach ($contacts as $uid => $contact) {
|
||||
if(strlen($value) > 0) {
|
||||
if (strlen($value) > 0) {
|
||||
$value .= ", ";
|
||||
}
|
||||
$value .= $contact["username"];
|
||||
|
@ -610,7 +608,7 @@ class courseinfo {
|
|||
$value = "";
|
||||
} else {
|
||||
// Convert to YYYY-MM-DD format.
|
||||
$value = date("Y-m-d", $raw);
|
||||
$value = date("Y-m-d", $raw);
|
||||
}
|
||||
} else {
|
||||
// Everything else can just use the export value.
|
||||
|
@ -618,12 +616,12 @@ class courseinfo {
|
|||
$value = $data->export_value();
|
||||
}
|
||||
|
||||
return [$value,$type,$raw];
|
||||
return [$value, $type, $raw];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fallback to empty if finding a match fails.
|
||||
return [null,null,null];
|
||||
return [null, null, null];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,32 +49,31 @@ class courseservice extends \external_api {
|
|||
*/
|
||||
const CAP_VIEW = "local/treestudyplan:viewuserreports";
|
||||
|
||||
|
||||
/**
|
||||
* Get the topmost categories for the specicied user.
|
||||
* Most of the work is offloaded to an SQL query in the interest of speed, but moodle functions are used to double check access permissions.
|
||||
* @param int $userid Id of the user
|
||||
* @return array of core_course_category
|
||||
* @return array of core_course_category
|
||||
*/
|
||||
public static function user_tops($userid=null,$capability='moodle/category:viewcourselist') {
|
||||
public static function user_tops($userid=null, $capability='moodle/category:viewcourselist') {
|
||||
global $DB, $USER;
|
||||
if ($userid == null) {
|
||||
$userid = $USER->id;
|
||||
}
|
||||
$tops = [];
|
||||
|
||||
if (has_capability($capability,\context_system::instance(),$userid)) {
|
||||
if (has_capability($capability, \context_system::instance(), $userid)) {
|
||||
if ($capability == 'moodle/category:viewcourselist') {
|
||||
// We are now just looking for the visible main level categories.
|
||||
// Add all categories of depth = 1;
|
||||
$rs = $DB->get_recordset("course_categories",["depth" => 1],'sortorder');
|
||||
$rs = $DB->get_recordset("course_categories", ["depth" => 1], 'sortorder');
|
||||
foreach( $rs as $rcat) {
|
||||
// Get the category, and double check if the category is visible to the current user.
|
||||
// Just in case it is a hidden category and the user does not have the viewhidden permission.
|
||||
$cat = \core_course_category::get($rcat->id, \IGNORE_MISSING, false, $userid);
|
||||
if ($cat !== null) {
|
||||
// Register the category.
|
||||
array_push($tops,$cat);
|
||||
array_push($tops, $cat);
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
|
@ -99,42 +98,42 @@ class courseservice extends \external_api {
|
|||
|
||||
// Use recordset to handle the eventuality of a really big and complex moodle setup.
|
||||
$recordset = $DB->get_records_sql($sql, ["userid" => $userid, "capability" => $capability,
|
||||
"ctxl_coursecat" => \CONTEXT_COURSECAT,]);
|
||||
"ctxl_coursecat" => \CONTEXT_COURSECAT ]);
|
||||
$params = ["userid" => $userid, "capability" => $capability,
|
||||
"ctxl_coursecat" => \CONTEXT_COURSECAT,];
|
||||
"ctxl_coursecat" => \CONTEXT_COURSECAT ];
|
||||
$contextids = [];
|
||||
foreach ($recordset as $r) {
|
||||
// Get the paths as an array.
|
||||
$parents = explode("/",$r->path);
|
||||
$parents = explode("/", $r->path);
|
||||
// Strip the first item, since it is an empty one.
|
||||
array_shift($parents);
|
||||
// Strip the last item, since it refers to self.
|
||||
array_pop($parents);
|
||||
// Figure out if any of the remaining parent contexts are already contexts with permission.
|
||||
$intersect = array_intersect($contextids,$parents);
|
||||
$intersect = array_intersect($contextids, $parents);
|
||||
if (count($intersect) == 0) {
|
||||
// Double check permissions according to the moodle capability system.
|
||||
$ctx = \context::instance_by_id($r->id);
|
||||
if (has_capability($capability,$ctx,$userid)) {
|
||||
if (has_capability($capability, $ctx, $userid)) {
|
||||
// Get the category, and double check if the category is visible to the current user.
|
||||
// Just in case it is a hidden category and the user does not have the viewhidden permission.
|
||||
$cat = \core_course_category::get($r->instanceid, \IGNORE_MISSING, false, $userid);
|
||||
if ($cat !== null) {
|
||||
// Register the context id in the list now, since we know the category is really visible.
|
||||
array_push($contextids,$r->id);
|
||||
array_push($contextids, $r->id);
|
||||
// Register the category.
|
||||
array_push($tops,$cat);
|
||||
array_push($tops, $cat);
|
||||
} else {
|
||||
// The category is not visible. Add the first known visible subcategories.
|
||||
$children = self::get_first_visible_children($r->id,$userid);
|
||||
$children = self::get_first_visible_children($r->id, $userid);
|
||||
foreach ($children as $cat) {
|
||||
array_push($tops,$cat);
|
||||
array_push($tops, $cat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//$recordset->close();
|
||||
//$recordset->close();
|
||||
}
|
||||
|
||||
return $tops;
|
||||
|
@ -142,7 +141,7 @@ class courseservice extends \external_api {
|
|||
|
||||
/**
|
||||
* Find the top-most child categories for a given category that are visible.
|
||||
*
|
||||
*
|
||||
* @param int $parentid The category to search for
|
||||
* @return array of \core_course_category
|
||||
*/
|
||||
|
@ -151,7 +150,7 @@ class courseservice extends \external_api {
|
|||
$capability = 'moodle/category:viewcourselist';
|
||||
|
||||
$tops = [];
|
||||
$path_like = $DB->sql_like('ctx.path',':pathsearch');
|
||||
$pathlike = $DB->sql_like('ctx.path', ':pathsearch');
|
||||
|
||||
$sql = "SELECT UNIQUE ctx.* FROM {context} AS ctx
|
||||
INNER JOIN {role_assignments} AS ra ON ra.contextid = ctx.id
|
||||
|
@ -159,51 +158,50 @@ class courseservice extends \external_api {
|
|||
LEFT JOIN {course_categories} AS cat ON ctx.instanceid = cat.id
|
||||
WHERE ( ctx.contextlevel = :ctxl_coursecat )
|
||||
AND ra.userid = :userid AND rc.capability = :capability
|
||||
AND {$path_like}
|
||||
AND {$pathlike}
|
||||
ORDER BY ctx.depth ASC, cat.sortorder ASC";
|
||||
|
||||
// Use recordset to handle the eventuality of a really big and complex moodle setup.
|
||||
$recordset = $DB->get_recordset_sql($sql, ["userid" => $userid,
|
||||
$recordset = $DB->get_recordset_sql($sql, ["userid" => $userid,
|
||||
"capability" => $capability,
|
||||
"ctxl_coursecat" => \CONTEXT_COURSECAT,
|
||||
"ctxl_coursecat" => \CONTEXT_COURSECAT,
|
||||
"pathsearch" => "%/{$parentid}/%",
|
||||
]);
|
||||
|
||||
$contextids = [];
|
||||
foreach ($recordset as $r) {
|
||||
// Get the paths as an array.
|
||||
$parents = explode("/",$r->path);
|
||||
$parents = explode("/", $r->path);
|
||||
// Strip the first item, since it is an empty one.
|
||||
array_shift($parents);
|
||||
// Strip the last item, since it refers to self.
|
||||
array_pop($parents);
|
||||
// Figure out if any of the remaining parent contexts are already contexts with permission.
|
||||
$intersect = array_intersect($contextids,$parents);
|
||||
$intersect = array_intersect($contextids, $parents);
|
||||
if (count($intersect) == 0) {
|
||||
// Double check permissions according to the moodle capability system.
|
||||
$ctx = \context::instance_by_id($r->id);
|
||||
if (has_capability($capability,$ctx,$userid)) {
|
||||
if (has_capability($capability, $ctx, $userid)) {
|
||||
// Get the category, and double check if the category is visible to the current user.
|
||||
// Just in case it is a hidden category and the user does not have the viewhidden permission.
|
||||
$cat = \core_course_category::get($r->instanceid, \IGNORE_MISSING, false, $userid);
|
||||
if ($cat !== null) {
|
||||
// Register the context id in the list now, since we know the category is really visible.
|
||||
array_push($contextids,$r->id);
|
||||
array_push($contextids, $r->id);
|
||||
// Register the category.
|
||||
array_push($tops,$cat);
|
||||
}
|
||||
}
|
||||
array_push($tops, $cat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$recordset->close();
|
||||
$recordset->close();
|
||||
return $tops;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return value description for map_categories function
|
||||
*/
|
||||
public static function map_categories_parameters() : \external_function_parameters {
|
||||
public static function map_categories_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplan_id" => new \external_value(PARAM_INT, 'ID of studyplan to map the categories for', VALUE_DEFAULT),
|
||||
] );
|
||||
|
@ -212,7 +210,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));
|
||||
}
|
||||
|
||||
|
@ -247,7 +245,6 @@ class courseservice extends \external_api {
|
|||
public static function map_categories($studyplanid = 0) {
|
||||
global $USER;
|
||||
|
||||
|
||||
// Determine top categories from provided context.
|
||||
|
||||
if ($studyplanid == 0) {
|
||||
|
@ -255,22 +252,22 @@ class courseservice extends \external_api {
|
|||
// This uses a custom function, since moodle's "core_course_category::user_top()" is somewhat deficient.
|
||||
$children = self::user_tops();
|
||||
if (count($children) == 0) {
|
||||
throw new moodle_exception("error:nocategoriesvisible","local_treestudyplan");
|
||||
throw new moodle_exception("error:nocategoriesvisible", "local_treestudyplan");
|
||||
}
|
||||
} else {
|
||||
if (\get_config("local_treestudyplan","limitcourselist")) { // TODO: Insert config setting here
|
||||
if (\get_config("local_treestudyplan", "limitcourselist")) { // TODO: Insert config setting here
|
||||
$studyplan = studyplan::find_by_id($studyplanid);
|
||||
$context = $studyplan->context();
|
||||
if ($context->contextlevel == \CONTEXT_SYSTEM) {
|
||||
$children = self::user_tops();
|
||||
} else if ($context->contextlevel == \CONTEXT_COURSECAT) {
|
||||
$cat = \core_course_category::get($context->instanceid,\MUST_EXIST,true);
|
||||
if ($cat->is_uservisible()) {
|
||||
$cat = \core_course_category::get($context->instanceid, \MUST_EXIST, true);
|
||||
if ($cat->is_uservisible()) {
|
||||
$children = [$cat];
|
||||
} else {
|
||||
$ci = new contextinfo($context);
|
||||
$contextname = $ci->pathstr();
|
||||
throw new moodle_exception("error:cannotviewcategory","local_treestudyplan",'',$contextname);
|
||||
throw new moodle_exception("error:cannotviewcategory", "local_treestudyplan", '', $contextname);
|
||||
}
|
||||
} else {
|
||||
$children = [];
|
||||
|
@ -278,7 +275,7 @@ class courseservice extends \external_api {
|
|||
} else {
|
||||
$children = self::user_tops();
|
||||
if (count($children) == 0) {
|
||||
throw new moodle_exception("error:nocategoriesvisible","local_treestudyplan");
|
||||
throw new moodle_exception("error:nocategoriesvisible", "local_treestudyplan");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -293,7 +290,7 @@ class courseservice extends \external_api {
|
|||
/**
|
||||
* Return value description for get_category function
|
||||
*/
|
||||
public static function get_category_parameters() : \external_function_parameters {
|
||||
public static function get_category_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"id" => new \external_value(PARAM_INT, 'id of category'),
|
||||
] );
|
||||
|
@ -302,7 +299,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);
|
||||
}
|
||||
|
||||
|
@ -362,8 +359,8 @@ class courseservice extends \external_api {
|
|||
global $USER;
|
||||
// List the categories in which the user has a specific capability.
|
||||
$list = [];
|
||||
$parents = self::user_tops($USER->id,$capability);
|
||||
array_merge($list,$parents);
|
||||
$parents = self::user_tops($USER->id, $capability);
|
||||
array_merge($list, $parents);
|
||||
|
||||
foreach ($parents as $parent) {
|
||||
// For optimization purposes, we include all its children now, since they will have inherited the permission.
|
||||
|
@ -394,7 +391,7 @@ class courseservice extends \external_api {
|
|||
/**
|
||||
* Return value description for list_available_categories function
|
||||
*/
|
||||
public static function list_available_categories_parameters() : \external_function_parameters {
|
||||
public static function list_available_categories_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"operation" => new \external_value(PARAM_TEXT, 'type of operation ["view"|"edit"]', VALUE_DEFAULT),
|
||||
"refcontext_id" => new \external_value(PARAM_INT, 'id of reference context', VALUE_DEFAULT),
|
||||
|
@ -404,7 +401,7 @@ class courseservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for list_available_categories function
|
||||
*/
|
||||
public static function list_available_categories_returns() : \external_description {
|
||||
public static function list_available_categories_returns(): \external_description {
|
||||
return new \external_multiple_structure(static::map_category_structure(true));
|
||||
}
|
||||
|
||||
|
@ -421,10 +418,10 @@ class courseservice extends \external_api {
|
|||
} else { // Operation == "view" || default.
|
||||
$capability = self::CAP_VIEW;
|
||||
}
|
||||
|
||||
|
||||
// Get the context ids of all categories the user has access to view and wich have the given permission.
|
||||
$contextids = [];
|
||||
$tops = self::user_tops(null,$capability);
|
||||
$tops = self::user_tops(null, $capability);
|
||||
foreach ($tops as $cat) {
|
||||
$ctx = \context_coursecat::instance($cat->id);
|
||||
$contextids[] = $ctx->id;
|
||||
|
@ -440,7 +437,7 @@ class courseservice extends \external_api {
|
|||
$contextcounts[$r->context_id] = $r->num;
|
||||
// Add any of the categories containing studyplans to the list.
|
||||
$ctx = \context::instance_by_id($r->context_id);
|
||||
if (has_capability($capability,$ctx) && !in_array($r->context_id,$contextids)) {
|
||||
if (has_capability($capability, $ctx) && !in_array($r->context_id, $contextids)) {
|
||||
$insertctxs[] = $ctx;
|
||||
}
|
||||
}
|
||||
|
@ -451,11 +448,11 @@ class courseservice extends \external_api {
|
|||
|
||||
// If the reference context id is not in the list, push it there if the user has proper permissions in that context
|
||||
if ($refctxid > 1 && !in_array($refctxid, $contextids)) {
|
||||
try {
|
||||
try {
|
||||
// Get the context.
|
||||
$refctx = \context::instance_by_id($refctxid);
|
||||
// Double check permissions.
|
||||
if (has_capability($capability,$refctx)) {
|
||||
if (has_capability($capability, $refctx)) {
|
||||
$insertctxs[] = $refctx;
|
||||
}
|
||||
} catch(\dml_missing_record_exception $x) {
|
||||
|
@ -468,12 +465,12 @@ class courseservice extends \external_api {
|
|||
$ipath = $ictx->get_parent_context_ids(true);
|
||||
$found = false;
|
||||
foreach ($ipath as $i => $pid) {
|
||||
$idx = array_search($pid,$contextids);
|
||||
if($idx !== false) {
|
||||
$idx = array_search($pid, $contextids);
|
||||
if ($idx !== false) {
|
||||
|
||||
$contextids = array_merge(
|
||||
array_slice($contextids, 0, $idx+1),
|
||||
array_reverse(array_slice($ipath,0,$i)),
|
||||
array_reverse(array_slice($ipath, 0, $i)),
|
||||
array_slice($contextids, $idx+1, count($contextids) - 1)
|
||||
) ;
|
||||
|
||||
|
@ -481,12 +478,11 @@ class courseservice extends \external_api {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if(!$found) {
|
||||
array_unshift($contextids,$ictx->id);
|
||||
if (!$found) {
|
||||
array_unshift($contextids, $ictx->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now translate this to the list of categories.
|
||||
foreach ($contextids as $ctxid ) {
|
||||
try {
|
||||
|
@ -494,7 +490,7 @@ class courseservice extends \external_api {
|
|||
if ($ctx->contextlevel == CONTEXT_SYSTEM) {
|
||||
$cat = \core_course_category::top();
|
||||
} else if ($ctx->contextlevel == CONTEXT_COURSECAT) {
|
||||
$cat = \core_course_category::get($ctx->instanceid,\MUST_EXIST,false);
|
||||
$cat = \core_course_category::get($ctx->instanceid, \MUST_EXIST, false);
|
||||
}
|
||||
$cats[] = $cat;
|
||||
// In edit mode, also include direct children of the currently selected context.
|
||||
|
@ -502,7 +498,7 @@ class courseservice extends \external_api {
|
|||
// Include direct children for navigation purposes.
|
||||
foreach ($cat->get_children() as $ccat) {
|
||||
$ccatctx = \context_coursecat::instance($ccat->id);
|
||||
if (!in_array($ccatctx->id,$contextids)) {
|
||||
if (!in_array($ccatctx->id, $contextids)) {
|
||||
$cats[] = $ccat;
|
||||
}
|
||||
}
|
||||
|
@ -529,7 +525,6 @@ class courseservice extends \external_api {
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**************************************
|
||||
*
|
||||
* Progress scanners for teacherview
|
||||
|
@ -540,7 +535,7 @@ class courseservice extends \external_api {
|
|||
* Return value description for scan_grade_progress function
|
||||
* @return external_function_parameters
|
||||
*/
|
||||
public static function scan_grade_progress_parameters() : \external_function_parameters {
|
||||
public static function scan_grade_progress_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"gradeitemid" => new \external_value(PARAM_INT, 'Grade item ID to scan progress for', VALUE_DEFAULT),
|
||||
"studyplanid" => new \external_value(PARAM_INT, 'Study plan id to check progress in', VALUE_DEFAULT),
|
||||
|
@ -551,7 +546,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);
|
||||
}
|
||||
|
||||
|
@ -585,7 +580,7 @@ class courseservice extends \external_api {
|
|||
/**
|
||||
* Return value description for scan_completion_progress function
|
||||
*/
|
||||
public static function scan_completion_progress_parameters() : \external_function_parameters {
|
||||
public static function scan_completion_progress_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"criteriaid" => new \external_value(PARAM_INT, 'CriteriaID to scan progress for', VALUE_DEFAULT),
|
||||
"studyplanid" => new \external_value(PARAM_INT, 'Study plan id to check progress in', VALUE_DEFAULT),
|
||||
|
@ -596,7 +591,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);
|
||||
}
|
||||
|
||||
|
@ -621,7 +616,7 @@ class courseservice extends \external_api {
|
|||
/**
|
||||
* Return value description for scan_badge_progress function
|
||||
*/
|
||||
public static function scan_badge_progress_parameters() : \external_function_parameters {
|
||||
public static function scan_badge_progress_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"badgeid" => new \external_value(PARAM_INT, 'Badge to scan progress for', VALUE_DEFAULT),
|
||||
"studyplanid" => new \external_value(PARAM_INT,
|
||||
|
@ -632,7 +627,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'),
|
||||
|
|
|
@ -33,18 +33,18 @@ class debug {
|
|||
* @param $filename File to write to
|
||||
* @return any The object
|
||||
*/
|
||||
public static function &dump(&$object,$filename="/tmp/debug.log") {
|
||||
public static function &dump(&$object, $filename="/tmp/debug.log") {
|
||||
|
||||
try {
|
||||
$f = fopen($filename,"a+");
|
||||
$f = fopen($filename, "a+");
|
||||
try {
|
||||
$json = \json_encode($object,JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR );
|
||||
fwrite($f,$json."\n");
|
||||
$json = \json_encode($object, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR );
|
||||
fwrite($f, $json."\n");
|
||||
} catch (JsonException $x) {
|
||||
fwrite($f,"Error processing json: ". $x->getMessage()."\n");
|
||||
fwrite($f,"Print_r dump: \n".print_r($object,true)."\n");
|
||||
fwrite($f, "Error processing json: ". $x->getMessage()."\n");
|
||||
fwrite($f, "Print_r dump: \n".print_r($object, true)."\n");
|
||||
}
|
||||
} catch (\Exception $x){
|
||||
} catch (\Exception $x) {
|
||||
|
||||
} finally {
|
||||
fclose($f);
|
||||
|
@ -57,26 +57,25 @@ class debug {
|
|||
* @param $filename File to write to
|
||||
* @return any The object
|
||||
*/
|
||||
public static function &print_r(&$object,$filename="/tmp/debug.log") {
|
||||
public static function &print_r(&$object, $filename="/tmp/debug.log") {
|
||||
try {
|
||||
$f = fopen($filename,"a+");
|
||||
fwrite($f,"Print_r dump: \n".print_r($object,true)."\n");
|
||||
$f = fopen($filename, "a+");
|
||||
fwrite($f, "Print_r dump: \n".print_r($object, true)."\n");
|
||||
} catch (\Exception $x) {
|
||||
} finally {
|
||||
fclose($f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $object Object to dump
|
||||
* @param $filename File to write to
|
||||
* @return any The object
|
||||
*/
|
||||
public static function write($text,$filename="/tmp/debug.log") {
|
||||
public static function write($text, $filename="/tmp/debug.log") {
|
||||
try {
|
||||
$f = fopen($filename,"a+");
|
||||
fwrite($f,$text."\n");
|
||||
$f = fopen($filename, "a+");
|
||||
fwrite($f, $text."\n");
|
||||
} catch (\Exception $x) {
|
||||
} finally {
|
||||
fclose($f);
|
||||
|
|
|
@ -25,7 +25,7 @@ abstract class formbase extends \moodleform {
|
|||
/**
|
||||
* Generate custom data from parameters
|
||||
* Also validate parameters and access permissions here
|
||||
*
|
||||
*
|
||||
* @param object $params The parameters for form initialization
|
||||
* @return object Form data based on parameters
|
||||
*/
|
||||
|
@ -34,23 +34,23 @@ abstract class formbase extends \moodleform {
|
|||
/**
|
||||
* Generate form data from parameters
|
||||
* Also validate parameters and access permissions here
|
||||
*
|
||||
*
|
||||
* @param object $customdata The parameters for form initialization
|
||||
* @return array Form data based on parameters
|
||||
*/
|
||||
abstract public function init_formdata(object $customdata);
|
||||
|
||||
/**
|
||||
* Validate security access for this form based on the provided parameters
|
||||
* Validate security access for this form based on the provided parameters
|
||||
* Return true if validation passes, false or throw an exception if it does not.
|
||||
*
|
||||
*
|
||||
* @param object $params The parameters for form initialization
|
||||
* @return bool True if security validation passes.
|
||||
* @return bool True if security validation passes.
|
||||
* @throws \moodle_exception if access denied for a specific reason.
|
||||
*/
|
||||
abstract public static function check_security(object $customdata);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Process the submission and perform necessary actions
|
||||
* @param object $entry The processed form data
|
||||
* @return object|array Data to pass to receiver if submission successful
|
||||
|
@ -58,7 +58,7 @@ abstract class formbase extends \moodleform {
|
|||
*/
|
||||
abstract protected function process_submitted_data(object $entry);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Process the submission and perform necessary actions
|
||||
* @return object|array Data to pass to receiver if submission successful
|
||||
* @throws \moodle_exception if an error must be given for a specific reason.
|
||||
|
@ -66,13 +66,11 @@ abstract class formbase extends \moodleform {
|
|||
public function process_submission() {
|
||||
$data = $this->get_data();
|
||||
|
||||
if($data) {
|
||||
if ($data) {
|
||||
return $this->process_submitted_data($data);
|
||||
} else {
|
||||
throw new \moodle_exception('no_form_data','local_treestudyplan','',null,$data);
|
||||
throw new \moodle_exception('no_form_data', 'local_treestudyplan', '', null, $data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -14,10 +14,9 @@ use local_treestudyplan\form\text_integer;
|
|||
use moodle_exception;
|
||||
use stdClass;
|
||||
|
||||
|
||||
/**
|
||||
* Moodleform class for the studyplan editor. A Moodleform is used here to facilitate a rich editor
|
||||
* in the studyplan description
|
||||
* Moodleform class for the studyplan editor. A Moodleform is used here to facilitate a rich editor
|
||||
* in the studyplan description
|
||||
*/
|
||||
class studyplan_editform extends formbase {
|
||||
/**
|
||||
|
@ -27,18 +26,18 @@ class studyplan_editform extends formbase {
|
|||
const CAP_EDIT = "local/treestudyplan:editstudyplan";
|
||||
|
||||
/**
|
||||
* Translate parameters into customdata.
|
||||
*
|
||||
* Translate parameters into customdata.
|
||||
*
|
||||
* @param object $params The parameters for form initialization
|
||||
* @return array Form data based on parameters
|
||||
*/
|
||||
*/
|
||||
public static function init_customdata(object $params) {
|
||||
$customdata = new stdClass;
|
||||
$customdata->create = $params->mode=='create'?true:false;
|
||||
if($customdata->create){
|
||||
$customdata->create = $params->mode=='create' ? true : false;
|
||||
if ($customdata->create) {
|
||||
$customdata->context = \context::instance_by_id($params->contextid);
|
||||
} else {
|
||||
|
||||
|
||||
$customdata->plan = studyplan::find_by_id($params->studyplan_id);
|
||||
$customdata->context = $customdata->plan->context();
|
||||
$customdata->simplemodel = $customdata->plan->simple_model();
|
||||
|
@ -59,43 +58,43 @@ class studyplan_editform extends formbase {
|
|||
'accepted_types' => ['.jpg', '.png', '.jpeg', '.svg', '.svgz'],
|
||||
'return_types' => \FILE_INTERNAL | \FILE_EXTERNAL,
|
||||
];
|
||||
return $customdata;
|
||||
return $customdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate security access for this form based on the customdata generated by init_customdata
|
||||
* Return true if validation passes, false or throw an exception if it does not.
|
||||
*
|
||||
*
|
||||
* @param object $customdata The customdata for this form
|
||||
* @return bool True if security validation passes.
|
||||
* @return bool True if security validation passes.
|
||||
* @throws \moodle_exception if access denied for a specific reason.
|
||||
*/
|
||||
public static function check_security(object $customdata) {
|
||||
/*webservicehelper::require_capabilities(self::CAP_EDIT,$customdata->context); */
|
||||
/*webservicehelper::require_capabilities(self::CAP_EDIT, $customdata->context); */
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate form data from parameters
|
||||
* Also validate parameters and access permissions here
|
||||
*
|
||||
*
|
||||
* @param object $customdata The parameters for form initialization
|
||||
* @return array Form data based on parameters
|
||||
*/
|
||||
*/
|
||||
public function init_formdata(object $customdata) {
|
||||
global $DB;
|
||||
/* Use direct database retrieval to avoid our abstractions causing trouble
|
||||
with existing moodle code assumptions.
|
||||
with existing moodle code assumptions.
|
||||
The form API does seem needlessly convoluted in it's use, but we need the editor...
|
||||
*/
|
||||
if($customdata->create) {
|
||||
if ($customdata->create) {
|
||||
$entry = new stdClass;
|
||||
$entry->context_id = $customdata->context->id;
|
||||
$entry->aggregation = get_config("local_treestudyplan","aggregation_mode");
|
||||
$ag_cfg = json_decode(aggregator::create($entry->aggregation, "")->config_string(),true);
|
||||
|
||||
$entry->aggregation = get_config("local_treestudyplan", "aggregation_mode");
|
||||
$agcfg = json_decode(aggregator::create($entry->aggregation, "")->config_string(), true);
|
||||
|
||||
// Determine the next august 1st for default value purposes.
|
||||
$august = strtotime("first day of august this year");
|
||||
if($august < time()) {
|
||||
if ($august < time()) {
|
||||
$august = strtotime("first day of august next year");
|
||||
}
|
||||
$entry->startdate = $august;
|
||||
|
@ -107,7 +106,7 @@ class studyplan_editform extends formbase {
|
|||
$entry->startdate = strtotime($customdata->simplemodel['pages'][0]['startdate']);
|
||||
$entry->enddate = strtotime($customdata->simplemodel['pages'][0]['enddate']);
|
||||
$entry->periods = $customdata->simplemodel['pages'][0]['periods'];
|
||||
$ag_cfg = json_decode($customdata->plan->aggregator()->config_string(),true);
|
||||
$agcfg = json_decode($customdata->plan->aggregator()->config_string(), true);
|
||||
}
|
||||
|
||||
// Prepare the editor
|
||||
|
@ -117,7 +116,7 @@ class studyplan_editform extends formbase {
|
|||
\context_system::instance(),
|
||||
'local_treestudyplan',
|
||||
'studyplan',
|
||||
($customdata->create)?null:$customdata->plan->id()
|
||||
($customdata->create) ? null : $customdata->plan->id()
|
||||
);
|
||||
|
||||
// Prepare file area for the icon
|
||||
|
@ -132,14 +131,14 @@ class studyplan_editform extends formbase {
|
|||
\context_system::instance()->id,
|
||||
'local_treestudyplan',
|
||||
'icon',
|
||||
($customdata->create)?null:$customdata->plan->id(),
|
||||
($customdata->create) ? null : $customdata->plan->id(),
|
||||
$customdata->fileoptions
|
||||
);
|
||||
$entry->icon = $draftitemid;
|
||||
|
||||
// Add aggregation configs to entry.
|
||||
|
||||
foreach ($ag_cfg as $key => $val) {
|
||||
foreach ($agcfg as $key => $val) {
|
||||
$entrykey = $entry->aggregation."_".$key;
|
||||
$entry->$entrykey = $val;
|
||||
}
|
||||
|
@ -160,29 +159,29 @@ class studyplan_editform extends formbase {
|
|||
|
||||
// Define the form
|
||||
$field = 'name';
|
||||
$mform->addElement('text',$field,
|
||||
get_string('studyplan_name','local_treestudyplan'),
|
||||
$mform->addElement('text', $field,
|
||||
get_string('studyplan_name', 'local_treestudyplan'),
|
||||
[]);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
||||
$field = 'shortname';
|
||||
$mform->addElement('text',$field,
|
||||
get_string('studyplan_shortname','local_treestudyplan'),
|
||||
$mform->addElement('text', $field,
|
||||
get_string('studyplan_shortname', 'local_treestudyplan'),
|
||||
[]);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
||||
$field = 'idnumber';
|
||||
$mform->addElement('text',$field,
|
||||
get_string('studyplan_idnumber','local_treestudyplan'),
|
||||
$mform->addElement('text', $field,
|
||||
get_string('studyplan_idnumber', 'local_treestudyplan'),
|
||||
[]);
|
||||
|
||||
$contextlist = [];
|
||||
foreach(courseservice::list_available_categories('edit') as $c){
|
||||
$contextlist[$c['context_id']] = implode(" / ",$c['category']['path']);
|
||||
foreach(courseservice::list_available_categories('edit') as $c) {
|
||||
$contextlist[$c['context_id']] = implode(" / ", $c['category']['path']);
|
||||
}
|
||||
|
||||
$mform->addElement('autocomplete', 'context_id',
|
||||
get_string('studyplan_context','local_treestudyplan'),
|
||||
$mform->addElement('autocomplete', 'context_id',
|
||||
get_string('studyplan_context', 'local_treestudyplan'),
|
||||
$contextlist);
|
||||
|
||||
$mform->addRule('context_id', null, 'required', null, 'client');
|
||||
|
@ -196,25 +195,25 @@ class studyplan_editform extends formbase {
|
|||
);
|
||||
|
||||
if ($customdata->create) {
|
||||
$timeless = \get_config("local_treestudyplan","timelessperiods");
|
||||
$timeless = \get_config("local_treestudyplan", "timelessperiods");
|
||||
if ( !$timeless) {
|
||||
// Only add these fields if a new studyplan is created, to easily initialize the first page
|
||||
$field = 'startdate';
|
||||
$mform->addElement('date_selector',$field,
|
||||
get_string('studyplan_startdate','local_treestudyplan'),
|
||||
$mform->addElement('date_selector', $field,
|
||||
get_string('studyplan_startdate', 'local_treestudyplan'),
|
||||
[]);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
||||
$field = 'enddate';
|
||||
$mform->addElement('date_selector',$field,
|
||||
get_string('studyplan_enddate','local_treestudyplan'),
|
||||
$mform->addElement('date_selector', $field,
|
||||
get_string('studyplan_enddate', 'local_treestudyplan'),
|
||||
[]);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
||||
|
||||
}
|
||||
$field = 'periods';
|
||||
$mform->addElement('text_integer',$field,
|
||||
get_string('studyplan_slots','local_treestudyplan'),
|
||||
$mform->addElement('text_integer', $field,
|
||||
get_string('studyplan_slots', 'local_treestudyplan'),
|
||||
["unsigned" => true]);
|
||||
$mform->setType($field, PARAM_INT);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
@ -222,83 +221,83 @@ class studyplan_editform extends formbase {
|
|||
} else {
|
||||
// These fields are only relevant if the studyplan is edited
|
||||
$field = 'suspended';
|
||||
$mform->addElement('advcheckbox',$field,
|
||||
get_string('studyplan_suspend','local_treestudyplan'),
|
||||
get_string('studyplan_suspend_details','local_treestudyplan'),
|
||||
$mform->addElement('advcheckbox', $field,
|
||||
get_string('studyplan_suspend', 'local_treestudyplan'),
|
||||
get_string('studyplan_suspend_details', 'local_treestudyplan'),
|
||||
[],
|
||||
);
|
||||
|
||||
if (premium::enabled()) {
|
||||
$field = 'template';
|
||||
$mform->addElement('advcheckbox',$field,
|
||||
get_string('studyplan_template','local_treestudyplan'),
|
||||
get_string('studyplan_template_details','local_treestudyplan'),
|
||||
$mform->addElement('advcheckbox', $field,
|
||||
get_string('studyplan_template', 'local_treestudyplan'),
|
||||
get_string('studyplan_template_details', 'local_treestudyplan'),
|
||||
[],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$aggregators = [];
|
||||
foreach(aggregator::list_model() as $a){
|
||||
foreach(aggregator::list_model() as $a) {
|
||||
// Add method only if not deprecated or currently used
|
||||
if ( $customdata->simplemodel['aggregation'] == $a['id'] || !($a['deprecated']) ) {
|
||||
$aggregators[$a['id']] = $a['name'];
|
||||
}
|
||||
}
|
||||
$field = 'aggregation';
|
||||
$mform->addElement('select',$field,
|
||||
get_string('choose_aggregation_style','local_treestudyplan'),
|
||||
$mform->addElement('select', $field,
|
||||
get_string('choose_aggregation_style', 'local_treestudyplan'),
|
||||
$aggregators);
|
||||
|
||||
/* Start Bistate aggregation specific items */
|
||||
$field = 'bistate_thresh_excellent';
|
||||
$mform->addElement('text_integer',$field,
|
||||
get_string('setting_bistate_thresh_excellent','local_treestudyplan'),
|
||||
$mform->addElement('text_integer', $field,
|
||||
get_string('setting_bistate_thresh_excellent', 'local_treestudyplan'),
|
||||
["unsigned" => false],
|
||||
);
|
||||
$mform->setType($field, PARAM_INT);
|
||||
$mform->hideIf($field, "aggregation", "neq", "bistate");
|
||||
$mform->hideif ($field, "aggregation", "neq", "bistate");
|
||||
|
||||
$field = 'bistate_thresh_good';
|
||||
$mform->addElement('text_integer',$field,
|
||||
get_string('setting_bistate_thresh_good','local_treestudyplan'),
|
||||
$mform->addElement('text_integer', $field,
|
||||
get_string('setting_bistate_thresh_good', 'local_treestudyplan'),
|
||||
["unsigned" => true],
|
||||
);
|
||||
$mform->setType($field, PARAM_INT);
|
||||
$mform->hideIf($field, "aggregation", "neq", "bistate");
|
||||
$mform->hideif ($field, "aggregation", "neq", "bistate");
|
||||
|
||||
$field = 'bistate_thresh_completed';
|
||||
$mform->addElement('text_integer',$field,
|
||||
get_string('setting_bistate_thresh_completed','local_treestudyplan'),
|
||||
$mform->addElement('text_integer', $field,
|
||||
get_string('setting_bistate_thresh_completed', 'local_treestudyplan'),
|
||||
["unsigned" => true],
|
||||
);
|
||||
$mform->setType($field, PARAM_INT);
|
||||
$mform->hideIf($field, "aggregation", "neq", "bistate");
|
||||
$mform->hideif ($field, "aggregation", "neq", "bistate");
|
||||
|
||||
$field = 'bistate_use_failed';
|
||||
$mform->addElement('checkbox',$field,
|
||||
get_string('setting_bistate_support_failed','local_treestudyplan'),
|
||||
$mform->addElement('checkbox', $field,
|
||||
get_string('setting_bistate_support_failed', 'local_treestudyplan'),
|
||||
[],
|
||||
);
|
||||
$mform->hideIf($field, "aggregation", "neq", "bistate");
|
||||
|
||||
$mform->hideif ($field, "aggregation", "neq", "bistate");
|
||||
|
||||
$field = 'bistate_accept_pending_as_submitted';
|
||||
$mform->addElement('checkbox',$field,
|
||||
get_string('setting_bistate_accept_pending_submitted','local_treestudyplan'),
|
||||
$mform->addElement('checkbox', $field,
|
||||
get_string('setting_bistate_accept_pending_submitted', 'local_treestudyplan'),
|
||||
[],
|
||||
);
|
||||
$mform->hideIf($field, "aggregation", "neq", "bistate");
|
||||
$mform->hideif ($field, "aggregation", "neq", "bistate");
|
||||
|
||||
/* End Bistate aggregation specific items */
|
||||
|
||||
$mform->addElement('editor', 'description_editor',
|
||||
get_string('studyplan_description', 'local_treestudyplan'),
|
||||
null,
|
||||
get_string('studyplan_description', 'local_treestudyplan'),
|
||||
null,
|
||||
$customdata->editoroptions);
|
||||
$mform->setType('description_editor', PARAM_RAW);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Process the submitted data and perform necessary actions
|
||||
* @param object $entry The processed form data;
|
||||
* @return bool false if submission not successful
|
||||
|
@ -308,12 +307,12 @@ class studyplan_editform extends formbase {
|
|||
$customdata = (object)$this->_customdata;
|
||||
|
||||
// Add aggregation configs to entry.
|
||||
$ag_cfg = json_decode(aggregator::create($entry->aggregation, "")->config_string(),true); // Retrieve default config string from selected aggregation method
|
||||
foreach ($ag_cfg as $key => $val) {
|
||||
$agcfg = json_decode(aggregator::create($entry->aggregation, "")->config_string(), true); // Retrieve default config string from selected aggregation method
|
||||
foreach ($agcfg as $key => $val) {
|
||||
$entrykey = $entry->aggregation."_".$key;
|
||||
$ag_cfg[$key] = $entry->$entrykey;
|
||||
$agcfg[$key] = $entry->$entrykey;
|
||||
}
|
||||
$aggregation_config = json_encode($ag_cfg);
|
||||
$aggregationconfig = json_encode($agcfg);
|
||||
|
||||
if ($customdata->create) {
|
||||
|
||||
|
@ -323,9 +322,9 @@ class studyplan_editform extends formbase {
|
|||
'idnumber' => $entry->idnumber,
|
||||
'context_id' => $entry->context_id,
|
||||
'aggregation' => $entry->aggregation,
|
||||
'aggregation_config' => $aggregation_config,
|
||||
'startdate' => date("Y-m-d",$entry->startdate),
|
||||
'enddate' => date("Y-m-d",$entry->enddate),
|
||||
'aggregation_config' => $aggregationconfig,
|
||||
'startdate' => date("Y-m-d", $entry->startdate),
|
||||
'enddate' => date("Y-m-d", $entry->enddate),
|
||||
'periods' => $entry->periods,
|
||||
]);
|
||||
// Process the provided files in the description editor
|
||||
|
@ -335,7 +334,7 @@ class studyplan_editform extends formbase {
|
|||
\context_system::instance(),
|
||||
'local_treestudyplan',
|
||||
'studyplan',
|
||||
$plan->id());
|
||||
$plan->id());
|
||||
// Update the description
|
||||
$plan->edit([
|
||||
'description' => $entry->description,
|
||||
|
@ -343,7 +342,7 @@ class studyplan_editform extends formbase {
|
|||
]);
|
||||
} else {
|
||||
$plan = $customdata->plan;
|
||||
|
||||
|
||||
// Process the provided files in the description editor
|
||||
$entry = file_postupdate_standard_editor($entry,
|
||||
'description',
|
||||
|
@ -361,7 +360,7 @@ class studyplan_editform extends formbase {
|
|||
'description' => $entry->description,
|
||||
'descriptionformat' => $entry->descriptionformat,
|
||||
'aggregation' => $entry->aggregation,
|
||||
'aggregation_config' => $aggregation_config,
|
||||
'aggregation_config' => $aggregationconfig,
|
||||
'suspended' => $entry->suspended,
|
||||
'template' => $entry->template,
|
||||
]);
|
||||
|
@ -382,12 +381,11 @@ class studyplan_editform extends formbase {
|
|||
|
||||
/* Return the simple model of the plan to make sure we can update stuff.
|
||||
Parse it through the clean_returnvalue function of exernal api (of which studyplanservice is a subclass)
|
||||
so we return it in a consistent way
|
||||
so we return it in a consistent way
|
||||
*/
|
||||
$response = studyplanservice::clean_returnvalue(studyplan::simple_structure(),$plan->simple_model());
|
||||
$response = studyplanservice::clean_returnvalue(studyplan::simple_structure(), $plan->simple_model());
|
||||
debug::dump($response);
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -14,10 +14,9 @@ use local_treestudyplan\form\text_integer;
|
|||
use moodle_exception;
|
||||
use stdClass;
|
||||
|
||||
|
||||
/**
|
||||
* Moodleform class for the studyplan editor. A Moodleform is used here to facilitate a rich editor
|
||||
* in the studyplan description
|
||||
* Moodleform class for the studyplan editor. A Moodleform is used here to facilitate a rich editor
|
||||
* in the studyplan description
|
||||
*/
|
||||
class studyplan_fromtemplateform extends formbase {
|
||||
/**
|
||||
|
@ -27,42 +26,41 @@ class studyplan_fromtemplateform extends formbase {
|
|||
const CAP_EDIT = "local/treestudyplan:editstudyplan";
|
||||
|
||||
/**
|
||||
* Translate parameters into customdata.
|
||||
*
|
||||
* Translate parameters into customdata.
|
||||
*
|
||||
* @param object $params The parameters for form initialization
|
||||
* @return array Form data based on parameters
|
||||
*/
|
||||
*/
|
||||
public static function init_customdata(object $params) {
|
||||
$customdata = new stdClass;
|
||||
$customdata->context = \context::instance_by_id($params->contextid);
|
||||
|
||||
|
||||
return $customdata;
|
||||
return $customdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate security access for this form based on the customdata generated by init_customdata
|
||||
* Return true if validation passes, false or throw an exception if it does not.
|
||||
*
|
||||
*
|
||||
* @param object $customdata The customdata for this form
|
||||
* @return bool True if security validation passes.
|
||||
* @return bool True if security validation passes.
|
||||
* @throws \moodle_exception if access denied for a specific reason.
|
||||
*/
|
||||
public static function check_security(object $customdata) {
|
||||
/*webservicehelper::require_capabilities(self::CAP_EDIT,$customdata->context); */
|
||||
/*webservicehelper::require_capabilities(self::CAP_EDIT, $customdata->context); */
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate form data from parameters
|
||||
* Also validate parameters and access permissions here
|
||||
*
|
||||
*
|
||||
* @param object $customdata The parameters for form initialization
|
||||
* @return array Form data based on parameters
|
||||
*/
|
||||
*/
|
||||
public function init_formdata(object $customdata) {
|
||||
global $DB;
|
||||
/* Use direct database retrieval to avoid our abstractions causing trouble
|
||||
with existing moodle code assumptions.
|
||||
with existing moodle code assumptions.
|
||||
The form API does seem needlessly convoluted in it's use, but we need the editor...
|
||||
*/
|
||||
$entry = new stdClass;
|
||||
|
@ -70,7 +68,7 @@ class studyplan_fromtemplateform extends formbase {
|
|||
|
||||
// Determine the next august 1st for default value purposes.
|
||||
$august = strtotime("first day of august this year");
|
||||
if($august < time()) {
|
||||
if ($august < time()) {
|
||||
$august = strtotime("first day of august next year");
|
||||
}
|
||||
$entry->startdate = $august;
|
||||
|
@ -95,70 +93,70 @@ class studyplan_fromtemplateform extends formbase {
|
|||
// Define the form
|
||||
|
||||
$templatelist = [];
|
||||
foreach(studyplan::find_template() as $s){
|
||||
foreach(studyplan::find_template() as $s) {
|
||||
$c = (new contextinfo($s->context()))->model();
|
||||
$templatelist[$s->id()] = implode(" / ",$c['path']) . " / " . $s->name();
|
||||
$templatelist[$s->id()] = implode(" / ", $c['path']) . " / " . $s->name();
|
||||
}
|
||||
|
||||
if (count($templatelist) > 0) {
|
||||
$mform->addElement('hidden','hastemplates','yes');
|
||||
$mform->addElement('hidden', 'hastemplates', 'yes');
|
||||
|
||||
$field = 'template_id';
|
||||
$mform->addElement('autocomplete', $field,
|
||||
get_string('studyplan_fromtemplate','local_treestudyplan'),
|
||||
$mform->addElement('autocomplete', $field,
|
||||
get_string('studyplan_fromtemplate', 'local_treestudyplan'),
|
||||
$templatelist);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
||||
$field = 'name';
|
||||
$mform->addElement('text',$field,
|
||||
get_string('studyplan_name','local_treestudyplan'),
|
||||
$mform->addElement('text', $field,
|
||||
get_string('studyplan_name', 'local_treestudyplan'),
|
||||
[]);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
||||
$field = 'shortname';
|
||||
$mform->addElement('text',$field,
|
||||
get_string('studyplan_shortname','local_treestudyplan'),
|
||||
$mform->addElement('text', $field,
|
||||
get_string('studyplan_shortname', 'local_treestudyplan'),
|
||||
[]);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
||||
$field = 'idnumber';
|
||||
$mform->addElement('text',$field,
|
||||
get_string('studyplan_idnumber','local_treestudyplan'),
|
||||
$mform->addElement('text', $field,
|
||||
get_string('studyplan_idnumber', 'local_treestudyplan'),
|
||||
[]);
|
||||
|
||||
$contextlist = [];
|
||||
foreach(courseservice::list_available_categories('edit') as $c){
|
||||
$contextlist[$c['context_id']] = implode(" / ",$c['category']['path']);
|
||||
foreach(courseservice::list_available_categories('edit') as $c) {
|
||||
$contextlist[$c['context_id']] = implode(" / ", $c['category']['path']);
|
||||
}
|
||||
|
||||
$field = 'context_id';
|
||||
$mform->addElement('autocomplete', $field,
|
||||
get_string('studyplan_context','local_treestudyplan'),
|
||||
$mform->addElement('autocomplete', $field,
|
||||
get_string('studyplan_context', 'local_treestudyplan'),
|
||||
$contextlist);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
||||
$timeless = \get_config("local_treestudyplan","timelessperiods");
|
||||
$timeless = \get_config("local_treestudyplan", "timelessperiods");
|
||||
if ( !$timeless) {
|
||||
// Only add these fields if the studyplans are timed
|
||||
$field = 'startdate';
|
||||
$mform->addElement('date_selector',$field,
|
||||
get_string('studyplan_startdate','local_treestudyplan'),
|
||||
$mform->addElement('date_selector', $field,
|
||||
get_string('studyplan_startdate', 'local_treestudyplan'),
|
||||
[]);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
||||
}
|
||||
} else {
|
||||
$mform->addElement('hidden','hastemplates','no');
|
||||
$mform->addElement('hidden', 'hastemplates', 'no');
|
||||
|
||||
$field = 'warning';
|
||||
$mform->addElement('static', $field,
|
||||
get_string('warning','core'),
|
||||
get_string('no_templates','local_treestudyplan')
|
||||
$mform->addElement('static', $field,
|
||||
get_string('warning', 'core'),
|
||||
get_string('no_templates', 'local_treestudyplan')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Process the submitted data and perform necessary actions
|
||||
* @param object $entry The processed form data;
|
||||
* @return bool false if submission not successful
|
||||
|
@ -167,21 +165,20 @@ class studyplan_fromtemplateform extends formbase {
|
|||
protected function process_submitted_data($entry) {
|
||||
$customdata = (object)$this->_customdata;
|
||||
|
||||
if($entry->hastemplates == "yes") {
|
||||
if ($entry->hastemplates == "yes") {
|
||||
// Find template study plan.
|
||||
$template = studyplan::find_by_id($entry->template_id);
|
||||
// Copy template plan.
|
||||
$plan = $template->duplicate($entry->name,$entry->shortname,$entry->context_id,$entry->idnumber,$entry->startdate);
|
||||
$plan = $template->duplicate($entry->name, $entry->shortname, $entry->context_id, $entry->idnumber, $entry->startdate);
|
||||
|
||||
/* Return the simple model of the plan to make sure we can update stuff.
|
||||
Parse it through the clean_returnvalue function of exernal api (of which studyplanservice is a subclass)
|
||||
so we return it in a consistent way
|
||||
so we return it in a consistent way
|
||||
*/
|
||||
return studyplanservice::clean_returnvalue(studyplan::simple_structure(),$plan->simple_model());
|
||||
return studyplanservice::clean_returnvalue(studyplan::simple_structure(), $plan->simple_model());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -15,8 +15,8 @@ use moodle_exception;
|
|||
use stdClass;
|
||||
|
||||
/**
|
||||
* Moodleform class for the studyplan editor. A Moodleform is used here to facilitate a rich editor
|
||||
* in the studyplan description
|
||||
* Moodleform class for the studyplan editor. A Moodleform is used here to facilitate a rich editor
|
||||
* in the studyplan description
|
||||
*/
|
||||
class studyplanpage_editform extends formbase {
|
||||
/**
|
||||
|
@ -26,15 +26,15 @@ class studyplanpage_editform extends formbase {
|
|||
const CAP_EDIT = "local/treestudyplan:editstudyplan";
|
||||
|
||||
/**
|
||||
* Translate parameters into customdata.
|
||||
*
|
||||
* Translate parameters into customdata.
|
||||
*
|
||||
* @param object $params The parameters for form initialization
|
||||
* @return array Form data based on parameters
|
||||
*/
|
||||
*/
|
||||
public static function init_customdata(object $params) {
|
||||
$customdata = new stdClass;
|
||||
$customdata->create = $params->mode=='create'?true:false;
|
||||
if($customdata->create){
|
||||
$customdata->create = $params->mode=='create' ? true : false;
|
||||
if ($customdata->create) {
|
||||
$customdata->plan = studyplan::find_by_id($params->studyplan_id);
|
||||
} else {
|
||||
$customdata->page = studyplanpage::find_by_id($params->page_id);
|
||||
|
@ -58,42 +58,42 @@ class studyplanpage_editform extends formbase {
|
|||
'accepted_types' => ['.jpg', '.png'],
|
||||
'return_types' => \FILE_INTERNAL | \FILE_EXTERNAL,
|
||||
];
|
||||
return $customdata;
|
||||
return $customdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate security access for this form based on the customdata generated by init_customdata
|
||||
* Return true if validation passes, false or throw an exception if it does not.
|
||||
*
|
||||
*
|
||||
* @param object $customdata The customdata for this form
|
||||
* @return bool True if security validation passes.
|
||||
* @return bool True if security validation passes.
|
||||
* @throws \moodle_exception if access denied for a specific reason.
|
||||
*/
|
||||
public static function check_security(object $customdata) {
|
||||
/*webservicehelper::require_capabilities(self::CAP_EDIT,$customdata->context); */
|
||||
/*webservicehelper::require_capabilities(self::CAP_EDIT, $customdata->context); */
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate form data from parameters
|
||||
* Also validate parameters and access permissions here
|
||||
*
|
||||
*
|
||||
* @param object $customdata The parameters for form initialization
|
||||
* @return array Form data based on parameters
|
||||
*/
|
||||
*/
|
||||
public function init_formdata(object $customdata) {
|
||||
global $DB;
|
||||
/* Use direct database retrieval to avoid our abstractions causing trouble
|
||||
with existing moodle code assumptions.
|
||||
with existing moodle code assumptions.
|
||||
The form API does seem needlessly convoluted in it's use, but we need the editor...
|
||||
*/
|
||||
if($customdata->create) {
|
||||
if ($customdata->create) {
|
||||
$plan = $customdata->plan;
|
||||
$entry = new stdClass;
|
||||
$entry->studyplan_id = $plan->id();
|
||||
|
||||
// By default, make the start date of a new page, continue 1 day after the last page's start date;
|
||||
$otherpages = $plan->pages();
|
||||
if(count($otherpages) > 0){
|
||||
if (count($otherpages) > 0) {
|
||||
$lastpage = $otherpages[count($otherpages) -1];
|
||||
|
||||
// Propose 1 year after the last page's start date, if no end date is set.
|
||||
|
@ -107,10 +107,10 @@ class studyplanpage_editform extends formbase {
|
|||
} else {
|
||||
// Determine the next august 1st for default value purposes. Only if no other page is available
|
||||
$august = strtotime("first day of august this year");
|
||||
if($august < time()) {
|
||||
if ($august < time()) {
|
||||
$august = strtotime("first day of august next year");
|
||||
}
|
||||
|
||||
|
||||
$entry->startdate = $august;
|
||||
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ class studyplanpage_editform extends formbase {
|
|||
\context_system::instance(),
|
||||
'local_treestudyplan',
|
||||
'studyplanpage',
|
||||
($customdata->create)?null:$customdata->page->id()
|
||||
($customdata->create) ? null : $customdata->page->id()
|
||||
);
|
||||
|
||||
return $entry;
|
||||
|
@ -148,49 +148,49 @@ class studyplanpage_editform extends formbase {
|
|||
|
||||
// Define the form
|
||||
$field = 'fullname';
|
||||
$mform->addElement('text',$field,
|
||||
get_string('studyplan_name','local_treestudyplan'),
|
||||
$mform->addElement('text', $field,
|
||||
get_string('studyplan_name', 'local_treestudyplan'),
|
||||
[]);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
||||
$field = 'shortname';
|
||||
$mform->addElement('text',$field,
|
||||
get_string('studyplan_shortname','local_treestudyplan'),
|
||||
$mform->addElement('text', $field,
|
||||
get_string('studyplan_shortname', 'local_treestudyplan'),
|
||||
[]);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
||||
$timeless = \get_config("local_treestudyplan","timelessperiods");
|
||||
$timeless = \get_config("local_treestudyplan", "timelessperiods");
|
||||
if ( !$timeless) {
|
||||
$field = 'startdate';
|
||||
$mform->addElement('date_selector',$field,
|
||||
get_string('studyplan_startdate','local_treestudyplan'),
|
||||
$mform->addElement('date_selector', $field,
|
||||
get_string('studyplan_startdate', 'local_treestudyplan'),
|
||||
[]);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
||||
$field = 'enddate';
|
||||
$mform->addElement('date_selector',$field,
|
||||
get_string('studyplan_startdate','local_treestudyplan'),
|
||||
$mform->addElement('date_selector', $field,
|
||||
get_string('studyplan_startdate', 'local_treestudyplan'),
|
||||
[]);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
}
|
||||
|
||||
$field = 'periods';
|
||||
$mform->addElement('text_integer',$field,
|
||||
get_string( ($timeless)?'studyplan_slots':'studyplan_periods','local_treestudyplan'),
|
||||
$mform->addElement('text_integer', $field,
|
||||
get_string( ($timeless) ? 'studyplan_slots' : 'studyplan_periods', 'local_treestudyplan'),
|
||||
["unsigned" => true, "nonzero" => true]);
|
||||
$mform->setType($field, PARAM_INT);
|
||||
$mform->addRule($field, null, 'required', null, 'client');
|
||||
|
||||
$field = 'description_editor';
|
||||
$mform->addElement('editor', $field,
|
||||
get_string('studyplan_description', 'local_treestudyplan'),
|
||||
null,
|
||||
get_string('studyplan_description', 'local_treestudyplan'),
|
||||
null,
|
||||
$customdata->editoroptions);
|
||||
$mform->setType($field, PARAM_RAW);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Process the submitted data and perform necessary actions
|
||||
* @param object $entry The processed form data;
|
||||
* @return bool false if submission not successful
|
||||
|
@ -199,13 +199,13 @@ class studyplanpage_editform extends formbase {
|
|||
protected function process_submitted_data($entry) {
|
||||
$customdata = (object)$this->_customdata;
|
||||
|
||||
if($customdata->create) {
|
||||
if ($customdata->create) {
|
||||
|
||||
// Use our own abstraction to update the record, so caches are maintained
|
||||
$page = studyplanpage::add(['fullname' => $entry->fullname,
|
||||
'shortname' => $entry->shortname,
|
||||
'startdate' => date("Y-m-d",$entry->startdate),
|
||||
'enddate' => date("Y-m-d",$entry->enddate),
|
||||
'startdate' => date("Y-m-d", $entry->startdate),
|
||||
'enddate' => date("Y-m-d", $entry->enddate),
|
||||
'periods' => $entry->periods,
|
||||
'studyplan_id' => $customdata->plan->id(),
|
||||
]);
|
||||
|
@ -216,7 +216,7 @@ class studyplanpage_editform extends formbase {
|
|||
\context_system::instance(),
|
||||
'local_treestudyplan',
|
||||
'studyplanpage',
|
||||
$page->id());
|
||||
$page->id());
|
||||
// Update the description
|
||||
$page->edit([
|
||||
'description' => $entry->description,
|
||||
|
@ -224,7 +224,7 @@ class studyplanpage_editform extends formbase {
|
|||
]);
|
||||
} else {
|
||||
$page = $customdata->page;
|
||||
|
||||
|
||||
// Process the provided files in the description editor
|
||||
$entry = file_postupdate_standard_editor($entry,
|
||||
'description',
|
||||
|
@ -239,18 +239,17 @@ class studyplanpage_editform extends formbase {
|
|||
'shortname' => $entry->shortname,
|
||||
'description' => $entry->description,
|
||||
'descriptionformat' => $entry->descriptionformat,
|
||||
'startdate' => date("Y-m-d",$entry->startdate),
|
||||
'enddate' => date("Y-m-d",$entry->enddate),
|
||||
'startdate' => date("Y-m-d", $entry->startdate),
|
||||
'enddate' => date("Y-m-d", $entry->enddate),
|
||||
'periods' => $entry->periods,
|
||||
]);
|
||||
}
|
||||
|
||||
/* Return the editor structure of the new / edited page
|
||||
Parse it through the clean_returnvalue function of exernal api (of which studyplanservice is a subclass)
|
||||
so we return it in a consistent way
|
||||
so we return it in a consistent way
|
||||
*/
|
||||
return studyplanservice::clean_returnvalue(studyplanpage::editor_structure(),$page->editor_model());
|
||||
return studyplanservice::clean_returnvalue(studyplanpage::editor_structure(), $page->editor_model());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -3,12 +3,10 @@ namespace local_treestudyplan\form;
|
|||
use MoodleQuickForm_text;
|
||||
use MoodleQuickForm;
|
||||
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . "/form/text.php");
|
||||
|
||||
|
||||
class text_integer extends MoodleQuickForm_text {
|
||||
/**
|
||||
* Accepts a renderer
|
||||
|
@ -32,14 +30,13 @@ class text_integer extends MoodleQuickForm_text {
|
|||
}
|
||||
$label = $this->getLabel();
|
||||
|
||||
|
||||
$unsigned = (isset($this->_attributes['unsigned']) && $this->_attributes['unsigned']);
|
||||
$nonzero = (isset($this->_attributes['nonzero']) && $this->_attributes['nonzero']);
|
||||
$context = array(
|
||||
'element' => $elementcontext,
|
||||
'label' => $label,
|
||||
'unsigned' => ($unsigned)?true:false ,
|
||||
'nonzero' => ($nonzero)?true:false ,
|
||||
'unsigned' => ($unsigned) ? true : false ,
|
||||
'nonzero' => ($nonzero) ? true : false ,
|
||||
'required' => $required,
|
||||
'advanced' => $advanced,
|
||||
'helpbutton' => $helpbutton,
|
||||
|
|
|
@ -95,14 +95,14 @@ class gradeinfo {
|
|||
* Get the grade_item
|
||||
* @return grade_item
|
||||
*/
|
||||
public function get_gradeitem() : grade_item {
|
||||
public function get_gradeitem(): grade_item {
|
||||
return $this->gradeitem;
|
||||
}
|
||||
/**
|
||||
* Get the gradingscanner
|
||||
* @return gradingscanner
|
||||
*/
|
||||
public function get_gradingscanner() : gradingscanner {
|
||||
public function get_gradingscanner(): gradingscanner {
|
||||
return $this->gradingscanner;
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ class gradeinfo {
|
|||
* Get the grade's scale if applicable
|
||||
* @return grade_scale|null
|
||||
*/
|
||||
public function get_scale() : ?grade_scale {
|
||||
public function get_scale(): ?grade_scale {
|
||||
return $this->scale;
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ class gradeinfo {
|
|||
* Get content items (activity icons) from the repository
|
||||
* @return content_item[]
|
||||
*/
|
||||
protected static function get_contentitems() : array {
|
||||
protected static function get_contentitems(): array {
|
||||
global $PAGE;
|
||||
if (empty(static::$contentitems)) {
|
||||
$PAGE->set_context(\context_system::instance());
|
||||
|
@ -132,7 +132,7 @@ class gradeinfo {
|
|||
* @param mixed $name Name of content item
|
||||
* @return content_item|null
|
||||
*/
|
||||
public static function get_contentitem($name) : ?content_item {
|
||||
public static function get_contentitem($name): ?content_item {
|
||||
$contentitems = static::get_contentitems();
|
||||
for ($i = 0; $i < count($contentitems); $i++) {
|
||||
if ($contentitems[$i]->get_name() == $name) {
|
||||
|
@ -148,7 +148,7 @@ class gradeinfo {
|
|||
* @return \context_course
|
||||
* @throws InvalidArgumentException if grade id is not found
|
||||
*/
|
||||
public static function get_coursecontext_by_id($id) : \context_course {
|
||||
public static function get_coursecontext_by_id($id): \context_course {
|
||||
$gi = grade_item::fetch(["id" => $id]);
|
||||
if (!$gi || course_module_instance_pending_deletion($gi->courseid, $gi->itemmodule, $gi->iteminstance)) {
|
||||
throw new \InvalidArgumentException ("Grade {$id} not found in database");
|
||||
|
@ -174,7 +174,7 @@ class gradeinfo {
|
|||
|
||||
// Determine the icon for the associated activity.
|
||||
$contentitem = static::get_contentitem($gi->itemmodule);
|
||||
$this->icon = empty($contentitem) ? "" : $contentitem->get_icon();
|
||||
$this->icon = empty($contentitem) ? "" : $contentitem->get_icon();
|
||||
|
||||
$this->scale = $gi->load_scale();
|
||||
$this->outcome = $gi->load_outcome();
|
||||
|
@ -210,7 +210,6 @@ class gradeinfo {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
$this->typename = empty($contentitem) ? $gi->itemmodule : $contentitem->get_title()->get_value();
|
||||
$this->gradingscanner = new gradingscanner($gi);
|
||||
|
||||
|
@ -222,7 +221,7 @@ class gradeinfo {
|
|||
* Check if this gradable item is selected in the studyitem
|
||||
* @return bool
|
||||
*/
|
||||
public function is_selected() : bool {
|
||||
public function is_selected(): bool {
|
||||
global $DB;
|
||||
if ($this->studyitem) {
|
||||
// Check if selected for this studyitem.
|
||||
|
@ -260,7 +259,7 @@ class gradeinfo {
|
|||
* Webservice structure for editor info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function editor_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function editor_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'grade_item id'),
|
||||
"cmid" => new \external_value(PARAM_INT, 'course module id'),
|
||||
|
@ -312,7 +311,7 @@ class gradeinfo {
|
|||
* Webservice structure for userinfo
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function user_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function user_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'grade_item id'),
|
||||
"cmid" => new \external_value(PARAM_INT, 'course module id'),
|
||||
|
@ -339,10 +338,10 @@ class gradeinfo {
|
|||
global $DB;
|
||||
$grade = $this->gradeitem->get_final($userid);
|
||||
// Format grade for proper display
|
||||
if(is_object($grade)) {
|
||||
$finalgrade = \grade_format_gradevalue($grade->finalgrade,$this->gradeitem,true,null,1);
|
||||
if (is_object($grade)) {
|
||||
$finalgrade = \grade_format_gradevalue($grade->finalgrade, $this->gradeitem, true, null, 1);
|
||||
} else {
|
||||
$finalgrade = \grade_format_gradevalue(0,$this->gradeitem,true,null,1);
|
||||
$finalgrade = \grade_format_gradevalue(0, $this->gradeitem, true, null, 1);
|
||||
}
|
||||
|
||||
// Retrieve the aggregator and determine completion.
|
||||
|
@ -358,8 +357,8 @@ class gradeinfo {
|
|||
"name" => $this->name,
|
||||
"typename" => $this->typename,
|
||||
"grade" => $finalgrade,
|
||||
"gradetype" => isset($this->scale) ? "completion" : "grade",
|
||||
"feedback" => empty($grade) ? null : $grade->feedback,
|
||||
"gradetype" => isset($this->scale) ? "completion" : "grade",
|
||||
"feedback" => empty($grade) ? null : $grade->feedback,
|
||||
"completion" => completion::label($completion),
|
||||
"icon" => $this->icon,
|
||||
"link" => $this->link,
|
||||
|
@ -375,7 +374,7 @@ class gradeinfo {
|
|||
* Export essential information for export
|
||||
* @return array information model
|
||||
*/
|
||||
public function export_model() : array {
|
||||
public function export_model(): array {
|
||||
return [
|
||||
"name" => $this->name,
|
||||
"type" => $this->gradeitem->itemmodule,
|
||||
|
@ -419,7 +418,7 @@ class gradeinfo {
|
|||
* @param studyitem|null $studyitem Studyitem linked to the course which can be linked to created gradeinfo objects
|
||||
* @return gradeinfo[] Array of gradeinfo
|
||||
*/
|
||||
public static function list_course_gradables($course, studyitem $studyitem = null) : array {
|
||||
public static function list_course_gradables($course, studyitem $studyitem = null): array {
|
||||
$list = [];
|
||||
|
||||
if (method_exists("\course_modinfo", "get_array_of_activities")) {
|
||||
|
@ -462,7 +461,7 @@ class gradeinfo {
|
|||
* @param studyitem $studyitem The studyitem to search for
|
||||
* @return gradeinfo[] Array of gradeinfo
|
||||
*/
|
||||
public static function list_studyitem_gradables(studyitem $studyitem) : array {
|
||||
public static function list_studyitem_gradables(studyitem $studyitem): array {
|
||||
global $DB;
|
||||
$table = 'local_treestudyplan_gradeinc';
|
||||
$list = [];
|
||||
|
@ -488,7 +487,6 @@ class gradeinfo {
|
|||
return $list;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Webservice executor to include grade with studyitem or not.
|
||||
* if both $inclue and $required are false, any existing DB record will be removed
|
||||
|
@ -506,14 +504,14 @@ class gradeinfo {
|
|||
$r = $DB->get_record($table, ['studyitem_id' => $itemid, 'grade_item_id' => $gradeid]);
|
||||
if ($r) {
|
||||
$r->include = 1;
|
||||
$r->required = boolval($required) ? 1 : 0;
|
||||
$r->required = boolval($required) ? 1 : 0;
|
||||
$id = $DB->update_record($table, $r);
|
||||
} else {
|
||||
$DB->insert_record($table, [
|
||||
'studyitem_id' => $itemid,
|
||||
'grade_item_id' => $gradeid,
|
||||
'include' => 1,
|
||||
'required' => boolval($required) ? 1 : 0 ]
|
||||
'required' => boolval($required) ? 1 : 0 ]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -57,7 +57,7 @@ class gradingscanner {
|
|||
* Check if a certain activity type is supported for scanning pending results
|
||||
* @param string $mod name of activity module
|
||||
*/
|
||||
public static function supported($mod) : bool {
|
||||
public static function supported($mod): bool {
|
||||
if (!array_key_exists($mod, self::$modsupported)) {
|
||||
self::$modsupported[$mod] = class_exists("\local_treestudyplan\\local\\ungradedscanners\\{$mod}_scanner");
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ class gradingscanner {
|
|||
* @param int $courseid Course id of the course to check
|
||||
* @return int[] Array if user ids
|
||||
*/
|
||||
public static function get_course_students($courseid) : array {
|
||||
public static function get_course_students($courseid): array {
|
||||
global $CFG;
|
||||
if (!array_key_exists($courseid, self::$coursestudents)) {
|
||||
$students = [];
|
||||
|
@ -99,7 +99,7 @@ class gradingscanner {
|
|||
/**
|
||||
* Check if this scanner is usable (has an internal activity specific scanner)
|
||||
*/
|
||||
public function is_available() : bool {
|
||||
public function is_available(): bool {
|
||||
return $this->scanner !== null;
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ class gradingscanner {
|
|||
* Check if the gradable item this scanner scans has pending submissions for a specific user
|
||||
* @param int $userid ID of the user to check for
|
||||
*/
|
||||
public function pending($userid) : bool {
|
||||
public function pending($userid): bool {
|
||||
if (!array_key_exists($userid, $this->pendingcache)) {
|
||||
if ($this->scanner === null) {
|
||||
$this->pendingcache[$userid] = false;
|
||||
|
@ -122,7 +122,7 @@ class gradingscanner {
|
|||
* Webservice structure for basic info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function structure($value = VALUE_OPTIONAL) : \external_description {
|
||||
public static function structure($value = VALUE_OPTIONAL): \external_description {
|
||||
return new \external_single_structure([
|
||||
"ungraded" => new \external_value(PARAM_INT, 'number of ungraded submissions'),
|
||||
"completed" => new \external_value(PARAM_INT, 'number of completed students'),
|
||||
|
@ -135,7 +135,7 @@ class gradingscanner {
|
|||
/**
|
||||
* Webservice model for basic info
|
||||
*/
|
||||
public function model() : array {
|
||||
public function model(): array {
|
||||
// Upda.
|
||||
$students = self::get_course_students($this->courseid);
|
||||
$completed = 0;
|
||||
|
@ -173,7 +173,7 @@ class gradingscanner {
|
|||
* Check if a grade is considered passed according to the rules
|
||||
* @param grade_grade $grade
|
||||
*/
|
||||
private function grade_passed($grade) : bool {
|
||||
private function grade_passed($grade): bool {
|
||||
// Function copied from bistate aggregator to avoid reference mazes.
|
||||
global $DB;
|
||||
$table = "local_treestudyplan_gradecfg";
|
||||
|
|
|
@ -69,7 +69,7 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
|||
*/
|
||||
protected function initialize($configstr) {
|
||||
// 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}"));
|
||||
if ($val >= 0 && $val <= 100) {
|
||||
$this->cfg()->$key = floatval($val) / 100;
|
||||
|
@ -84,7 +84,7 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
|||
|
||||
if (is_array($config)) {
|
||||
// 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)) {
|
||||
$val = $config[$key];
|
||||
if ($val >= 0 && $val <= 100) {
|
||||
|
@ -142,7 +142,7 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
|||
* Determine if Aggregation method makes use of "required grades" in a course/module.
|
||||
* @return bool True if Aggregation method makes use of "required grades" in a course/module.
|
||||
*/
|
||||
public function use_required_grades(){
|
||||
public function use_required_grades() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
|||
$totalrequired = 0;
|
||||
$requiredmet = 0;
|
||||
|
||||
$minprogress = ($this->cfg()->accept_pending_as_submitted) ? completion::PENDING : completion::PROGRESS;
|
||||
$minprogress = ($this->cfg()->accept_pending_as_submitted) ? completion : :PENDING : completion::PROGRESS;
|
||||
|
||||
foreach ($completions as $index => $c) {
|
||||
|
||||
|
@ -181,7 +181,7 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
|||
$progress += ($c >= $minprogress) ? 1 : 0;
|
||||
$failed += ($c <= completion::FAILED) ? 1 : 0;
|
||||
|
||||
if (in_array($index,$required)) {
|
||||
if (in_array($index, $required)) {
|
||||
// Not using count($required) to prevent nonexistant indices in the required list from messing things up.
|
||||
$totalrequired += 1;
|
||||
if ($c >= completion::COMPLETED) {
|
||||
|
@ -193,10 +193,10 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
|||
$started = $progress + $failed;
|
||||
$allrequiredmet = ($requiredmet >= $totalrequired);
|
||||
|
||||
$fractioncompleted = ($total > 0) ? (floatval($completed) / floatval($total)) : 0.0;
|
||||
$fractionprogress = ($total > 0) ? (floatval($progress) / floatval($total)) : 0.0;
|
||||
$fractionfailed = ($total > 0) ? (floatval($failed) / floatval($total)) : 0.0;
|
||||
$fractionstarted = ($total > 0) ? (floatval($started) / floatval($total)) : 0.0;
|
||||
$fractioncompleted = ($total > 0) ? (floatval($completed) / floatval($total)): 0.0;
|
||||
$fractionprogress = ($total > 0) ? (floatval($progress) / floatval($total)): 0.0;
|
||||
$fractionfailed = ($total > 0) ? (floatval($failed) / floatval($total)): 0.0;
|
||||
$fractionstarted = ($total > 0) ? (floatval($started) / floatval($total)): 0.0;
|
||||
|
||||
if ($total == 0) {
|
||||
return completion::INCOMPLETE;
|
||||
|
@ -230,7 +230,7 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
|||
*/
|
||||
public function aggregate_course(courseinfo $courseinfo, studyitem $studyitem, $userid) {
|
||||
$course = $courseinfo->course();
|
||||
$coursefinished = ($course->enddate) ? ($course->enddate < time()) : false;
|
||||
$coursefinished = ($course->enddate) ? ($course->enddate < time()): false;
|
||||
// Note: studyitem condition config is not used in this aggregator.
|
||||
// Loop through all associated gradables and count the totals, completed, etc..
|
||||
$completions = [];
|
||||
|
@ -323,12 +323,12 @@ class bistate_aggregator extends \local_treestudyplan\aggregator {
|
|||
$gradeitem = $gradeinfo->get_gradeitem();
|
||||
$grade = $gradeitem->get_final($userid);
|
||||
$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)) {
|
||||
return completion::INCOMPLETE;
|
||||
} 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.
|
||||
// Therefor, we treat a NULL result as a reason to check the relevant gradingscanner for presence of pending items.
|
||||
|
||||
|
|
|
@ -68,13 +68,13 @@ class competency_aggregator extends \local_treestudyplan\aggregator {
|
|||
*/
|
||||
protected function initialize($configstr) {
|
||||
// First initialize with the defaults.
|
||||
foreach (["thresh_completed", ] as $key) {
|
||||
foreach (["thresh_completed" ] as $key) {
|
||||
$val = intval(get_config('local_treestudyplan', "competency_{$key}"));
|
||||
if ($val >= 0 && $val <= 100) {
|
||||
$this->cfg()->$key = floatval($val) / 100;
|
||||
}
|
||||
}
|
||||
foreach (["use_failed", ] as $key) {
|
||||
foreach (["use_failed" ] as $key) {
|
||||
$this->cfg()->$key = boolval(get_config('local_treestudyplan', "competency_{$key}"));
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ class competency_aggregator extends \local_treestudyplan\aggregator {
|
|||
|
||||
if (is_array($config)) {
|
||||
// Copy all valid config settings to this item.
|
||||
foreach (["thresh_completed", ] as $key) {
|
||||
foreach (["thresh_completed" ] as $key) {
|
||||
if (array_key_exists($key, $config)) {
|
||||
$val = $config[$key];
|
||||
if ($val >= 0 && $val <= 100) {
|
||||
|
@ -91,7 +91,7 @@ class competency_aggregator extends \local_treestudyplan\aggregator {
|
|||
}
|
||||
}
|
||||
}
|
||||
foreach (["use_failed",] as $key) {
|
||||
foreach (["use_failed" ] as $key) {
|
||||
if (array_key_exists($key, $config)) {
|
||||
$this->cfg()->$key = boolval($config[$key]);
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ class competency_aggregator extends \local_treestudyplan\aggregator {
|
|||
public function aggregate_course(courseinfo $courseinfo, studyitem $studyitem, $userid) {
|
||||
// Retrieve the course competencies
|
||||
$course = $courseinfo->course();
|
||||
$cci = new coursecompetencyinfo($course,$studyitem);
|
||||
$cci = new coursecompetencyinfo($course, $studyitem);
|
||||
|
||||
$competencies = $cci->course_competencies();
|
||||
if (count($competencies) == 0) {
|
||||
|
@ -180,14 +180,14 @@ class competency_aggregator extends \local_treestudyplan\aggregator {
|
|||
$requiredcount = 0;
|
||||
foreach ($competencies as $c) {
|
||||
$count += 1;
|
||||
$p = $cci->proficiency($c,$userid);
|
||||
$p = $cci->proficiency($c, $userid);
|
||||
if ($p->proficient) {
|
||||
$proficient += 1;
|
||||
}
|
||||
if ($p->courseproficient) {
|
||||
$courseproficient += 1;
|
||||
}
|
||||
if ($cci->is_required(($c))){
|
||||
if ($cci->is_required(($c))) {
|
||||
$requiredcount += 1;
|
||||
if ($p->proficient) {
|
||||
$requiredmet += 1;
|
||||
|
@ -196,9 +196,9 @@ class competency_aggregator extends \local_treestudyplan\aggregator {
|
|||
|
||||
}
|
||||
|
||||
// Determine minimum for
|
||||
// Determine minimum for
|
||||
$limit = $this->cfg()->thresh_completed * $count;
|
||||
$coursefinished = ($course->enddate) ? ($course->enddate < time()) : false;
|
||||
$coursefinished = ($course->enddate) ? ($course->enddate < time()): false;
|
||||
|
||||
if ($proficient >= $count && $requiredmet >= $requiredcount) {
|
||||
if ($limit < $count) {
|
||||
|
@ -280,7 +280,6 @@ class competency_aggregator extends \local_treestudyplan\aggregator {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine completion for a single grade and user
|
||||
* @param gradeinfo $gradeinfo Gradeinfo object for grade to check
|
||||
|
@ -291,5 +290,4 @@ class competency_aggregator extends \local_treestudyplan\aggregator {
|
|||
// COURSE COMPETENCIES DOESN'T REALLY USE THIS FUNCTION.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ class core_aggregator extends \local_treestudyplan\aggregator {
|
|||
/** @var bool */
|
||||
public const DEPRECATED = false;
|
||||
|
||||
|
||||
/**
|
||||
* Create new instance of aggregation method
|
||||
* @param string $configstr Aggregation configuration string
|
||||
|
@ -50,7 +49,7 @@ class core_aggregator extends \local_treestudyplan\aggregator {
|
|||
* @param string $configstr Aggregation configuration string
|
||||
*/
|
||||
protected function initialize($configstr) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -208,7 +207,6 @@ class core_aggregator extends \local_treestudyplan\aggregator {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine completion for a single grade and user
|
||||
* @param gradeinfo $gradeinfo Gradeinfo object for grade to check
|
||||
|
|
|
@ -133,7 +133,7 @@ class tristate_aggregator extends \local_treestudyplan\aggregator {
|
|||
*/
|
||||
public function aggregate_course(courseinfo $courseinfo, studyitem $studyitem, $userid) {
|
||||
$condition = self::DEFAULT_CONDITION;
|
||||
|
||||
|
||||
$list = [];
|
||||
foreach (gradeinfo::list_studyitem_gradables($studyitem) as $gi) {
|
||||
$list[] = $this->grade_completion($gi, $userid);
|
||||
|
@ -152,7 +152,7 @@ class tristate_aggregator extends \local_treestudyplan\aggregator {
|
|||
public function aggregate_junction(array $completion, studyitem $studyitem, $userid) {
|
||||
$completed = self::aggregate_completion($completion, $studyitem->conditions());
|
||||
// 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'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -169,7 +169,7 @@ class tristate_aggregator extends \local_treestudyplan\aggregator {
|
|||
if (empty($grade)) {
|
||||
return completion::INCOMPLETE;
|
||||
} 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.
|
||||
// Therefor, we treat a NULL result as a reason to check the relevant gradingscanner for presence of pending items.
|
||||
|
||||
|
|
|
@ -68,13 +68,13 @@ class webservicehelper {
|
|||
* @param string $capability The capability to scan for in the categories
|
||||
* @return boolean
|
||||
*/
|
||||
public static function has_capability_in_any_category($capability,$userid=null ) {
|
||||
public static function has_capability_in_any_category($capability, $userid=null ) {
|
||||
global $USER;
|
||||
if ($userid == null) {
|
||||
$userid = $USER->id;
|
||||
}
|
||||
$list = courseservice::user_tops($userid,$capability);
|
||||
|
||||
$list = courseservice::user_tops($userid, $capability);
|
||||
|
||||
return boolval(count($list) > 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,15 +70,15 @@ class randomimage {
|
|||
];
|
||||
|
||||
/**
|
||||
* Create a random polygon with number of points between 0 & $max_pts
|
||||
* Create a random polygon with number of points between 0 & $maxpts
|
||||
* @param \GdImage $im The image reource
|
||||
* @param integer $max_pts Max number of point to use
|
||||
* @param integer $maxpts Max number of point to use
|
||||
* @return void
|
||||
*/
|
||||
private function random_polygon($im, Int $max_pts = 20)
|
||||
private function random_polygon($im, Int $maxpts = 20)
|
||||
{
|
||||
$color = imagecolorallocatealpha($im, ...$this->random_color_alpha());
|
||||
$pts = $this->random_pts(\random_int(3, $max_pts));
|
||||
$pts = $this->random_pts(\random_int(3, $maxpts));
|
||||
imagefilledpolygon($im, $pts, $color);
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,6 @@ class randomimage {
|
|||
imagefilledarc($im, $cx, $cy, $w, $h, $s, $e, $col, $style);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates an array of random alpha color values.
|
||||
* @return Array [r, g, b, a]
|
||||
|
@ -116,7 +115,7 @@ class randomimage {
|
|||
}
|
||||
|
||||
/**
|
||||
* Generates a set of random points for a polygon [x1,y1, x2,y2,...]
|
||||
* Generates a set of random points for a polygon [x1, y1, x2, y2, ...]
|
||||
* @param integer $length Number of sets of points to generate
|
||||
* @return Array The resulting array of points
|
||||
*/
|
||||
|
@ -130,7 +129,7 @@ class randomimage {
|
|||
return $pts;
|
||||
}
|
||||
|
||||
public function __construct($shapes=3,$width=256,$height=256) {
|
||||
public function __construct($shapes=3, $width=256, $height=256) {
|
||||
$this->shapes = $shapes;
|
||||
$this->width = $width;
|
||||
$this->height = $height;
|
||||
|
@ -143,7 +142,7 @@ class randomimage {
|
|||
}
|
||||
|
||||
$this->name = $string.".png";
|
||||
|
||||
|
||||
$im = imagecreatetruecolor($this->width, $this->height);
|
||||
for ($i = 0; $i < $this->shapes; $i++) {
|
||||
switch(\random_int(1, 2)) {
|
||||
|
@ -155,8 +154,8 @@ class randomimage {
|
|||
break;
|
||||
}
|
||||
}
|
||||
$this->tempfile = \tempnam("/tmp","tsp");
|
||||
imagepng($im,$this->tempfile);
|
||||
$this->tempfile = \tempnam("/tmp", "tsp");
|
||||
imagepng($im, $this->tempfile);
|
||||
imagedestroy($im);
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ class period {
|
|||
/**
|
||||
* Shortcut to studyplan (page)'s aggregator
|
||||
*/
|
||||
public function aggregator() : aggregator {
|
||||
public function aggregator(): aggregator {
|
||||
return $this->page->aggregator();
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ class period {
|
|||
$period = self::find_by_id($id);
|
||||
} catch (\dml_missing_record_exception $x) {
|
||||
// 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 .
|
||||
$pcount = $page->periods();
|
||||
$ystart = $page->startdate()->getTimestamp();
|
||||
|
@ -118,7 +118,7 @@ class period {
|
|||
}
|
||||
|
||||
// Continue period numbers if so configured
|
||||
if (get_config("local_treestudyplan","continueperiodnumberingnewpage")) {
|
||||
if (get_config("local_treestudyplan", "continueperiodnumberingnewpage")) {
|
||||
$offset = 0;
|
||||
foreach (studyplanpage::find_studyplan_children($page->studyplan()) as $p) {
|
||||
if ($p->id() != $page->id()) {
|
||||
|
@ -142,7 +142,6 @@ class period {
|
|||
return $period;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find all periods registered to a studyplan in sequence
|
||||
* @param studyplanpage $page Studyplan page to find periods for
|
||||
|
@ -181,7 +180,7 @@ class period {
|
|||
* Return associated studyplan
|
||||
* @return studyplan
|
||||
*/
|
||||
public function studyplan() : studyplan {
|
||||
public function studyplan(): studyplan {
|
||||
return $this->page->studyplan();
|
||||
}
|
||||
|
||||
|
@ -242,7 +241,7 @@ class period {
|
|||
* Webservice structure for basic info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of period'),
|
||||
"fullname" => new \external_value(PARAM_TEXT, 'Full name of period'),
|
||||
|
@ -259,14 +258,14 @@ class period {
|
|||
* @return array Webservice data model
|
||||
*/
|
||||
public function model() {
|
||||
$timeless = get_config("local_treestudyplan","timelessperiods");
|
||||
$timeless = get_config("local_treestudyplan", "timelessperiods");
|
||||
return [
|
||||
'id' => $this->r->id,
|
||||
'fullname' => $this->r->fullname,
|
||||
'shortname' => $this->r->shortname,
|
||||
'period' => $this->r->period,
|
||||
'startdate' => ($timeless)?0:$this->r->startdate,
|
||||
'enddate' => ($timeless)?0:$this->r->enddate,
|
||||
'startdate' => ($timeless) ? 0 : $this->r->startdate,
|
||||
'enddate' => ($timeless) ? 0 : $this->r->enddate,
|
||||
'timeless' => $timeless,
|
||||
];
|
||||
}
|
||||
|
@ -276,7 +275,7 @@ class period {
|
|||
* 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']
|
||||
*/
|
||||
public static function add($fields) : self {
|
||||
public static function add($fields): self {
|
||||
global $DB;
|
||||
|
||||
if (!isset($fields['page_id'])) {
|
||||
|
@ -305,7 +304,7 @@ class period {
|
|||
* Edit period properties
|
||||
* @param array $fields Properties for ['fullname', 'shortname', 'startdate', 'enddate']
|
||||
*/
|
||||
public function edit($fields) : self {
|
||||
public function edit($fields): self {
|
||||
global $DB;
|
||||
|
||||
$pages = self::find_for_page($this->page());
|
||||
|
@ -313,7 +312,7 @@ class period {
|
|||
$next = (count($pages) > $this->period()) ? $pages[$this->period() + 1] : null;
|
||||
|
||||
$editable = ['fullname', 'shortname', 'startdate', 'enddate'];
|
||||
$info = ['id' => $this->id, ];
|
||||
$info = ['id' => $this->id ];
|
||||
foreach ($editable as $f) {
|
||||
if (array_key_exists($f, $fields)) {
|
||||
$info[$f] = $fields[$f];
|
||||
|
@ -347,7 +346,7 @@ class period {
|
|||
/**
|
||||
* Delete period
|
||||
*/
|
||||
public function delete() : success {
|
||||
public function delete(): success {
|
||||
global $DB;
|
||||
$DB->delete_records(self::TABLE, ['id' => $this->id]);
|
||||
return success::success();
|
||||
|
@ -357,7 +356,7 @@ class period {
|
|||
* Webservice structure for list of periods in page
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function page_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function page_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_multiple_structure(self::structure(), "The periods in the page", $value);
|
||||
}
|
||||
|
||||
|
@ -366,9 +365,9 @@ class period {
|
|||
* @param studyplanpage $page The page to create the model for
|
||||
* @return array Webservice data model
|
||||
*/
|
||||
public static function page_model(studyplanpage $page) : array {
|
||||
public static function page_model(studyplanpage $page): array {
|
||||
$model = [];
|
||||
foreach (self::find_for_page($page,true) as $p) {
|
||||
foreach (self::find_for_page($page, true) as $p) {
|
||||
$model[] = $p->model();
|
||||
}
|
||||
return $model;
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
namespace local_treestudyplan;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
@ -30,7 +29,6 @@ use DateTime;
|
|||
use moodle_url;
|
||||
use stdClass;
|
||||
|
||||
|
||||
/**
|
||||
* Handle badge information in the same style as the other classes
|
||||
*/
|
||||
|
@ -38,7 +36,7 @@ class premium extends \external_api {
|
|||
|
||||
// Toggle the variable below to enable support for premium stuff.
|
||||
// If set to false, all premium features will be enabled and no premium settings panel will be visible.
|
||||
private static $premium_supported = false;
|
||||
private static $premiumsupported = false;
|
||||
|
||||
private static $premiumcrt = "-----BEGIN CERTIFICATE-----
|
||||
MIIDSzCCAjMCFFlyhmKf1fN7U5lQL/dtlsyP24AQMA0GCSqGSIb3DQEBCwUAMGEx
|
||||
|
@ -64,31 +62,31 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
private static $cachedpremiumstatus = null;
|
||||
|
||||
public static function supported() {
|
||||
return self::$premium_supported;
|
||||
return self::$premiumsupported;
|
||||
}
|
||||
|
||||
private static function decrypt($encrypted) {
|
||||
// Get the public key.
|
||||
$key = \openssl_get_publickey(self::$premiumcrt);
|
||||
if ($key === false ){
|
||||
if ($key === false ) {
|
||||
throw new \ValueError("Error parsing public key data)");
|
||||
}
|
||||
// Determine the key size.
|
||||
$keysize = \openssl_pkey_get_details($key)["bits"];
|
||||
//
|
||||
//
|
||||
$blocksize = ($keysize / 8); // Bits / 8. Whether padded or not.
|
||||
|
||||
// Decode data in
|
||||
|
||||
// Decode data in
|
||||
$b64 = \base64_decode($encrypted);
|
||||
if ($b64 === false) {
|
||||
throw new \ValueError("Error in base64 decoding");
|
||||
}
|
||||
|
||||
$data = \str_split($b64,$blocksize);
|
||||
$data = \str_split($b64, $blocksize);
|
||||
$decrypted = "";
|
||||
$i = 0;
|
||||
foreach($data as $chunk) {
|
||||
if (\openssl_public_decrypt($chunk,$dchunk,$key, \OPENSSL_PKCS1_PADDING)) {
|
||||
if (\openssl_public_decrypt($chunk, $dchunk, $key, \OPENSSL_PKCS1_PADDING)) {
|
||||
$decrypted .= $dchunk;
|
||||
} else {
|
||||
throw new \ValueError("Error decrypting chunk $i ({$blocksize} bytes)");
|
||||
|
@ -104,23 +102,23 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
|
||||
return $decrypted;
|
||||
}
|
||||
|
||||
|
||||
private static function trim_headers($data) {
|
||||
// Headers are repeated in this function for easier testing and copy-pasting into other projects.
|
||||
$START_HEADER = "----- BEGIN ACTIVATION KEY -----";
|
||||
$END_HEADER = "----- END ACTIVATION KEY -----";
|
||||
|
||||
$parts = preg_split("/\r?\n/",\trim($data));
|
||||
$STARTHEADER = "----- BEGIN ACTIVATION KEY -----";
|
||||
$ENDHEADER = "----- END ACTIVATION KEY -----";
|
||||
|
||||
$parts = preg_split("/\r?\n/", \trim($data));
|
||||
if (count($parts) > 2) {
|
||||
$start = -1;
|
||||
$end = -1;
|
||||
for($i = 0; $i < count($parts); $i++) {
|
||||
$p = trim(preg_replace('/\s+/u', ' ', $parts[$i])); // Make sure all unicode spaces are converted to normal spaces before comparing...
|
||||
|
||||
if ( $p == $START_HEADER ) {
|
||||
if ( $p == $STARTHEADER ) {
|
||||
$start = $i+1;
|
||||
}
|
||||
if ($start > 0 && $p == $END_HEADER) {
|
||||
if ($start > 0 && $p == $ENDHEADER) {
|
||||
$end = $i;
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +127,7 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
throw new \ValueError("Invalid activation key wrappers");
|
||||
} else {
|
||||
$keyslice = array_slice($parts, $start, $end - $start);
|
||||
return implode("\n",$keyslice);
|
||||
return implode("\n", $keyslice);
|
||||
}
|
||||
} else {
|
||||
throw new \ValueError("Invalid activation key");
|
||||
|
@ -141,7 +139,7 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
* @return bool
|
||||
*/
|
||||
public static function enabled() {
|
||||
if (self::$premium_supported) {
|
||||
if (self::$premiumsupported) {
|
||||
$status = self::premiumStatus();
|
||||
return $status->enabled;
|
||||
} else {
|
||||
|
@ -154,10 +152,10 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
* @param string $intent The intent to search for
|
||||
* @return bool
|
||||
*/
|
||||
public static function has_intent($intent){
|
||||
public static function has_intent($intent) {
|
||||
$status = self::premiumStatus();
|
||||
if ($status->enabled) {
|
||||
return \in_array(\strtolower($intent),$status->intents);
|
||||
return \in_array(\strtolower($intent), $status->intents);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -166,25 +164,25 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
public static function debuginfo() {
|
||||
$s = "<pre>";
|
||||
try {
|
||||
$activationkey = \get_config("local_treestudyplan","premium_key");
|
||||
$activationkey = \get_config("local_treestudyplan", "premium_key");
|
||||
if (strlen($activationkey) > 0) {
|
||||
$keydata = self::trim_headers($activationkey);
|
||||
$json = self::decrypt($keydata);
|
||||
$s .= "Decoded key data:\n----\n";
|
||||
$s .= $json . "\n----\n";
|
||||
$decoded = \json_decode($json,false);
|
||||
$decoded = \json_decode($json, false);
|
||||
$s .= "Read as object:\n----\n";
|
||||
$s .= print_r($decoded,true) ."\n----\n";
|
||||
$s .= print_r($decoded, true) ."\n----\n";
|
||||
$status = self::premiumStatus();
|
||||
$s .= "Parsed premium status block:\n----\n";
|
||||
$s .= print_r($status,true) ."\n----\n";
|
||||
$s .= print_r($status, true) ."\n----\n";
|
||||
$s .= "Message: " . self::statusdescription() . "\n";
|
||||
} else {
|
||||
$s .= "Premium key empty";
|
||||
}
|
||||
} catch (\Throwable $x) {
|
||||
$s .= "!!! " . get_class($x) . ": " . $x->getCode() . " | " . $x->getMessage(). "\n";
|
||||
$stack = explode("\n",$x->getTraceAsString());
|
||||
$stack = explode("\n", $x->getTraceAsString());
|
||||
foreach ($stack as $l) {
|
||||
$s .= " " . trim($l) ."\n";
|
||||
}
|
||||
|
@ -193,13 +191,13 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
$s.="</pre>";
|
||||
return $s;
|
||||
}
|
||||
/**
|
||||
/**
|
||||
* Determine, cache and retrieve premium status
|
||||
* @return object
|
||||
*/
|
||||
protected static function premiumStatus() {
|
||||
if (!isset(self::$cachedpremiumstatus)) {
|
||||
|
||||
|
||||
// Initialize default object.
|
||||
$o = new \stdClass;
|
||||
$o->enabled = false;
|
||||
|
@ -210,28 +208,28 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
$o->expired = false;
|
||||
$o->issued = "";
|
||||
try {
|
||||
$activationkey = \get_config("local_treestudyplan","premium_key");
|
||||
$activationkey = \get_config("local_treestudyplan", "premium_key");
|
||||
if (strlen($activationkey) > 0) {
|
||||
|
||||
|
||||
$keydata = self::trim_headers($activationkey);
|
||||
$json = self::decrypt($keydata);
|
||||
$decoded = \json_decode($json,false);
|
||||
$decoded = \json_decode($json, false);
|
||||
|
||||
if (is_object($decoded)) {
|
||||
|
||||
// Copy basic data/
|
||||
$keys = ["name","website","expires","issued"];
|
||||
$keys = ["name", "website", "expires", "issued"];
|
||||
foreach ( $keys as $k) {
|
||||
if (isset($decoded->$k)) {
|
||||
$o->$k = $decoded->$k;
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($decoded->intent)) {
|
||||
$o->intents = explode(",",$decoded->intent);
|
||||
if (!empty($decoded->intent)) {
|
||||
$o->intents = explode(", ", $decoded->intent);
|
||||
}
|
||||
|
||||
// Convert dates to DateTime for
|
||||
// Convert dates to DateTime for
|
||||
$now = new \DateTime();
|
||||
$issuedate = new \DateTime($o->issued);
|
||||
$expirydate = new \DateTime(); // Default to now
|
||||
|
@ -244,7 +242,7 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
} catch (\Exception $x) {}
|
||||
}
|
||||
|
||||
if ( \in_array('treestudyplan',$o->intents)
|
||||
if ( \in_array('treestudyplan', $o->intents)
|
||||
&& !empty($o->issued)
|
||||
&& self::website_match($o->website)
|
||||
) {
|
||||
|
@ -256,17 +254,17 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
$o->enabled = false;
|
||||
}
|
||||
// Format dates localized.
|
||||
$o->issued = \userdate($issuedate->getTimestamp(),\get_string('strftimedate','langconfig'));
|
||||
$o->issued = \userdate($issuedate->getTimestamp(), \get_string('strftimedate', 'langconfig'));
|
||||
if ($o->expires == "never") {
|
||||
$o->expires = \get_string("premium:never",'local_treestudyplan');
|
||||
$o->expires = \get_string("premium:never", 'local_treestudyplan');
|
||||
} else {
|
||||
$o->expires = \userdate($expirydate->getTimestamp(),\get_string('strftimedate','langconfig'));
|
||||
$o->expires = \userdate($expirydate->getTimestamp(), \get_string('strftimedate', 'langconfig'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\ValueError $x) {
|
||||
$o->status = \get_string("premium:invalidactivationcontent","local_treestudyplan");
|
||||
$o->status = \get_string("premium:invalidactivationcontent", "local_treestudyplan");
|
||||
}
|
||||
self::$cachedpremiumstatus = $o;
|
||||
|
||||
|
@ -280,13 +278,13 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
private static function website_match($key) {
|
||||
global $CFG;
|
||||
$site = $CFG->wwwroot;
|
||||
|
||||
|
||||
// Add double slashes to key and site if no scheme is set.
|
||||
// Basically: if no double slashes present before any dots,slashes or @s.
|
||||
if(!\preg_match_all('#^[^./@]*?//#',$key )) {
|
||||
// Basically: if no double slashes present before any dots, slashes or @s.
|
||||
if (!\preg_match_all('#^[^./@]*?//#', $key )) {
|
||||
$key = "//".$key;
|
||||
}
|
||||
if(!\preg_match_all('#^[^./@]*?//#',$site)) {
|
||||
if (!\preg_match_all('#^[^./@]*?//#', $site)) {
|
||||
$site = "//".$site;
|
||||
}
|
||||
// Use parse_url() to split path and host.
|
||||
|
@ -304,17 +302,17 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
}
|
||||
|
||||
// First match the host part.
|
||||
$keyparts = \array_reverse(\explode(".",$keyurl->host));
|
||||
$siteparts = \array_reverse(\explode(".",$siteurl->host));
|
||||
$keyparts = \array_reverse(\explode(".", $keyurl->host));
|
||||
$siteparts = \array_reverse(\explode(".", $siteurl->host));
|
||||
|
||||
// Trim starting www from both parts, since site.domain and www.site.domain should be treated as the same.
|
||||
if (($x = \array_pop($keyparts)) != "www") {\array_push($keyparts,$x);}
|
||||
if (($x = \array_pop($siteparts)) != "www") {\array_push($siteparts,$x);}
|
||||
if (($x = \array_pop($keyparts)) != "www") {\array_push($keyparts, $x);}
|
||||
if (($x = \array_pop($siteparts)) != "www") {\array_push($siteparts, $x);}
|
||||
|
||||
for ($i = 0; $i < count($keyparts); $i++) {
|
||||
// No match if the site does not have a part, but the key does. Unless the key part is *
|
||||
if (!isset($siteparts[$i]) ) {
|
||||
if($keyparts[$i] != "*") {
|
||||
if ($keyparts[$i] != "*") {
|
||||
return false;
|
||||
} else {
|
||||
$i++; //increment $i by one before break, to make sure the comparison following this loop holds.
|
||||
|
@ -324,7 +322,7 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
|
||||
// Now do a proper case insensitive check for matching.
|
||||
// Uses fnmatch to easily handle shell type wildcards.
|
||||
if ( ! \fnmatch($keyparts[$i],$siteparts[$i],\FNM_CASEFOLD)) {
|
||||
if ( ! \fnmatch($keyparts[$i], $siteparts[$i], \FNM_CASEFOLD)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -335,39 +333,39 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
|
||||
// If we made it here then the host part matches. Now check the path.
|
||||
// If path is /*, matches all subpaths including /
|
||||
$keypath = empty($keyurl->path)?"/":$keyurl->path;
|
||||
$sitepath = empty($siteurl->path)?"/":$siteurl->path;
|
||||
|
||||
$keypath = empty($keyurl->path) ? "/" : $keyurl->path;
|
||||
$sitepath = empty($siteurl->path) ? "/" : $siteurl->path;
|
||||
|
||||
// Trim trailing / from both paths before comparison
|
||||
if (\strlen($sitepath) > 1) {
|
||||
$sitepath = \rtrim($sitepath,"/");
|
||||
$sitepath = \rtrim($sitepath, "/");
|
||||
}
|
||||
if (\strlen($keypath) > 1) {
|
||||
$keypath = \rtrim($keypath,"/");
|
||||
$keypath = \rtrim($keypath, "/");
|
||||
}
|
||||
|
||||
// Do a case insensitive fnmatch on the site so wildcards are matched too.
|
||||
return \fnmatch($keypath,$sitepath,\FNM_CASEFOLD);
|
||||
return \fnmatch($keypath, $sitepath, \FNM_CASEFOLD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameter description for webservice function get_premiumstatus
|
||||
*/
|
||||
public static function get_premiumstatus_parameters() : \external_function_parameters {
|
||||
public static function get_premiumstatus_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return value description for webservice function get_premiumstatus
|
||||
*/
|
||||
public static function get_premiumstatus_returns() : \external_description {
|
||||
public static function get_premiumstatus_returns(): \external_description {
|
||||
return new \external_single_structure([
|
||||
"enabled" => new \external_value(PARAM_BOOL, 'premium status enabled'),
|
||||
"website" => new \external_value(PARAM_TEXT, 'premium registration website'),
|
||||
"name" => new \external_value(PARAM_TEXT, 'premium registration name'),
|
||||
"expires" => new \external_value(PARAM_TEXT, 'premium registration expiry date'),
|
||||
"expired" => new \external_value(PARAM_BOOL, 'premium status expired'),
|
||||
"intents" => new \external_multiple_structure(new \external_value(PARAM_TEXT),'additional intents included in the license '),
|
||||
"intents" => new \external_multiple_structure(new \external_value(PARAM_TEXT), 'additional intents included in the license '),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -376,7 +374,7 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
* @return object
|
||||
*/
|
||||
public static function get_premiumstatus() {
|
||||
if (self::$premium_supported) {
|
||||
if (self::$premiumsupported) {
|
||||
$status = self::premiumStatus();
|
||||
$keys = [
|
||||
"enabled",
|
||||
|
@ -386,7 +384,7 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
"expired",
|
||||
"intents",
|
||||
];
|
||||
|
||||
|
||||
$result = [];
|
||||
foreach ( $keys as $param) {
|
||||
$result[$param] = $status->$param;
|
||||
|
@ -416,19 +414,19 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
$msg->issued = $status->issued;
|
||||
$msg->expires = $status->expires;
|
||||
if ($status->website != "*") {
|
||||
$msg->sitestatus = \get_string("premium:onsite",'local_treestudyplan',$status);
|
||||
$msg->sitestatus = \get_string("premium:onsite", 'local_treestudyplan', $status);
|
||||
} else {
|
||||
$msg->sitestatus = \get_string("premium:anywhere",'local_treestudyplan');
|
||||
$msg->sitestatus = \get_string("premium:anywhere", 'local_treestudyplan');
|
||||
}
|
||||
|
||||
if($status->enabled) {
|
||||
return \get_string("premium:active",'local_treestudyplan',$msg);
|
||||
if ($status->enabled) {
|
||||
return \get_string("premium:active", 'local_treestudyplan', $msg);
|
||||
} else if ($status->expired) {
|
||||
return \get_string("premium:expired",'local_treestudyplan',$msg);
|
||||
return \get_string("premium:expired", 'local_treestudyplan', $msg);
|
||||
} else if (!self::website_match($status->website)) {
|
||||
return \get_string("premium:siteinvalid",'local_treestudyplan',$status->website);
|
||||
return \get_string("premium:siteinvalid", 'local_treestudyplan', $status->website);
|
||||
} else {
|
||||
return \get_string("premium:notregistered",'local_treestudyplan',$msg);
|
||||
return \get_string("premium:notregistered", 'local_treestudyplan', $msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -437,7 +435,7 @@ Klc5I28bGbvxIV5pnL6ZSjHEDp2WreM8HB0XFJwU+Q==
|
|||
*/
|
||||
public static function require_premium($message="premiumfeature:warning") {
|
||||
if (! self::enabled()) {
|
||||
throw new \moodle_exception($message,"local_treestudyplan");
|
||||
throw new \moodle_exception($message, "local_treestudyplan");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ class provider implements \core_privacy\local\metadata\provider,
|
|||
* @param int $userid The user to search.
|
||||
* @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
|
||||
*/
|
||||
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->add_system_context(); // For invitations.
|
||||
|
||||
|
@ -260,7 +260,7 @@ class provider implements \core_privacy\local\metadata\provider,
|
|||
// Determine the relevant plan_ids for this context.
|
||||
$sql = "SELECT s.id FROM {local_treestudyplan}
|
||||
WHERE ( s.context_id IS NULL OR s.context_id == 0 OR s.context_id = :contextid)) ";
|
||||
$planids = $DB->get_fieldset_sql($sql, ["contextid" => $context->id, ]);
|
||||
$planids = $DB->get_fieldset_sql($sql, ["contextid" => $context->id ]);
|
||||
// If plan ids not empty, they will be processed later.
|
||||
|
||||
// Also delete all invitations for these users.
|
||||
|
@ -270,7 +270,7 @@ class provider implements \core_privacy\local\metadata\provider,
|
|||
} else if ($context->contextlevel == CONTEXT_COURSECAT) {
|
||||
$sql = "SELECT s.id FROM {local_treestudyplan}
|
||||
WHERE (s.context_id = :contextid)";
|
||||
$planids = $DB->get_fieldset_sql($sql, ["contextid" => $context->id, ]);
|
||||
$planids = $DB->get_fieldset_sql($sql, ["contextid" => $context->id ]);
|
||||
// If plan ids not empty, they will be processed later.
|
||||
}
|
||||
|
||||
|
|
|
@ -45,12 +45,12 @@ class reportinvite_form extends moodleform {
|
|||
$mform->addElement('hidden', 'update', 0);
|
||||
$mform->setType('update', PARAM_INT);
|
||||
|
||||
$mform->addElement('text', 'name', get_string('invite_name', 'local_treestudyplan'), array('size' => 50));
|
||||
$mform->addElement('text', 'name', get_string('invite_name', 'local_treestudyplan'), ['size' => 50]);
|
||||
$mform->setType('name', PARAM_NOTAGS); // Set type of element.
|
||||
$mform->setDefault('name', ''); // Default value.
|
||||
$mform->addRule('name', get_string('required'), 'required', null, 'client');
|
||||
|
||||
$mform->addElement('text', 'email', get_string('invite_email', 'local_treestudyplan'), array('size' => 20));
|
||||
$mform->addElement('text', 'email', get_string('invite_email', 'local_treestudyplan'), ['size' => 20]);
|
||||
$mform->setType('email', PARAM_NOTAGS); // Set type of element.
|
||||
$mform->setDefault('email', ''); // Default value.
|
||||
$mform->addRule('email', get_string('required'), 'required', null, 'client');
|
||||
|
@ -68,7 +68,7 @@ class reportinvite_form extends moodleform {
|
|||
* @return array validation data
|
||||
*/
|
||||
public function validation($data, $files) {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -40,19 +40,18 @@ class reportservice extends \external_api {
|
|||
*/
|
||||
const CAP_VIEW = "local/treestudyplan:viewuserreports";
|
||||
|
||||
|
||||
public static function get_report_structure_parameters() : \external_function_parameters {
|
||||
public static function get_report_structure_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters([
|
||||
"pageid" => new \external_value(PARAM_INT, 'id of studyplan page'),
|
||||
"firstperiod" => new \external_value(PARAM_INT, 'first period to include in report',VALUE_DEFAULT),
|
||||
"lastperiod" => new \external_value(PARAM_INT, 'last period to include in report',VALUE_DEFAULT),
|
||||
"firstperiod" => new \external_value(PARAM_INT, 'first period to include in report', VALUE_DEFAULT),
|
||||
"lastperiod" => new \external_value(PARAM_INT, 'last period to include in report', VALUE_DEFAULT),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return value description for webservice function list_user_studyplans
|
||||
*/
|
||||
public static function get_report_structure_returns() : \external_description {
|
||||
public static function get_report_structure_returns(): \external_description {
|
||||
return new \external_single_structure([
|
||||
"periods" => new \external_multiple_structure(new \external_single_structure([
|
||||
"period" => period::structure(),
|
||||
|
@ -75,14 +74,14 @@ class reportservice extends \external_api {
|
|||
* @param int|null $lastperiod Last period to include in report
|
||||
* @return object
|
||||
*/
|
||||
public static function get_report_structure($pageid,$firstperiod=null,$lastperiod=null) {
|
||||
public static function get_report_structure($pageid, $firstperiod=null, $lastperiod=null) {
|
||||
$page = studyplanpage::find_by_id($pageid);
|
||||
webservicehelper::require_capabilities(self::CAP_VIEW,$page->studyplan()->context());
|
||||
webservicehelper::require_capabilities(self::CAP_VIEW, $page->studyplan()->context());
|
||||
|
||||
$plan = $page->studyplan();
|
||||
if (empty($firstperiod)) {
|
||||
$firstperiod = 1;
|
||||
}
|
||||
}
|
||||
if (empty($lastperiod)) {
|
||||
// Index for periods starts at 1, so the period count is same as length
|
||||
$lastperiod = $page->periods();
|
||||
|
@ -111,30 +110,29 @@ class reportservice extends \external_api {
|
|||
"line" => $line->simple_model(),
|
||||
"items" => [],
|
||||
];
|
||||
$items = studyitem::search_studyline_children($line,$i,studyitem::COURSE);
|
||||
$items = studyitem::search_studyline_children($line, $i, studyitem::COURSE);
|
||||
if (count($items) > 0) {
|
||||
foreach ($items as $item) {
|
||||
$lmodel["items"][] = $item->editor_model();
|
||||
}
|
||||
|
||||
|
||||
// Only include the line if it has actual children - saves us from muddying up the report.
|
||||
$pmodel['lines'][] = $lmodel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$model["periods"][] = $pmodel;
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
public static function get_report_data_parameters() : \external_function_parameters {
|
||||
public static function get_report_data_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters([
|
||||
"pageid" => new \external_value(PARAM_INT, 'id of studyplan page'),
|
||||
"userid" => new \external_value(PARAM_INT, 'id of user'),
|
||||
"firstperiod" => new \external_value(PARAM_INT, 'first period to include in report',VALUE_DEFAULT),
|
||||
"lastperiod" => new \external_value(PARAM_INT, 'last period to include in report',VALUE_DEFAULT),
|
||||
"firstperiod" => new \external_value(PARAM_INT, 'first period to include in report', VALUE_DEFAULT),
|
||||
"lastperiod" => new \external_value(PARAM_INT, 'last period to include in report', VALUE_DEFAULT),
|
||||
|
||||
]);
|
||||
}
|
||||
|
@ -142,22 +140,21 @@ class reportservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function list_user_studyplans
|
||||
*/
|
||||
public static function get_report_data_returns() : \external_description {
|
||||
public static function get_report_data_returns(): \external_description {
|
||||
return new \external_multiple_structure(studyitem::user_structure(), "Information per studyitem");
|
||||
}
|
||||
|
||||
|
||||
public static function get_report_data($pageid,$userid,$firstperiod=null,$lastperiod=null) {
|
||||
public static function get_report_data($pageid, $userid, $firstperiod=null, $lastperiod=null) {
|
||||
$page = studyplanpage::find_by_id($pageid);
|
||||
webservicehelper::require_capabilities(self::CAP_VIEW,$page->studyplan()->context());
|
||||
webservicehelper::require_capabilities(self::CAP_VIEW, $page->studyplan()->context());
|
||||
$plan = $page->studyplan();
|
||||
if (!$plan->has_linked_user($userid)) {
|
||||
throw new \moodle_exception("error:usernotassociated","local_treestudyplan");
|
||||
throw new \moodle_exception("error:usernotassociated", "local_treestudyplan");
|
||||
}
|
||||
|
||||
if (empty($firstperiod)) {
|
||||
$firstperiod = 1;
|
||||
}
|
||||
}
|
||||
if (empty($lastperiod)) {
|
||||
// Index for periods starts at 1, so the period count is same as length
|
||||
$lastperiod = $page->periods();
|
||||
|
@ -170,7 +167,7 @@ class reportservice extends \external_api {
|
|||
for($i = $firstperiod; $i <= $lastperiod; $i++) {
|
||||
$lines = studyline::find_page_children($page);
|
||||
foreach ($lines as $line) {
|
||||
$items = studyitem::search_studyline_children($line,$i,studyitem::COURSE);
|
||||
$items = studyitem::search_studyline_children($line, $i, studyitem::COURSE);
|
||||
if (count($items) > 0) {
|
||||
foreach ($items as $item) {
|
||||
$model[] = $item->user_model($userid);
|
||||
|
@ -183,9 +180,7 @@ class reportservice extends \external_api {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function get_report_details_parameters() : \external_function_parameters {
|
||||
public static function get_report_details_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters([
|
||||
"itemid" => new \external_value(PARAM_INT, 'id of studyitem'),
|
||||
"userid" => new \external_value(PARAM_INT, 'id of user'),
|
||||
|
@ -195,7 +190,7 @@ class reportservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function list_user_studyplans
|
||||
*/
|
||||
public static function get_report_details_returns() : \external_description {
|
||||
public static function get_report_details_returns(): \external_description {
|
||||
return studyitem::user_structure();
|
||||
}
|
||||
|
||||
|
@ -205,16 +200,15 @@ class reportservice extends \external_api {
|
|||
* @param int $userid ID of user to check specific info for
|
||||
* @return array
|
||||
*/
|
||||
public static function get_report_details($itemid,$userid) {
|
||||
public static function get_report_details($itemid, $userid) {
|
||||
$item = studyitem::find_by_id($itemid);
|
||||
$plan = $item->studyline()->studyplan();
|
||||
webservicehelper::require_capabilities(self::CAP_VIEW,$plan->context());
|
||||
webservicehelper::require_capabilities(self::CAP_VIEW, $plan->context());
|
||||
if (!$plan->has_linked_user($userid)) {
|
||||
throw new \moodle_exception("error:usernotassociated","local_treestudyplan");
|
||||
throw new \moodle_exception("error:usernotassociated", "local_treestudyplan");
|
||||
}
|
||||
return $item->user_model($userid);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -48,11 +48,11 @@ class studentstudyplanservice extends \external_api {
|
|||
* list_user_studyplans *
|
||||
* *
|
||||
************************/
|
||||
|
||||
|
||||
/**
|
||||
* Parameter description for webservice function list_user_studyplans
|
||||
*/
|
||||
public static function list_user_studyplans_parameters() : \external_function_parameters {
|
||||
public static function list_user_studyplans_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters([
|
||||
"userid" => new \external_value(PARAM_INT, 'id of student', VALUE_DEFAULT),
|
||||
]);
|
||||
|
@ -61,7 +61,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()
|
||||
);
|
||||
|
@ -95,7 +95,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function get_user_studyplan
|
||||
*/
|
||||
public static function get_user_studyplan_parameters() : \external_function_parameters {
|
||||
public static function get_user_studyplan_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"userid" => new \external_value(PARAM_INT, 'id of user'),
|
||||
"studyplanid" => new \external_value(PARAM_INT, 'id of specific studyplan to provide'),
|
||||
|
@ -105,7 +105,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();
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ class studentstudyplanservice extends \external_api {
|
|||
}
|
||||
|
||||
if ($studyplan->exist_for_user($userid)) {
|
||||
|
||||
|
||||
$model = $studyplan->user_model($userid);
|
||||
return $model;
|
||||
} else {
|
||||
|
@ -143,7 +143,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function get_user_page
|
||||
*/
|
||||
public static function get_user_page_parameters() : \external_function_parameters {
|
||||
public static function get_user_page_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"userid" => new \external_value(PARAM_INT, 'id of user'),
|
||||
"pageid" => new \external_value(PARAM_INT, 'id of specific studyplan to provide'),
|
||||
|
@ -153,7 +153,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function get_user_page
|
||||
*/
|
||||
public static function get_user_page_returns() : \external_description {
|
||||
public static function get_user_page_returns(): \external_description {
|
||||
return studyplan::user_structure();
|
||||
}
|
||||
|
||||
|
@ -185,7 +185,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function list_invited_studyplan
|
||||
*/
|
||||
public static function list_invited_studyplans_parameters() : \external_function_parameters {
|
||||
public static function list_invited_studyplans_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"invitekey" => new \external_value(PARAM_RAW, 'invite key'),
|
||||
] );
|
||||
|
@ -194,7 +194,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function list_invited_studyplan
|
||||
*/
|
||||
public static function list_invited_studyplans_returns() : \external_description {
|
||||
public static function list_invited_studyplans_returns(): \external_description {
|
||||
return new \external_multiple_structure(
|
||||
studyplan::simple_structure()
|
||||
);
|
||||
|
@ -208,7 +208,7 @@ class studentstudyplanservice extends \external_api {
|
|||
public static function list_invited_studyplans($invitekey) {
|
||||
global $DB;
|
||||
// First check if studyplan sharing is enabled.
|
||||
if (!get_config("local_treestudyplan","enableplansharing")) {
|
||||
if (!get_config("local_treestudyplan", "enableplansharing")) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -243,7 +243,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function get_invited_studyplan
|
||||
*/
|
||||
public static function get_invited_studyplan_parameters() : \external_function_parameters {
|
||||
public static function get_invited_studyplan_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"invitekey" => new \external_value(PARAM_RAW, 'invite key'),
|
||||
"studyplanid" => new \external_value(PARAM_INT, 'studyplan_id'),
|
||||
|
@ -253,7 +253,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 studyplan::user_structure();
|
||||
}
|
||||
|
||||
|
@ -263,10 +263,10 @@ class studentstudyplanservice extends \external_api {
|
|||
* @param int $studyplanid ID of the studyplan to retrieve
|
||||
* @return array
|
||||
*/
|
||||
public static function get_invited_studyplan($invitekey,$studyplanid) {
|
||||
public static function get_invited_studyplan($invitekey, $studyplanid) {
|
||||
global $DB;
|
||||
// First check if studyplan sharing is enabled.
|
||||
if (!get_config("local_treestudyplan","enableplansharing")) {
|
||||
if (!get_config("local_treestudyplan", "enableplansharing")) {
|
||||
return [];
|
||||
}
|
||||
$invite = $DB->get_record_select(
|
||||
|
@ -280,7 +280,7 @@ class studentstudyplanservice extends \external_api {
|
|||
}
|
||||
|
||||
// Do not validate the context in this instance to avoid requiring logins when this is not wanted
|
||||
|
||||
|
||||
$studyplan = studyplan::find_by_id($studyplanid);
|
||||
$userid = $invite->user_id;
|
||||
|
||||
|
@ -290,7 +290,7 @@ class studentstudyplanservice extends \external_api {
|
|||
} else {
|
||||
throw new \moodle_exception("The selected studyplan is suspended");
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
throw new \moodle_exception("Invitation's user is not linked to this studyplan");
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function get_invited_studyplan
|
||||
*/
|
||||
public static function get_invited_page_parameters() : \external_function_parameters {
|
||||
public static function get_invited_page_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"invitekey" => new \external_value(PARAM_RAW, 'invite key'),
|
||||
"pageid" => new \external_value(PARAM_INT, 'studyplan page id'),
|
||||
|
@ -315,7 +315,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function get_invited_studyplan
|
||||
*/
|
||||
public static function get_invited_page_returns() : \external_description {
|
||||
public static function get_invited_page_returns(): \external_description {
|
||||
return studyplanpage::user_structure();
|
||||
}
|
||||
|
||||
|
@ -325,10 +325,10 @@ class studentstudyplanservice extends \external_api {
|
|||
* @param int $pageid ID of the studyplan to retrieve
|
||||
* @return array
|
||||
*/
|
||||
public static function get_invited_page($invitekey,$pageid) {
|
||||
public static function get_invited_page($invitekey, $pageid) {
|
||||
global $DB;
|
||||
// First check if studyplan sharing is enabled.
|
||||
if (!get_config("local_treestudyplan","enableplansharing")) {
|
||||
if (!get_config("local_treestudyplan", "enableplansharing")) {
|
||||
return [];
|
||||
}
|
||||
$invite = $DB->get_record_select(
|
||||
|
@ -342,7 +342,7 @@ class studentstudyplanservice extends \external_api {
|
|||
}
|
||||
|
||||
// Do not validate the context in this instance to avoid requiring logins when this is not wanted
|
||||
|
||||
|
||||
$page = studyplanpage::find_by_id($pageid);
|
||||
$studyplan = $page->studyplan();
|
||||
$userid = $invite->user_id;
|
||||
|
@ -363,14 +363,14 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function list_own_studyplans
|
||||
*/
|
||||
public static function list_own_studyplans_parameters() : \external_function_parameters {
|
||||
public static function list_own_studyplans_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
);
|
||||
|
@ -401,7 +401,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function get_own_studyplan
|
||||
*/
|
||||
public static function get_own_studyplan_parameters() : \external_function_parameters {
|
||||
public static function get_own_studyplan_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplanid" => new \external_value(PARAM_INT, 'id of studyplan to retrieve'),
|
||||
] );
|
||||
|
@ -410,7 +410,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 studyplan::user_structure();
|
||||
}
|
||||
|
||||
|
@ -446,7 +446,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function get_own_page
|
||||
*/
|
||||
public static function get_own_page_parameters() : \external_function_parameters {
|
||||
public static function get_own_page_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"pageid" => new \external_value(PARAM_INT, 'id of studyplan to retrieve'),
|
||||
] );
|
||||
|
@ -455,12 +455,12 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function get_own_page
|
||||
*/
|
||||
public static function get_own_page_returns() : \external_description {
|
||||
public static function get_own_page_returns(): \external_description {
|
||||
return studyplan::user_structure();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get studyplanpage for current user
|
||||
* Get studyplanpage for current user
|
||||
* @param int $pagid ID of specific studyplan page
|
||||
* @return array
|
||||
*/
|
||||
|
@ -491,14 +491,14 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function list_teaching_studyplans
|
||||
*/
|
||||
public static function list_teaching_studyplans_parameters() : \external_function_parameters {
|
||||
public static function list_teaching_studyplans_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return value description for webservice function list_teaching_studyplans
|
||||
*/
|
||||
public static function list_teaching_studyplans_returns() : \external_description {
|
||||
public static function list_teaching_studyplans_returns(): \external_description {
|
||||
return new \external_multiple_structure(
|
||||
studyplan::simple_structure()
|
||||
);
|
||||
|
@ -532,14 +532,14 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function list_teaching_studyplans
|
||||
*/
|
||||
public static function list_coaching_studyplans_parameters() : \external_function_parameters {
|
||||
public static function list_coaching_studyplans_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return value description for webservice function list_teaching_studyplans
|
||||
*/
|
||||
public static function list_coaching_studyplans_returns() : \external_description {
|
||||
public static function list_coaching_studyplans_returns(): \external_description {
|
||||
return new \external_multiple_structure(
|
||||
studyplan::simple_structure()
|
||||
);
|
||||
|
@ -557,17 +557,17 @@ class studentstudyplanservice extends \external_api {
|
|||
\external_api::validate_context(\context_system::instance());
|
||||
|
||||
// Return empty list if coach role not enabled
|
||||
if ( ! (premium::enabled() && \get_config("local_treestudyplan","enablecoach")) ) {
|
||||
if ( ! (premium::enabled() && \get_config("local_treestudyplan", "enablecoach")) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$records = $DB->get_records("local_treestudyplan_coach",["user_id" => $userid]);
|
||||
$records = $DB->get_records("local_treestudyplan_coach", ["user_id" => $userid]);
|
||||
|
||||
$list = [];
|
||||
foreach ($records as $r) {
|
||||
try {
|
||||
$studyplan = studyplan::find_by_id($r->studyplan_id);
|
||||
if (has_capability(self::CAP_COACH,$studyplan->context(),$USER)) {
|
||||
if (has_capability(self::CAP_COACH, $studyplan->context(), $USER)) {
|
||||
$list[] = $studyplan->simple_model_coach();
|
||||
}
|
||||
} catch(\Exception $x) {}
|
||||
|
@ -584,7 +584,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function get_teaching_studyplan
|
||||
*/
|
||||
public static function get_teaching_studyplan_parameters() : \external_function_parameters {
|
||||
public static function get_teaching_studyplan_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"studyplanid" => new \external_value(PARAM_INT, 'id of specific studyplan to provide', VALUE_DEFAULT),
|
||||
] );
|
||||
|
@ -593,7 +593,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function get_teaching_studyplan
|
||||
*/
|
||||
public static function get_teaching_studyplan_returns() : \external_description {
|
||||
public static function get_teaching_studyplan_returns(): \external_description {
|
||||
return studyplan::editor_structure();
|
||||
}
|
||||
|
||||
|
@ -625,7 +625,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function get_teaching_page
|
||||
*/
|
||||
public static function get_teaching_page_parameters() : \external_function_parameters {
|
||||
public static function get_teaching_page_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"pageid" => new \external_value(PARAM_INT, 'id of specific studyplan page to provide', VALUE_DEFAULT),
|
||||
] );
|
||||
|
@ -634,7 +634,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function get_teaching_page
|
||||
*/
|
||||
public static function get_teaching_page_returns() : \external_description {
|
||||
public static function get_teaching_page_returns(): \external_description {
|
||||
return studyplanpage::editor_structure();
|
||||
}
|
||||
|
||||
|
@ -667,7 +667,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function get_teaching_page
|
||||
*/
|
||||
public static function line_enrol_self_parameters() : \external_function_parameters {
|
||||
public static function line_enrol_self_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
"id" => new \external_value(PARAM_INT, 'id of specific studyline to enrol into'),
|
||||
] );
|
||||
|
@ -676,7 +676,7 @@ class studentstudyplanservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function get_teaching_page
|
||||
*/
|
||||
public static function line_enrol_self_returns() : \external_description {
|
||||
public static function line_enrol_self_returns(): \external_description {
|
||||
return studyline::enrol_info_structure();
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,6 @@ class studyitem {
|
|||
/** @var aggregator */
|
||||
private $aggregator;
|
||||
|
||||
|
||||
/**
|
||||
* Return the context the studyplan is associated to
|
||||
*/
|
||||
|
@ -83,8 +82,8 @@ class studyitem {
|
|||
/**
|
||||
* Return the condition string for this item
|
||||
*/
|
||||
public function conditions() : string {
|
||||
if($this->r->type == self::COURSE) {
|
||||
public function conditions(): string {
|
||||
if ($this->r->type == self::COURSE) {
|
||||
return (!empty($this->r->conditions)) ? $this->r->conditions : "";
|
||||
} else {
|
||||
return (!empty($this->r->conditions)) ? $this->r->conditions : "ALL";
|
||||
|
@ -118,42 +117,42 @@ class studyitem {
|
|||
/**
|
||||
* Return database identifier
|
||||
*/
|
||||
public function id() : int {
|
||||
public function id(): int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return period slot for this item
|
||||
*/
|
||||
public function slot() : int {
|
||||
public function slot(): int {
|
||||
return $this->r->slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return layer (order within a line and slot) for this item
|
||||
*/
|
||||
public function layer() : int {
|
||||
public function layer(): int {
|
||||
return $this->r->layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return study item type (see constants above)
|
||||
*/
|
||||
public function type() : string {
|
||||
public function type(): string {
|
||||
return $this->r->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return period span
|
||||
*/
|
||||
public function span() : string {
|
||||
public function span(): string {
|
||||
return $this->r->span;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return id of linked course (only relevant on COURSE types) or 0 if none
|
||||
*/
|
||||
public function courseid() : int {
|
||||
public function courseid(): int {
|
||||
return $this->r->course_id;
|
||||
}
|
||||
|
||||
|
@ -161,16 +160,16 @@ class studyitem {
|
|||
* Check if a studyitem with the given id exists
|
||||
* @param int $id Id of studyplan
|
||||
*/
|
||||
public static function exists($id) : bool {
|
||||
public static function exists($id): bool {
|
||||
global $DB;
|
||||
return is_numeric($id) && $DB->record_exists(self::TABLE, array('id' => $id));
|
||||
return is_numeric($id) && $DB->record_exists(self::TABLE, ['id' => $id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Webservice structure for simple info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function simple_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function simple_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of study item'),
|
||||
"type" => new \external_value(PARAM_TEXT, 'shortname of study item'),
|
||||
|
@ -179,7 +178,7 @@ class studyitem {
|
|||
"span" => new \external_value(PARAM_INT, 'how many periods the item spans'),
|
||||
"course" => courseinfo::simple_structure(VALUE_OPTIONAL),
|
||||
"badge" => badgeinfo::simple_structure(VALUE_OPTIONAL),
|
||||
],"",$value);
|
||||
], "", $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,7 +198,7 @@ class studyitem {
|
|||
if (isset($ci)) {
|
||||
$model['course'] = $ci->simple_model();
|
||||
}
|
||||
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', ['id' => $this->r->badge_id])) {
|
||||
$badge = new \core_badges\badge($this->r->badge_id);
|
||||
$badgeinfo = new badgeinfo($badge);
|
||||
$model['badge'] = $badgeinfo->simple_model();
|
||||
|
@ -211,7 +210,7 @@ class studyitem {
|
|||
* Webservice structure for editor info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function editor_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function editor_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of study item'),
|
||||
"type" => new \external_value(PARAM_TEXT, 'shortname of study item'),
|
||||
|
@ -226,7 +225,7 @@ class studyitem {
|
|||
'in' => new \external_multiple_structure(studyitemconnection::structure()),
|
||||
'out' => new \external_multiple_structure(studyitemconnection::structure()),
|
||||
]),
|
||||
],"",$value);
|
||||
], "", $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -257,7 +256,7 @@ class studyitem {
|
|||
'connections' => [
|
||||
"in" => [],
|
||||
"out" => [],
|
||||
]
|
||||
],
|
||||
];
|
||||
if ($mode == "export") {
|
||||
// Remove slot and layer.
|
||||
|
@ -278,7 +277,7 @@ class studyitem {
|
|||
}
|
||||
|
||||
// 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', ['id' => $this->r->badge_id])) {
|
||||
$badge = new \core_badges\badge($this->r->badge_id);
|
||||
$badgeinfo = new badgeinfo($badge);
|
||||
if ($mode == "export") {
|
||||
|
@ -329,11 +328,11 @@ class studyitem {
|
|||
* '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 {
|
||||
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'];
|
||||
$info = [ 'layer' => 0, ];
|
||||
$info = [ 'layer' => 0 ];
|
||||
foreach ($addable as $f) {
|
||||
if (array_key_exists($f, $fields)) {
|
||||
$info[$f] = $fields[$f];
|
||||
|
@ -352,11 +351,11 @@ class studyitem {
|
|||
* Edit study item properties
|
||||
* @param array $fields Changed roperties for study line ['conditions', 'course_id', 'continuation_id', 'span']
|
||||
*/
|
||||
public function edit($fields) : self {
|
||||
public function edit($fields): self {
|
||||
global $DB;
|
||||
$editable = ['conditions', 'course_id', 'continuation_id', 'span'];
|
||||
|
||||
$info = ['id' => $this->id, ];
|
||||
$info = ['id' => $this->id ];
|
||||
foreach ($editable as $f) {
|
||||
if (array_key_exists($f, $fields) && isset($fields[$f])) {
|
||||
$info[$f] = $fields[$f];
|
||||
|
@ -372,7 +371,7 @@ class studyitem {
|
|||
/**
|
||||
* Check if references course and badges are still available
|
||||
*/
|
||||
public function valid() : bool {
|
||||
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);
|
||||
|
@ -418,7 +417,7 @@ class studyitem {
|
|||
* 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 {
|
||||
public static function reorder($resequence): success {
|
||||
global $DB;
|
||||
|
||||
foreach ($resequence as $sq) {
|
||||
|
@ -442,7 +441,7 @@ class studyitem {
|
|||
* @param studyline $line The studyline to search for
|
||||
* @return studyitem[]
|
||||
*/
|
||||
public static function find_studyline_children(studyline $line) : array {
|
||||
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()]);
|
||||
|
@ -460,13 +459,13 @@ class studyitem {
|
|||
* @param int $type The type of items to include
|
||||
* @return studyitem[]
|
||||
*/
|
||||
public static function search_studyline_children(studyline $line,$slot,$type) : array {
|
||||
public static function search_studyline_children(studyline $line, $slot, $type): array {
|
||||
global $DB;
|
||||
$list = [];
|
||||
$ids = $DB->get_fieldset_select(
|
||||
self::TABLE, "id",
|
||||
self::TABLE, "id",
|
||||
"line_id = :line_id AND type = :type AND ( slot <= :slota AND ( slot + (span-1) >= :slotb ) ) ORDER BY layer",
|
||||
['line_id' => $line->id(), 'slota' => $slot, 'slotb' => $slot,'type' => $type]
|
||||
['line_id' => $line->id(), 'slota' => $slot, 'slotb' => $slot, 'type' => $type]
|
||||
);
|
||||
foreach ($ids as $id) {
|
||||
$item = self::find_by_id($id, $line);
|
||||
|
@ -475,13 +474,11 @@ 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 {
|
||||
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'),
|
||||
"type" => new \external_value(PARAM_TEXT, 'type of study item'),
|
||||
|
@ -495,7 +492,7 @@ class studyitem {
|
|||
* Webservice model for linking between plans
|
||||
* @param int $userid ID for user to links completion from
|
||||
*/
|
||||
private function link_model($userid) : array {
|
||||
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]);
|
||||
|
@ -513,7 +510,7 @@ class studyitem {
|
|||
* Webservice structure for userinfo
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function user_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function user_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of study item'),
|
||||
"type" => new \external_value(PARAM_TEXT, 'type of study item'),
|
||||
|
@ -591,7 +588,7 @@ class studyitem {
|
|||
/**
|
||||
* Get courseinfo for studyitem if it references a course
|
||||
*/
|
||||
public function getcourseinfo() : ?courseinfo {
|
||||
public function getcourseinfo(): ?courseinfo {
|
||||
if (empty($this->courseinfo) && courseinfo::exists($this->r->course_id)) {
|
||||
$this->courseinfo = new courseinfo($this->r->course_id, $this);
|
||||
}
|
||||
|
@ -603,7 +600,7 @@ class studyitem {
|
|||
* @param int $userid User id
|
||||
* @return int completion:: constant
|
||||
*/
|
||||
public function completion($userid) : int {
|
||||
public function completion($userid): int {
|
||||
global $DB;
|
||||
|
||||
if ($this->valid()) {
|
||||
|
@ -649,7 +646,7 @@ class studyitem {
|
|||
break;
|
||||
}
|
||||
}
|
||||
return ($notexpired) ? completion::COMPLETED : completion::INCOMPLETE;
|
||||
return ($notexpired) ? completion : :COMPLETED : completion::INCOMPLETE;
|
||||
} else {
|
||||
return completion::COMPLETED;
|
||||
}
|
||||
|
@ -673,7 +670,7 @@ class studyitem {
|
|||
* Duplicate this studyitem
|
||||
* @param studyline $newline Study line to add duplicate to
|
||||
*/
|
||||
public function duplicate($newline) : self {
|
||||
public function duplicate($newline): self {
|
||||
global $DB;
|
||||
// Clone the database fields.
|
||||
$fields = clone $this->r;
|
||||
|
@ -700,12 +697,11 @@ class studyitem {
|
|||
return $this->generate_model("export");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import studyitems from model
|
||||
* @param array $model Decoded array
|
||||
*/
|
||||
public static function import_item($model) : self {
|
||||
public static function import_item($model): self {
|
||||
unset($model["course_id"]);
|
||||
unset($model["competency_id"]);
|
||||
unset($model["badge_id"]);
|
||||
|
|
|
@ -56,7 +56,7 @@ class studyitemconnection {
|
|||
* Webservice structure for basic info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
'id' => new \external_value(PARAM_INT, 'id of connection'),
|
||||
'from_id' => new \external_value(PARAM_INT, 'id of start item'),
|
||||
|
@ -72,25 +72,24 @@ class studyitemconnection {
|
|||
return ['id' => $this->r->id, 'from_id' => $this->r->from_id, 'to_id' => $this->r->to_id];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get originating studyitem for this connection
|
||||
*/
|
||||
public function from_item() : studyitem {
|
||||
public function from_item(): studyitem {
|
||||
return studyitem::find_by_id($this->r->from_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get target studyitem for this connection
|
||||
*/
|
||||
public function to_item() : studyitem {
|
||||
public function to_item(): studyitem {
|
||||
return studyitem::find_by_id($this->r->to_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get originating studyitem id for this connection
|
||||
*/
|
||||
public function from_id() : int {
|
||||
public function from_id(): int {
|
||||
return $this->r->from_id;
|
||||
}
|
||||
|
||||
|
@ -106,7 +105,7 @@ class studyitemconnection {
|
|||
* @param int $itemid Id of the studyitem
|
||||
* @return studyitemconnection[]
|
||||
*/
|
||||
public static function find_outgoing($itemid) : array {
|
||||
public static function find_outgoing($itemid): array {
|
||||
global $DB;
|
||||
$list = [];
|
||||
$connout = $DB->get_records(self::TABLE, ['from_id' => $itemid]);
|
||||
|
|
|
@ -39,7 +39,7 @@ class studyline {
|
|||
* @var int
|
||||
*/
|
||||
public const ENROLLABLE_SELF = 1;
|
||||
|
||||
|
||||
/**
|
||||
* Studyline can be enrolled into by specific role(s)
|
||||
* @var int
|
||||
|
@ -110,7 +110,6 @@ class studyline {
|
|||
/** @var studyplan*/
|
||||
private $studyplan;
|
||||
|
||||
|
||||
/**
|
||||
* Return the context the studyplan is associated to
|
||||
*/
|
||||
|
@ -121,14 +120,14 @@ class studyline {
|
|||
/**
|
||||
* Return the studyplan for this line
|
||||
*/
|
||||
public function studyplan() : studyplan {
|
||||
public function studyplan(): studyplan {
|
||||
return $this->studyplan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the studyplan page for this line
|
||||
*/
|
||||
public function page() : studyplanpage {
|
||||
public function page(): studyplanpage {
|
||||
return $this->page;
|
||||
}
|
||||
|
||||
|
@ -158,35 +157,35 @@ class studyline {
|
|||
/**
|
||||
* Return database identifier
|
||||
*/
|
||||
public function id() : int {
|
||||
public function id(): int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return full name
|
||||
*/
|
||||
public function name() : string {
|
||||
public function name(): string {
|
||||
return $this->r->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return short name
|
||||
*/
|
||||
public function shortname() : string {
|
||||
public function shortname(): string {
|
||||
return $this->r->shortname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this line is enrollable by the student
|
||||
*/
|
||||
public function self_enrollable() : bool {
|
||||
public function self_enrollable(): bool {
|
||||
return ($this->r->enrollable == self::ENROLLABLE_SELF || $this->r->enrollable == self::ENROLLABLE_SELF_ROLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this line is enrollable by a role
|
||||
*/
|
||||
public function role_enrollable() : bool {
|
||||
public function role_enrollable(): bool {
|
||||
return ($this->r->enrollable == self::ENROLLABLE_ROLE || $this->r->enrollable == self::ENROLLABLE_SELF_ROLE);
|
||||
}
|
||||
|
||||
|
@ -194,11 +193,11 @@ class studyline {
|
|||
* Whether the current user can enrol a specific user in this line
|
||||
* @param int|null $user ID or user object for user or null
|
||||
*/
|
||||
public function can_enrol($userid=null) : bool {
|
||||
public function can_enrol($userid=null): bool {
|
||||
global $USER;
|
||||
|
||||
$plan = $this->studyplan();
|
||||
if (!empty($userid)){
|
||||
if (!empty($userid)) {
|
||||
if ( $plan->has_linked_user(intval($userid))) {
|
||||
if ( $this->self_enrollable() && $userid == $USER->id ) {
|
||||
return true;
|
||||
|
@ -206,7 +205,7 @@ class studyline {
|
|||
if ( $this->role_enrollable()) {
|
||||
$context = $plan->context();
|
||||
foreach ( $this->enrol_roleids() as $rid) {
|
||||
if (\user_has_role_assignment($USER->id,$rid,$context->id)){
|
||||
if (\user_has_role_assignment($USER->id, $rid, $context->id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -216,73 +215,73 @@ class studyline {
|
|||
if ( $this->role_enrollable()) {
|
||||
$context = $plan->context();
|
||||
foreach ( $this->enrol_roleids() as $rid) {
|
||||
if (\user_has_role_assignment($USER->id,$rid,$context->id)){
|
||||
if (\user_has_role_assignment($USER->id, $rid, $context->id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this line is enrollable at all
|
||||
*/
|
||||
public function enrollable() : bool {
|
||||
public function enrollable(): bool {
|
||||
return $this->r->enrollable != self::ENROLLABLE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the available roles that can enrol the student
|
||||
*/
|
||||
public function enrol_roles() : array {
|
||||
public function enrol_roles(): array {
|
||||
global $DB;
|
||||
$list = [];
|
||||
$roles = explode(",",$this->r->enrolrole);
|
||||
$roles = explode(", ", $this->r->enrolrole);
|
||||
foreach($roles as $r) {
|
||||
$roleid = intval($r);
|
||||
if ($roleid > 0) {
|
||||
try {
|
||||
$role = $DB->get_record('role',["id" => $roleid],"*", MUST_EXIST);
|
||||
$role = $DB->get_record('role', ["id" => $roleid], "*", MUST_EXIST);
|
||||
$list[] = $role;
|
||||
} catch(\Exception $x) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the available roles that can enrol the student
|
||||
*/
|
||||
public function enrol_roleids() : array {
|
||||
public function enrol_roleids(): array {
|
||||
global $DB;
|
||||
$list = [];
|
||||
$roles = explode(",",$this->r->enrolrole);
|
||||
$roles = explode(", ", $this->r->enrolrole);
|
||||
foreach($roles as $r) {
|
||||
$roleid = intval($r);
|
||||
if ($roleid > 0) {
|
||||
$list[] = $roleid;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the available roles that can enrol the student in a proper model
|
||||
*/
|
||||
public function enrol_roles_model() : array {
|
||||
public function enrol_roles_model(): array {
|
||||
$list = [];
|
||||
foreach($this->enrol_roles() as $role) {
|
||||
$name = role_get_name($role,$this->context()); // Get localized role name.
|
||||
$name = role_get_name($role, $this->context()); // Get localized role name.
|
||||
$list[] = [
|
||||
"id" => $role->id,
|
||||
"name" => $name,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
|
@ -290,7 +289,7 @@ class studyline {
|
|||
* Webservice structure for editor info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function editor_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function editor_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of studyline'),
|
||||
"name" => new \external_value(PARAM_TEXT, 'shortname of studyline'),
|
||||
|
@ -306,7 +305,7 @@ class studyline {
|
|||
studyitem::editor_structure(), 'filter items'),
|
||||
])
|
||||
)
|
||||
],"Study line editor structure",$value);
|
||||
], "Study line editor structure", $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -321,19 +320,19 @@ class studyline {
|
|||
"id" => new \external_value(PARAM_INT, 'id of role'),
|
||||
"name" => new \external_value(PARAM_TEXT, 'name of role'),
|
||||
])),
|
||||
"can_enrol" => new \external_value(PARAM_BOOL, 'enrollable by current user',VALUE_OPTIONAL),
|
||||
"enrolled" => new \external_value(PARAM_BOOL, 'student is enrolled',VALUE_OPTIONAL),
|
||||
"enrolled_time" => new \external_value(PARAM_INT, 'moment of enrollment',VALUE_OPTIONAL),
|
||||
"enrolled_by" => new \external_value(PARAM_TEXT, 'Name of enrolling user',VALUE_OPTIONAL),
|
||||
"selfview" => new \external_value(PARAM_BOOL, 'viewing user is the student',VALUE_OPTIONAL),
|
||||
],"Enrollment info",$value);
|
||||
"can_enrol" => new \external_value(PARAM_BOOL, 'enrollable by current user', VALUE_OPTIONAL),
|
||||
"enrolled" => new \external_value(PARAM_BOOL, 'student is enrolled', VALUE_OPTIONAL),
|
||||
"enrolled_time" => new \external_value(PARAM_INT, 'moment of enrollment', VALUE_OPTIONAL),
|
||||
"enrolled_by" => new \external_value(PARAM_TEXT, 'Name of enrolling user', VALUE_OPTIONAL),
|
||||
"selfview" => new \external_value(PARAM_BOOL, 'viewing user is the student', VALUE_OPTIONAL),
|
||||
], "Enrollment info", $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Webservice structure for simple info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function simple_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function simple_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of studyline'),
|
||||
"name" => new \external_value(PARAM_TEXT, 'shortname of studyline'),
|
||||
|
@ -341,14 +340,14 @@ class studyline {
|
|||
"color" => new \external_value(PARAM_TEXT, 'description of studyline'),
|
||||
"sequence" => new \external_value(PARAM_INT, 'order of studyline'),
|
||||
"enrol" => self::enrol_info_structure(),
|
||||
],"Study line simple structure",$value);
|
||||
], "Study line simple structure", $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Webservice model for simple info
|
||||
* @return array Webservice data model
|
||||
*/
|
||||
public function simple_model() : array {
|
||||
public function simple_model(): array {
|
||||
return [
|
||||
'id' => $this->r->id,
|
||||
'name' => $this->r->name,
|
||||
|
@ -363,7 +362,7 @@ class studyline {
|
|||
* Webservice model for editor info
|
||||
* @return array Webservice data model
|
||||
*/
|
||||
public function editor_model() : array {
|
||||
public function editor_model(): array {
|
||||
return $this->generate_model("editor");
|
||||
}
|
||||
|
||||
|
@ -371,7 +370,7 @@ class studyline {
|
|||
* Create a model for the given type of operation
|
||||
* @param string $mode One of [ 'editor', 'export']
|
||||
*/
|
||||
protected function generate_model($mode) : array {
|
||||
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;
|
||||
|
@ -436,12 +435,11 @@ class studyline {
|
|||
return $model;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a new study line
|
||||
* @param array $fields Properties for study line ['page_id', 'name', 'shortname', 'color']
|
||||
*/
|
||||
public static function add($fields) : self {
|
||||
public static function add($fields): self {
|
||||
global $DB;
|
||||
|
||||
if (!isset($fields['page_id'])) {
|
||||
|
@ -450,7 +448,7 @@ class studyline {
|
|||
|
||||
$pageid = $fields['page_id'];
|
||||
$sqmax = $DB->get_field_select(self::TABLE, "MAX(sequence)", "page_id = :page_id", ['page_id' => $pageid]);
|
||||
$addable = ['page_id', 'name', 'shortname', 'color','enrollable','enrolrole'];
|
||||
$addable = ['page_id', 'name', 'shortname', 'color', 'enrollable', 'enrolrole'];
|
||||
$info = ['sequence' => $sqmax + 1];
|
||||
foreach ($addable as $f) {
|
||||
if (array_key_exists($f, $fields)) {
|
||||
|
@ -465,10 +463,10 @@ class studyline {
|
|||
* Edit study line properties
|
||||
* @param array $fields Changed roperties for study line ['name', 'shortname', 'color']
|
||||
*/
|
||||
public function edit($fields) : self {
|
||||
public function edit($fields): self {
|
||||
global $DB;
|
||||
$editable = ['name', 'shortname', 'color','enrollable','enrolrole'];
|
||||
$info = ['id' => $this->id, ];
|
||||
$editable = ['name', 'shortname', 'color', 'enrollable', 'enrolrole'];
|
||||
$info = ['id' => $this->id ];
|
||||
foreach ($editable as $f) {
|
||||
if (array_key_exists($f, $fields)) {
|
||||
$info[$f] = $fields[$f];
|
||||
|
@ -484,7 +482,7 @@ class studyline {
|
|||
* Delete studyline
|
||||
* @param bool $force Force deletion even if study line contains items
|
||||
*/
|
||||
public function delete($force = false) : success {
|
||||
public function delete($force = false): success {
|
||||
global $DB;
|
||||
|
||||
if ($force) {
|
||||
|
@ -506,7 +504,7 @@ class studyline {
|
|||
* Reorder study lines
|
||||
* @param int[] $resequence New order of study lines by id
|
||||
*/
|
||||
public static function reorder($resequence) : success {
|
||||
public static function reorder($resequence): success {
|
||||
global $DB;
|
||||
|
||||
foreach ($resequence as $sq) {
|
||||
|
@ -524,7 +522,7 @@ class studyline {
|
|||
* @param studyplanpage $page The studyplanpage to search for
|
||||
* @return studyline[]
|
||||
*/
|
||||
public static function find_page_children(studyplanpage $page) : array {
|
||||
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",
|
||||
|
@ -539,7 +537,7 @@ class studyline {
|
|||
* Webservice structure for userinfo
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function user_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function user_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of studyline'),
|
||||
"name" => new \external_value(PARAM_TEXT, 'shortname of studyline'),
|
||||
|
@ -564,7 +562,7 @@ class studyline {
|
|||
* @return array Webservice data model
|
||||
*/
|
||||
public function enrol_info_model($userid=null) {
|
||||
global $DB,$USER;
|
||||
global $DB, $USER;
|
||||
|
||||
$model = [
|
||||
'enrolroles' => $this->enrol_roleids(),
|
||||
|
@ -573,34 +571,34 @@ class studyline {
|
|||
];
|
||||
|
||||
if (!empty($userid)) {
|
||||
$r = $DB->get_record('local_treestudyplan_lineuser',[
|
||||
$r = $DB->get_record('local_treestudyplan_lineuser', [
|
||||
'line_id' => $this->id(),
|
||||
'user_id' => $userid,
|
||||
]);
|
||||
|
||||
if (empty($r)) {
|
||||
$enrolled = false;
|
||||
$enrolled_time = 0;
|
||||
$enrolled_by = "";
|
||||
$enrolledtime = 0;
|
||||
$enrolledby = "";
|
||||
} else {
|
||||
$enrolled = boolval($r->enrolled);
|
||||
$enrolled_time = $r->timeenrolled;
|
||||
$by = $DB->get_record('user',["id" => $r->enrolledby]);
|
||||
$enrolledtime = $r->timeenrolled;
|
||||
$by = $DB->get_record('user', ["id" => $r->enrolledby]);
|
||||
if (empty($by)) {
|
||||
$enrolled_by = \get_string("unknownuser","core");
|
||||
$enrolledby = \get_string("unknownuser", "core");
|
||||
} else {
|
||||
$enrolled_by = "{$by->firstname} {$by->lastname}";
|
||||
$enrolledby = "{$by->firstname} {$by->lastname}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$usermodel = [
|
||||
'can_enrol' => $this->can_enrol($userid),
|
||||
"enrolled" => $enrolled,
|
||||
"enrolled_time" => $enrolled_time,
|
||||
"enrolled_by" => $enrolled_by,
|
||||
"enrolled_time" => $enrolledtime,
|
||||
"enrolled_by" => $enrolledby,
|
||||
"selfview" => boolval($userid == $USER->id),
|
||||
];
|
||||
$model = array_merge($model,$usermodel);
|
||||
$model = array_merge($model, $usermodel);
|
||||
} else {
|
||||
$model["can_enrol"] = $this->can_enrol();
|
||||
}
|
||||
|
@ -613,7 +611,7 @@ class studyline {
|
|||
*/
|
||||
public function get_enrolled_userids() {
|
||||
$userids = $this->studyplan()->find_linked_userids();
|
||||
if($this->enrollable()) {
|
||||
if ($this->enrollable()) {
|
||||
$list = [];
|
||||
foreach($userids as $uid) {
|
||||
if ( $this->isenrolled($uid)) {
|
||||
|
@ -626,7 +624,6 @@ class studyline {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if student is enrolled in the line.
|
||||
* @param int $userid ID of user to check specific info for
|
||||
|
@ -637,7 +634,7 @@ class studyline {
|
|||
if ($this->r->enrollable == self::ENROLLABLE_NONE) {
|
||||
return true; // If student cannot enrol, the student always is enrolled
|
||||
} else {
|
||||
$r = $DB->get_record('local_treestudyplan_lineuser',[
|
||||
$r = $DB->get_record('local_treestudyplan_lineuser', [
|
||||
'line_id' => $this->id(),
|
||||
'user_id' => $userid,
|
||||
]);
|
||||
|
@ -649,13 +646,13 @@ class studyline {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List the course id is linked in this studyplan
|
||||
* Used for cohort enrolment cascading
|
||||
* @return int[]
|
||||
*/
|
||||
public function get_linked_course_ids() : array {
|
||||
public function get_linked_course_ids(): array {
|
||||
global $DB;
|
||||
|
||||
$sql = "SELECT i.course_id
|
||||
|
@ -674,7 +671,7 @@ class studyline {
|
|||
* @param int $userid of user to enrol
|
||||
*/
|
||||
public function enrol($userid) {
|
||||
global $DB,$USER;
|
||||
global $DB, $USER;
|
||||
|
||||
if ($this->r->enrollable > self::ENROLLABLE_NONE) {
|
||||
$r = $DB->get_record("local_treestudyplan_lineuser",
|
||||
|
@ -686,7 +683,7 @@ class studyline {
|
|||
$r->enrolled = 1;
|
||||
$r->timeenrolled = time();
|
||||
$r->enrolledby = $USER->id;
|
||||
$DB->update_record("local_treestudyplan_lineuser",$r);
|
||||
$DB->update_record("local_treestudyplan_lineuser", $r);
|
||||
}
|
||||
// Otherwise, ignore the request.
|
||||
|
||||
|
@ -698,7 +695,7 @@ class studyline {
|
|||
$r->user_id = $userid;
|
||||
$r->timeenrolled = time();
|
||||
$r->enrolledby = $USER->id;
|
||||
$DB->insert_record("local_treestudyplan_lineuser",$r);
|
||||
$DB->insert_record("local_treestudyplan_lineuser", $r);
|
||||
}
|
||||
|
||||
$this->studyplan()->mark_csync_changed();
|
||||
|
@ -713,8 +710,8 @@ class studyline {
|
|||
* @param int $userid of user to unenrol
|
||||
*/
|
||||
public function unenrol($userid) {
|
||||
global $DB,$USER;
|
||||
|
||||
global $DB, $USER;
|
||||
|
||||
if ($this->r->enrollable > self::ENROLLABLE_NONE) {
|
||||
// Check if an enrollment line exist.
|
||||
$r = $DB->get_record("local_treestudyplan_lineuser",
|
||||
|
@ -726,18 +723,17 @@ class studyline {
|
|||
$r->enrolled = 0;
|
||||
$r->timeenrolled = time(); // Regi
|
||||
$r->enrolledby = $USER->id;
|
||||
$DB->update_record("local_treestudyplan_lineuser",$r);
|
||||
|
||||
$DB->update_record("local_treestudyplan_lineuser", $r);
|
||||
|
||||
$this->studyplan()->mark_csync_changed();
|
||||
}
|
||||
// Otherwise, ignore the request.
|
||||
|
||||
}
|
||||
}
|
||||
// Otherwise, no action is needed.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Webservice model for user info
|
||||
* @param int $userid ID of user to check specific info for
|
||||
|
@ -803,7 +799,7 @@ class studyline {
|
|||
* @param array $translation Mapping array of old item ids to new item ids for connection matching
|
||||
* @param bool $bare Set to true to skip copying contents
|
||||
*/
|
||||
public function duplicate($newpage, &$translation,$bare = false) : self {
|
||||
public function duplicate($newpage, &$translation, $bare = false): self {
|
||||
global $DB;
|
||||
|
||||
// Clone the database fields.
|
||||
|
|
|
@ -38,7 +38,6 @@ class studyplan {
|
|||
/** @var string */
|
||||
const TABLE_COACH = "local_treestudyplan_coach";
|
||||
|
||||
|
||||
/**
|
||||
* Cache retrieved studyitems in this session
|
||||
* @var array */
|
||||
|
@ -73,7 +72,7 @@ class studyplan {
|
|||
/**
|
||||
* Return configured aggregator for this studyplan
|
||||
*/
|
||||
public function aggregator() : aggregator {
|
||||
public function aggregator(): aggregator {
|
||||
return $this->aggregator;
|
||||
}
|
||||
|
||||
|
@ -96,7 +95,7 @@ class studyplan {
|
|||
private function __construct($id) {
|
||||
global $DB;
|
||||
$this->id = $id;
|
||||
$this->r = $DB->get_record(self::TABLE, ['id' => $id],"*",MUST_EXIST);
|
||||
$this->r = $DB->get_record(self::TABLE, ['id' => $id], "*", MUST_EXIST);
|
||||
|
||||
$this->aggregator = aggregator::create_or_default($this->r->aggregation, $this->r->aggregation_config);
|
||||
}
|
||||
|
@ -155,14 +154,13 @@ class studyplan {
|
|||
return $date;
|
||||
}
|
||||
|
||||
|
||||
private function icon() {
|
||||
global $CFG;
|
||||
$fs = \get_file_storage();
|
||||
// Returns an array of `stored_file` instances.
|
||||
$files = $fs->get_area_files(\context_system::instance()->id, 'local_treestudyplan', 'icon', $this->id);
|
||||
|
||||
if (count($files) > 0 ){
|
||||
if (count($files) > 0 ) {
|
||||
$file = array_shift($files);
|
||||
if ($file->get_filename() == ".") {
|
||||
// Get next file if the first is the directory itself.
|
||||
|
@ -188,12 +186,12 @@ class studyplan {
|
|||
$url = \moodle_url::make_pluginfile_url(\context_system::instance()->id, 'local_treestudyplan', 'defaulticon', 0, "/",
|
||||
$defaulticon);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return $url->out();
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Return description with all file references resolved
|
||||
*/
|
||||
public function description() {
|
||||
|
@ -202,7 +200,7 @@ class studyplan {
|
|||
$this->r->description,
|
||||
// The pluginfile URL which will serve the request.
|
||||
'pluginfile.php',
|
||||
|
||||
|
||||
// The combination of contextid / component / filearea / itemid
|
||||
// form the virtual bucket that file are stored in.
|
||||
\context_system::instance()->id, // System instance is always used for this
|
||||
|
@ -217,7 +215,7 @@ class studyplan {
|
|||
* @param bool $refresh Set to true to force a refresh of the pages
|
||||
* @return studyplanpage[]
|
||||
*/
|
||||
public function pages($refresh=false) : array {
|
||||
public function pages($refresh=false): array {
|
||||
if ( ((bool)$refresh) || empty($this->pagecache)) {
|
||||
$this->pagecache = studyplanpage::find_studyplan_children($this);
|
||||
}
|
||||
|
@ -252,24 +250,24 @@ class studyplan {
|
|||
* Webservice structure for basic info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function simple_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function simple_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of studyplan'),
|
||||
"userid" => new \external_value(PARAM_INT, 'id of user the plan is shown for',VALUE_OPTIONAL),
|
||||
"userid" => new \external_value(PARAM_INT, 'id of user the plan is shown for', VALUE_OPTIONAL),
|
||||
"name" => new \external_value(PARAM_TEXT, 'name of studyplan'),
|
||||
"shortname" => new \external_value(PARAM_TEXT, 'shortname of studyplan'),
|
||||
"idnumber" => new \external_value(PARAM_TEXT, 'idnumber of curriculum'),
|
||||
"context_id" => new \external_value(PARAM_INT, 'context_id of studyplan'),
|
||||
"description" => new \external_value(PARAM_RAW, 'description of studyplan'),
|
||||
"descriptionformat" => new \external_value(PARAM_INT, 'description format'),
|
||||
"icon" => new \external_value(PARAM_RAW,'icon for this plan'),
|
||||
"icon" => new \external_value(PARAM_RAW, 'icon for this plan'),
|
||||
"aggregation" => new \external_value(PARAM_TEXT, 'selected aggregator'),
|
||||
"aggregation_config" => new \external_value(PARAM_TEXT, 'config string for aggregator'),
|
||||
"aggregation_info" => aggregator::basic_structure(),
|
||||
"pages" => new \external_multiple_structure(studyplanpage::simple_structure(), 'pages'),
|
||||
"progress" => new \external_value(PARAM_FLOAT,"fraction of completed modules",VALUE_OPTIONAL),
|
||||
"amteaching" => new \external_value(PARAM_BOOL,"Current user is teaching one or more courses in this studyplan",VALUE_OPTIONAL),
|
||||
"suspended" => new \external_value(PARAM_BOOL, 'if studyplan is suspended',VALUE_OPTIONAL),
|
||||
"progress" => new \external_value(PARAM_FLOAT, "fraction of completed modules", VALUE_OPTIONAL),
|
||||
"amteaching" => new \external_value(PARAM_BOOL, "Current user is teaching one or more courses in this studyplan", VALUE_OPTIONAL),
|
||||
"suspended" => new \external_value(PARAM_BOOL, 'if studyplan is suspended', VALUE_OPTIONAL),
|
||||
], 'Basic studyplan info', $value);
|
||||
}
|
||||
|
||||
|
@ -299,10 +297,10 @@ class studyplan {
|
|||
'pages' => $pages,
|
||||
'suspended' => boolval($this->r->suspended),
|
||||
];
|
||||
if(isset($userid)) {
|
||||
if (isset($userid)) {
|
||||
$model["userid"] = $userid;
|
||||
$model["progress"] = $this->scanuserprogress($userid);
|
||||
$model['amteaching'] = teachingfinder::is_teaching_studyplan($this,$userid);
|
||||
$model['amteaching'] = teachingfinder::is_teaching_studyplan($this, $userid);
|
||||
}
|
||||
return $model;
|
||||
}
|
||||
|
@ -317,7 +315,7 @@ class studyplan {
|
|||
$sum = 0;
|
||||
foreach ( $users as $uid ) {
|
||||
$sum += $this->scanuserprogress($uid);
|
||||
}
|
||||
}
|
||||
|
||||
$model["progress"] = $sum / count($users);
|
||||
|
||||
|
@ -328,7 +326,7 @@ class studyplan {
|
|||
* Webservice structure for editor info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function editor_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function editor_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of studyplan'),
|
||||
"name" => new \external_value(PARAM_TEXT, 'name of studyplan'),
|
||||
|
@ -336,7 +334,7 @@ class studyplan {
|
|||
"idnumber" => new \external_value(PARAM_TEXT, 'idnumber of curriculum'),
|
||||
"description" => new \external_value(PARAM_RAW, 'description of studyplan'),
|
||||
"descriptionformat" => new \external_value(PARAM_INT, 'description format'),
|
||||
"icon" => new \external_value(PARAM_RAW,'icon for this plan'),
|
||||
"icon" => new \external_value(PARAM_RAW, 'icon for this plan'),
|
||||
"context_id" => new \external_value(PARAM_INT, 'context_id of studyplan'),
|
||||
"aggregation" => new \external_value(PARAM_TEXT, 'selected aggregator'),
|
||||
"aggregation_config" => new \external_value(PARAM_TEXT, 'config string for aggregator'),
|
||||
|
@ -350,7 +348,7 @@ class studyplan {
|
|||
])),
|
||||
], "Scale forcing on stuff", VALUE_OPTIONAL),
|
||||
], "Advanced features available", VALUE_OPTIONAL),
|
||||
"suspended" => new \external_value(PARAM_BOOL, 'if studyplan is suspended',VALUE_OPTIONAL),
|
||||
"suspended" => new \external_value(PARAM_BOOL, 'if studyplan is suspended', VALUE_OPTIONAL),
|
||||
], 'Studyplan full structure', $value);
|
||||
}
|
||||
|
||||
|
@ -390,7 +388,7 @@ class studyplan {
|
|||
|
||||
// Get a list of available scales.
|
||||
$scales = array_map( function($scale) {
|
||||
return [ "id" => $scale->id, "name" => $scale->name, ];
|
||||
return [ "id" => $scale->id, "name" => $scale->name ];
|
||||
}, \grade_scale::fetch_all(['courseid' => 0]) );
|
||||
|
||||
$model['advanced']['force_scales'] = [
|
||||
|
@ -407,7 +405,7 @@ class studyplan {
|
|||
* '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 {
|
||||
public static function add($fields, $bare = false): self {
|
||||
global $CFG, $DB;
|
||||
|
||||
$addable = ['name', 'shortname', 'description', 'descriptionformat', 'idnumber', 'context_id', 'aggregation', 'aggregation_config'];
|
||||
|
@ -420,7 +418,7 @@ class studyplan {
|
|||
$id = $DB->insert_record(self::TABLE, $info);
|
||||
$plan = self::find_by_id($id); // Make sure the new studyplan is immediately cached.
|
||||
|
||||
// Add a single page and initialize it with placeholder data
|
||||
// Add a single page and initialize it with placeholder data
|
||||
// This makes it easier to create a new study plan
|
||||
// On import, adding an empty page messes things up , so we have an option to skip this....
|
||||
if (!$bare) {
|
||||
|
@ -437,7 +435,7 @@ class studyplan {
|
|||
}
|
||||
}
|
||||
|
||||
$page = studyplanpage::add($pageinfo,$bare);
|
||||
$page = studyplanpage::add($pageinfo, $bare);
|
||||
$plan->page_cache = [$page];
|
||||
}
|
||||
|
||||
|
@ -449,7 +447,7 @@ class studyplan {
|
|||
* @param array $fields Changed properties for study line ['name', 'shortname', 'description', 'idnumber',
|
||||
* 'context_id', 'aggregation', 'aggregation_config', 'suspended']
|
||||
*/
|
||||
public function edit($fields) : self {
|
||||
public function edit($fields): self {
|
||||
global $DB;
|
||||
$editable = [
|
||||
'name',
|
||||
|
@ -463,7 +461,7 @@ class studyplan {
|
|||
'suspended',
|
||||
'template'
|
||||
];
|
||||
$info = ['id' => $this->id, ];
|
||||
$info = ['id' => $this->id ];
|
||||
foreach ($editable as $f) {
|
||||
if (array_key_exists($f, $fields)) {
|
||||
$info[$f] = $fields[$f];
|
||||
|
@ -486,7 +484,7 @@ class studyplan {
|
|||
* Delete studyline
|
||||
* @param bool $force Force deletion even if study line contains items
|
||||
*/
|
||||
public function delete($force = false) : success {
|
||||
public function delete($force = false): success {
|
||||
global $DB;
|
||||
|
||||
if ($force) {
|
||||
|
@ -503,7 +501,7 @@ class studyplan {
|
|||
$DB->delete_records("local_treestudyplan_coach", ["studyplan_id" => $this->id]);
|
||||
$DB->delete_records("local_treestudyplan_cohort", ["studyplan_id" => $this->id]);
|
||||
$DB->delete_records("local_treestudyplan_user", ["studyplan_id" => $this->id]);
|
||||
//
|
||||
//
|
||||
$DB->delete_records('local_treestudyplan', ['id' => $this->id]);
|
||||
return success::success();
|
||||
}
|
||||
|
@ -514,7 +512,7 @@ class studyplan {
|
|||
* @param int $contextid Optional contextid to search in. ANY context used if left empty
|
||||
* @return studyplan[]
|
||||
*/
|
||||
public static function find_all($contextid = -1) : array {
|
||||
public static function find_all($contextid = -1): array {
|
||||
global $DB, $USER;
|
||||
$list = [];
|
||||
|
||||
|
@ -541,7 +539,7 @@ class studyplan {
|
|||
* @param int $contextid Optional contextid to search in. ANY context used if left empty
|
||||
* @return studyplan[]
|
||||
*/
|
||||
public static function find_template($contextid = -1) : array {
|
||||
public static function find_template($contextid = -1): array {
|
||||
global $DB, $USER;
|
||||
$list = [];
|
||||
|
||||
|
@ -569,7 +567,7 @@ class studyplan {
|
|||
* @param int $contextid Optional contextid to search in. ANY context used if left empty
|
||||
* @return int
|
||||
*/
|
||||
public static function count_template($contextid = -1) : int {
|
||||
public static function count_template($contextid = -1): int {
|
||||
global $DB, $USER;
|
||||
$list = [];
|
||||
|
||||
|
@ -604,7 +602,7 @@ class studyplan {
|
|||
} else if ($contextid > 1) {
|
||||
$where .= " AND context_id = :contextid";
|
||||
}
|
||||
|
||||
|
||||
$ids = $DB->get_fieldset_select(self::TABLE, "id", $where, ["shortname" => $shortname, "contextid" => $contextid]);
|
||||
foreach ($ids as $id) {
|
||||
$list[] = self::find_by_id($id);
|
||||
|
@ -665,7 +663,7 @@ class studyplan {
|
|||
* @param int $userid Id of the user to search for
|
||||
* @return studyplan[]
|
||||
*/
|
||||
public static function find_for_user($userid) : array {
|
||||
public static function find_for_user($userid): array {
|
||||
global $DB;
|
||||
|
||||
$sql = "SELECT s.id FROM {local_treestudyplan} s
|
||||
|
@ -699,7 +697,7 @@ class studyplan {
|
|||
* 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 {
|
||||
public static function exist_for_user($userid): bool {
|
||||
global $DB;
|
||||
$count = 0;
|
||||
$sql = "SELECT COUNT(s.id) FROM {local_treestudyplan} s
|
||||
|
@ -722,7 +720,7 @@ class studyplan {
|
|||
* Retrieve the users linked to this studyplan.
|
||||
* @return stdClass[] User objects
|
||||
*/
|
||||
public function find_linked_users() : array {
|
||||
public function find_linked_users(): array {
|
||||
global $DB;
|
||||
|
||||
$users = [];
|
||||
|
@ -793,11 +791,11 @@ class studyplan {
|
|||
public function is_coach($user=null) {
|
||||
global $DB, $USER
|
||||
;
|
||||
if ( ! (premium::enabled() && \get_config("local_treestudyplan","enablecoach")) ) {
|
||||
if ( ! (premium::enabled() && \get_config("local_treestudyplan", "enablecoach")) ) {
|
||||
// If coach role is not available, return false immediately.
|
||||
return false;
|
||||
}
|
||||
if($user == null) {
|
||||
if ($user == null) {
|
||||
$user = $USER;
|
||||
$userid = $USER->id;
|
||||
} else if (is_numeric($user)) {
|
||||
|
@ -805,9 +803,9 @@ class studyplan {
|
|||
} else {
|
||||
$userid = $user->id;
|
||||
}
|
||||
$r = $DB->get_record(self::TABLE_COACH,["studyplan_id" => $this->id, "user_id"=> $userid]);
|
||||
$r = $DB->get_record(self::TABLE_COACH, ["studyplan_id" => $this->id, "user_id"=> $userid]);
|
||||
|
||||
if ($r && has_capability(associationservice::CAP_COACH,$this->context(),$userid)) {
|
||||
if ($r && has_capability(associationservice::CAP_COACH, $this->context(), $userid)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -818,7 +816,7 @@ class studyplan {
|
|||
* Webservice structure for userinfo
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function user_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function user_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of studyplan'),
|
||||
"userid" => new \external_value(PARAM_INT, 'id of user the plan is shown for'),
|
||||
|
@ -826,8 +824,8 @@ class studyplan {
|
|||
"shortname" => new \external_value(PARAM_TEXT, 'shortname of studyplan'),
|
||||
"description" => new \external_value(PARAM_RAW, 'description of studyplan'),
|
||||
"descriptionformat" => new \external_value(PARAM_INT, 'description format'),
|
||||
"icon" => new \external_value(PARAM_RAW,'icon for this plan'),
|
||||
"progress" => new \external_value(PARAM_FLOAT,"fraction of completed modules"),
|
||||
"icon" => new \external_value(PARAM_RAW, 'icon for this plan'),
|
||||
"progress" => new \external_value(PARAM_FLOAT, "fraction of completed modules"),
|
||||
"idnumber" => new \external_value(PARAM_TEXT, 'idnumber of curriculum'),
|
||||
"pages" => new \external_multiple_structure(studyplanpage::user_structure()),
|
||||
"aggregation_info" => aggregator::basic_structure(),
|
||||
|
@ -893,9 +891,9 @@ class studyplan {
|
|||
* @param string $shortname New shortname of studyplan
|
||||
* @return array Simple webservices model of plan
|
||||
*/
|
||||
public static function duplicate_plan($planid, $name, $shortname) : array {
|
||||
public static function duplicate_plan($planid, $name, $shortname): array {
|
||||
$ori = self::find_by_id($planid);
|
||||
$new = $ori->duplicate($name, $shortname,$ori->context()->id);
|
||||
$new = $ori->duplicate($name, $shortname, $ori->context()->id);
|
||||
return $new->simple_model();
|
||||
}
|
||||
|
||||
|
@ -904,21 +902,21 @@ class studyplan {
|
|||
* @param string $name New fullname of studyplan
|
||||
* @param string $shortname New shortname of studyplan
|
||||
*/
|
||||
public function duplicate($name, $shortname, $contextid, $idnumber=null, $newstartdate = null) : self {
|
||||
public function duplicate($name, $shortname, $contextid, $idnumber=null, $newstartdate = null): self {
|
||||
// First duplicate the studyplan structure.
|
||||
$newplan = self::add([
|
||||
'name' => $name,
|
||||
'shortname' => $shortname,
|
||||
'idnumber' => ($idnumber?$idnumber:$this->r->idnumber),
|
||||
'idnumber' => ($idnumber ? $idnumber : $this->r->idnumber),
|
||||
'context_id' => $contextid,
|
||||
'description' => $this->r->description,
|
||||
'descriptionformat' => $this->r->descriptionformat,
|
||||
'aggregation' => $this->r->aggregation,
|
||||
'aggregation_config' => $this->r->aggregation_config
|
||||
],true);
|
||||
], true);
|
||||
|
||||
// Copy any files related to this studyplan.
|
||||
$areas = ["icon","studyplan"];
|
||||
$areas = ["icon", "studyplan"];
|
||||
$fs = \get_file_storage();
|
||||
foreach ($areas as $area) {
|
||||
$files = $fs->get_area_files(
|
||||
|
@ -948,9 +946,9 @@ class studyplan {
|
|||
}
|
||||
|
||||
// Next, copy the studylines.
|
||||
$timeless = \get_config("local_treestudyplan","timelessperiods");
|
||||
$timeless = \get_config("local_treestudyplan", "timelessperiods");
|
||||
if (!$timeless && $newstartdate) {
|
||||
$newstart = new \DateTime(date("Y-m-d",$newstartdate));
|
||||
$newstart = new \DateTime(date("Y-m-d", $newstartdate));
|
||||
$oldstart = $this->startdate();
|
||||
$timeoffset = $oldstart->diff($newstart);
|
||||
} else {
|
||||
|
@ -958,7 +956,7 @@ class studyplan {
|
|||
}
|
||||
|
||||
foreach ($this->pages() as $page) {
|
||||
$newchild = $page->duplicate($newplan,$timeoffset);
|
||||
$newchild = $page->duplicate($newplan, $timeoffset);
|
||||
}
|
||||
|
||||
return $newplan;
|
||||
|
@ -967,7 +965,7 @@ class studyplan {
|
|||
/**
|
||||
* Description of export structure for webservices
|
||||
*/
|
||||
public static function export_structure() : \external_description {
|
||||
public static function export_structure(): \external_description {
|
||||
return new \external_single_structure([
|
||||
"format" => new \external_value(PARAM_TEXT, 'format of studyplan export'),
|
||||
"content" => new \external_value(PARAM_RAW, 'exported studyplan content'),
|
||||
|
@ -1010,7 +1008,6 @@ class studyplan {
|
|||
return $model;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Export files from file storage
|
||||
* @param string $area Name of the file area to export
|
||||
|
@ -1041,9 +1038,9 @@ class studyplan {
|
|||
* Import previously exported files into the file storage
|
||||
* @param string $area Name of the file area to import
|
||||
* @param mixed $importfiles List of files to import from string in the format exported in export_model()
|
||||
*
|
||||
*
|
||||
*/
|
||||
public function import_files($importfiles,$area) {
|
||||
public function import_files($importfiles, $area) {
|
||||
$fs = get_file_storage();
|
||||
foreach($importfiles as $file) {
|
||||
if ($file['name'] != ".") {
|
||||
|
@ -1055,7 +1052,7 @@ class studyplan {
|
|||
'filepath' => $file["path"], // Path of the file.
|
||||
'filename' => $file["name"], // Name of the file..
|
||||
];
|
||||
|
||||
|
||||
$fs->create_file_from_string($fileinfo, convert_uudecode($file["content"]));
|
||||
}
|
||||
}
|
||||
|
@ -1099,11 +1096,11 @@ class studyplan {
|
|||
|
||||
// Import the files
|
||||
if (isset( $planmodel['files']) && is_array( $planmodel['files'])) {
|
||||
$plan->import_files( $planmodel['files'],"studyplan");
|
||||
$plan->import_files( $planmodel['files'], "studyplan");
|
||||
}
|
||||
// Import the icon
|
||||
if (isset( $planmodel['iconfiles']) && is_array( $planmodel['iconfiles'])) {
|
||||
$plan->import_files( $planmodel['iconfiles'],"icon");
|
||||
$plan->import_files( $planmodel['iconfiles'], "icon");
|
||||
}
|
||||
|
||||
// Now import each page.
|
||||
|
@ -1138,12 +1135,11 @@ class studyplan {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import pages from decoded array model
|
||||
* @param array $model Decoded array
|
||||
*/
|
||||
protected function import_pages_model($model) : bool {
|
||||
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();
|
||||
|
@ -1152,7 +1148,7 @@ class studyplan {
|
|||
$page->import_periods_model($p["perioddesc"]);
|
||||
$page->import_studylines_model($p["studylines"]);
|
||||
if ($p['files']) {
|
||||
$page->import_files($p["files"],'studyplanpage');
|
||||
$page->import_files($p["files"], 'studyplanpage');
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -1181,7 +1177,7 @@ class studyplan {
|
|||
/**
|
||||
* Check if the studyplan as changed regarding courses and associated cohorts
|
||||
*/
|
||||
public function has_csync_changed() : bool {
|
||||
public function has_csync_changed(): bool {
|
||||
return ($this->r->csync_flag > 0) ? true : false;
|
||||
}
|
||||
|
||||
|
@ -1189,7 +1185,7 @@ class studyplan {
|
|||
* See if the specified course id is linked in this studyplan
|
||||
* @param int $courseid Id of course to check
|
||||
*/
|
||||
public function course_linked($courseid) : bool {
|
||||
public function course_linked($courseid): bool {
|
||||
global $DB;
|
||||
|
||||
$sql = "SELECT COUNT(i.id)
|
||||
|
@ -1203,13 +1199,12 @@ class studyplan {
|
|||
return ($count > 0) ? true : false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all study lines linked to this plan (quickly)
|
||||
* Used for cohort enrolment cascading
|
||||
* @return studyline[]
|
||||
*/
|
||||
public function get_all_studylines() : array {
|
||||
public function get_all_studylines(): array {
|
||||
global $DB;
|
||||
|
||||
$sql = "SELECT l.id
|
||||
|
@ -1242,7 +1237,7 @@ class studyplan {
|
|||
* List the user id's explicitly associated with this studyplan
|
||||
* @return int[]
|
||||
*/
|
||||
public function get_linked_user_ids() : array {
|
||||
public function get_linked_user_ids(): array {
|
||||
global $CFG, $DB;
|
||||
|
||||
$sql = "SELECT DISTINCT j.user_id FROM {local_treestudyplan_user} j
|
||||
|
@ -1254,7 +1249,7 @@ class studyplan {
|
|||
* See if the specified badge is linked in this studyplan
|
||||
* @param int $badgeid Badge id
|
||||
*/
|
||||
public function badge_linked($badgeid) : bool {
|
||||
public function badge_linked($badgeid): bool {
|
||||
global $DB;
|
||||
|
||||
$sql = "SELECT COUNT(i.id)
|
||||
|
|
|
@ -53,7 +53,7 @@ class studyplanpage {
|
|||
* Get aggregator for the studyplan (page)
|
||||
* @return aggregator
|
||||
*/
|
||||
public function aggregator() : aggregator {
|
||||
public function aggregator(): aggregator {
|
||||
return $this->studyplan->aggregator();
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ class studyplanpage {
|
|||
/**
|
||||
* Find studyplan for this page
|
||||
*/
|
||||
public function studyplan() : studyplan {
|
||||
public function studyplan(): studyplan {
|
||||
return $this->studyplan;
|
||||
}
|
||||
|
||||
|
@ -143,9 +143,9 @@ class studyplanpage {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Return description with all file references resolved
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function description() {
|
||||
$text = \file_rewrite_pluginfile_urls(
|
||||
|
@ -153,7 +153,7 @@ class studyplanpage {
|
|||
$this->r->description,
|
||||
// The pluginfile URL which will serve the request.
|
||||
'pluginfile.php',
|
||||
|
||||
|
||||
// The combination of contextid / component / filearea / itemid
|
||||
// form the virtual bucket that file are stored in.
|
||||
\context_system::instance()->id, // System instance is always used for this
|
||||
|
@ -181,7 +181,7 @@ class studyplanpage {
|
|||
* Webservice structure for basic info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function simple_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function simple_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of studyplan page'),
|
||||
"fullname" => new \external_value(PARAM_TEXT, 'name of studyplan page'),
|
||||
|
@ -211,7 +211,7 @@ class studyplanpage {
|
|||
'enddate' => $this->r->enddate,
|
||||
'timing' => $this->timing(),
|
||||
"perioddesc" => period::page_model($this),
|
||||
'timeless' => \get_config("local_treestudyplan","timelessperiods"),
|
||||
'timeless' => \get_config("local_treestudyplan", "timelessperiods"),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -219,7 +219,7 @@ class studyplanpage {
|
|||
* Webservice structure for editor info
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function editor_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function editor_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of studyplan'),
|
||||
"fullname" => new \external_value(PARAM_TEXT, 'name of studyplan page'),
|
||||
|
@ -253,7 +253,7 @@ class studyplanpage {
|
|||
'timing' => $this->timing(),
|
||||
'studylines' => [],
|
||||
"perioddesc" => period::page_model($this),
|
||||
'timeless' => \get_config("local_treestudyplan","timelessperiods"),
|
||||
'timeless' => \get_config("local_treestudyplan", "timelessperiods"),
|
||||
];
|
||||
|
||||
$children = studyline::find_page_children($this);
|
||||
|
@ -268,7 +268,7 @@ class studyplanpage {
|
|||
* @param mixed $fields Parameter for new study plan page
|
||||
* @param bool $bare If true, do not create a first page with copy of studyplan names
|
||||
*/
|
||||
public static function add($fields, $bare = false) : self {
|
||||
public static function add($fields, $bare = false): self {
|
||||
global $DB;
|
||||
|
||||
if (!isset($fields['studyplan_id'])) {
|
||||
|
@ -297,8 +297,8 @@ class studyplanpage {
|
|||
$page = self::find_by_id($id); // Make sure the new page is immediately cached.
|
||||
|
||||
if (!$bare) {
|
||||
|
||||
if(get_config("local_treestudyplan","copystudylinesnewpage")) {
|
||||
|
||||
if (get_config("local_treestudyplan", "copystudylinesnewpage")) {
|
||||
$templatepage = null;
|
||||
$templatelines = [];
|
||||
// find the latest a page with lines in the plan
|
||||
|
@ -316,16 +316,16 @@ class studyplanpage {
|
|||
if (isset($templatepage)) {
|
||||
foreach ($templatelines as $l) {
|
||||
$map = []; // Bare copy still requires passing an empty array.
|
||||
$l->duplicate($page,$map,true); // Do bare copy, which does not include line content.
|
||||
$l->duplicate($page, $map, true); // Do bare copy, which does not include line content.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(count(studyline::find_page_children($page)) == 0) {
|
||||
if (count(studyline::find_page_children($page)) == 0) {
|
||||
// Add an empty study line if there are currently no study lines
|
||||
$lineinfo = ['page_id' => $id,
|
||||
'name' => get_string("default_line_name","local_treestudyplan"),
|
||||
'shortname' => get_string("default_line_shortname","local_treestudyplan"),
|
||||
'name' => get_string("default_line_name", "local_treestudyplan"),
|
||||
'shortname' => get_string("default_line_shortname", "local_treestudyplan"),
|
||||
"color" => "#DDDDDD",
|
||||
];
|
||||
studyline::add($lineinfo);
|
||||
|
@ -339,10 +339,10 @@ class studyplanpage {
|
|||
* Edit studyplan page
|
||||
* @param mixed $fields Parameters to change
|
||||
*/
|
||||
public function edit($fields) : self {
|
||||
public function edit($fields): self {
|
||||
global $DB;
|
||||
$editable = ['fullname', 'shortname', 'description', 'descriptionformat', 'periods', 'startdate', 'enddate'];
|
||||
$info = ['id' => $this->id, ];
|
||||
$info = ['id' => $this->id ];
|
||||
foreach ($editable as $f) {
|
||||
if (array_key_exists($f, $fields)) {
|
||||
$info[$f] = $fields[$f];
|
||||
|
@ -386,7 +386,7 @@ class studyplanpage {
|
|||
* Webservice structure for userinfo
|
||||
* @param int $value Webservice requirement constant
|
||||
*/
|
||||
public static function user_structure($value = VALUE_REQUIRED) : \external_description {
|
||||
public static function user_structure($value = VALUE_REQUIRED): \external_description {
|
||||
return new \external_single_structure([
|
||||
"id" => new \external_value(PARAM_INT, 'id of studyplan page'),
|
||||
"fullname" => new \external_value(PARAM_TEXT, 'name of studyplan page'),
|
||||
|
@ -420,7 +420,7 @@ class studyplanpage {
|
|||
'timing' => $this->timing(),
|
||||
'studylines' => [],
|
||||
"perioddesc" => period::page_model($this),
|
||||
'timeless' => \get_config("local_treestudyplan","timelessperiods"),
|
||||
'timeless' => \get_config("local_treestudyplan", "timelessperiods"),
|
||||
];
|
||||
|
||||
$children = studyline::find_page_children($this);
|
||||
|
@ -444,7 +444,7 @@ class studyplanpage {
|
|||
foreach ($items as $c) {
|
||||
if (in_array($c->type(), studyline::COURSE_TYPES)) {
|
||||
$courses += 1;
|
||||
if($c->completion($userid) >= completion::COMPLETED){
|
||||
if ($c->completion($userid) >= completion::COMPLETED) {
|
||||
$completed += 1;
|
||||
}
|
||||
}
|
||||
|
@ -479,7 +479,7 @@ class studyplanpage {
|
|||
* @param int $pageid Id of the page to copy
|
||||
* @param studyplan $newstudyplan Studyplan to copy the page into
|
||||
*/
|
||||
public static function duplicate_page(int $pageid, studyplan $newstudyplan) : self {
|
||||
public static function duplicate_page(int $pageid, studyplan $newstudyplan): self {
|
||||
$ori = self::find_by_id($pageid);
|
||||
$new = $ori->duplicate($newstudyplan);
|
||||
return $new;
|
||||
|
@ -489,11 +489,11 @@ class studyplanpage {
|
|||
* Duplicate this studyplan page
|
||||
* @param studyplan $newstudyplan Studyplan to copy the page into
|
||||
*/
|
||||
public function duplicate(studyplan $newstudyplan, $timeoffset = null) : self {
|
||||
public function duplicate(studyplan $newstudyplan, $timeoffset = null): self {
|
||||
if ($timeoffset == null) {
|
||||
$timeoffset = new \DateInterval("P0D");
|
||||
}
|
||||
|
||||
|
||||
// First duplicate the studyplan structure.
|
||||
$new = self::add([
|
||||
'studyplan_id' => $newstudyplan->id(),
|
||||
|
@ -502,7 +502,7 @@ class studyplanpage {
|
|||
'description' => $this->r->description,
|
||||
'pages' => $this->r->pages,
|
||||
'startdate' => $this->startdate()->add($timeoffset)->format("Y-m-d"),
|
||||
'enddate' => empty($this->r->enddate) ? null : ($this->enddate()->add($timeoffset)->format("Y-m-d")),
|
||||
'enddate' => empty($this->r->enddate) ? null : ($this->enddate()->add($timeoffset)->format("Y-m-d")),
|
||||
]);
|
||||
|
||||
// Copy any files related to this page.
|
||||
|
@ -550,7 +550,7 @@ class studyplanpage {
|
|||
$translation = [];
|
||||
$newchild = $c->duplicate($new, $translation);
|
||||
$itemtranslation += $translation; // Fixes behaviour where translation array is reset on each call.
|
||||
$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.
|
||||
|
@ -569,7 +569,7 @@ class studyplanpage {
|
|||
/**
|
||||
* Description of export structure for webservices
|
||||
*/
|
||||
public static function export_structure() : \external_description {
|
||||
public static function export_structure(): \external_description {
|
||||
return new \external_single_structure([
|
||||
"format" => new \external_value(PARAM_TEXT, 'format of studyplan export'),
|
||||
"content" => new \external_value(PARAM_RAW, 'exported studyplan content'),
|
||||
|
@ -748,9 +748,9 @@ class studyplanpage {
|
|||
* Import previously exported files into the file storage
|
||||
* @param string $area Name of the file area to export
|
||||
* @param mixed $importfiles List of files to import from string in the format exported in export_model()
|
||||
*
|
||||
*
|
||||
*/
|
||||
public function import_files($importfiles,$area) {
|
||||
public function import_files($importfiles, $area) {
|
||||
$fs = get_file_storage();
|
||||
foreach($importfiles as $file) {
|
||||
if ($file['name'] != ".") {
|
||||
|
@ -768,7 +768,6 @@ class studyplanpage {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Export this pages periods into an array before serialization
|
||||
* @return array
|
||||
|
@ -871,7 +870,7 @@ class studyplanpage {
|
|||
$itemtranslation = [];
|
||||
$itemconnections = [];
|
||||
foreach ($model as $ix => $linemodel) {
|
||||
$translation = [];
|
||||
$translation = [];
|
||||
$connections = [];
|
||||
$linemap[$ix]->import_studyitems($linemodel["slots"], $translation, $connections);
|
||||
$itemtranslation += $translation; // Fixes behaviour where translation array is reset on each call.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -43,7 +43,7 @@ class success {
|
|||
* @param string $msg Message to add to result
|
||||
* @param array|object $data Custom data to pass to receiver
|
||||
*/
|
||||
public static function success($data=[]) : self {
|
||||
public static function success($data=[]): self {
|
||||
return new self(true, 'success', $data);
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ class success {
|
|||
* @param string $msg Message to add to result
|
||||
* @param array|object $data Custom data to pass to receiver
|
||||
*/
|
||||
public static function fail($msg = "", $data=[]) : self {
|
||||
public static function fail($msg = "", $data=[]): self {
|
||||
return new self(false, $msg, $data);
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ class success {
|
|||
* @param array|object $data Custom data to pass to receiver
|
||||
*/
|
||||
public function __construct($success, $msg, $data=[]) {
|
||||
$this->success = ($success) ? true : false;
|
||||
$this->success = ($success) ? true : false;
|
||||
$this->msg = $msg;
|
||||
$this->data = json_encode($data);
|
||||
}
|
||||
|
@ -71,7 +71,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_RAW, 'message'),
|
||||
|
@ -79,7 +79,6 @@ class success {
|
|||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make the webservice result model
|
||||
* @return array Webservice value
|
||||
|
|
|
@ -72,7 +72,7 @@ class autocohortsync extends \core\task\scheduled_task {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Perform immediate syncronization on a single studyplan.
|
||||
*/
|
||||
public static function syncplan(studyplan $studyplan) {
|
||||
|
@ -86,7 +86,7 @@ class autocohortsync extends \core\task\scheduled_task {
|
|||
$studyplan->clear_csync_changed(); // Clear the csync required flag.
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Perform immediate syncronization on a single studyline.
|
||||
*/
|
||||
public static function syncline(studyline $line) {
|
||||
|
|
|
@ -33,7 +33,6 @@ class teachingfinder {
|
|||
/** @var string */
|
||||
const TABLE = "local_treestudyplan_teachers";
|
||||
|
||||
|
||||
/**
|
||||
* List all studyplans the current user is teaching
|
||||
* (Updates the cache if no results are found the first time)
|
||||
|
@ -62,7 +61,7 @@ class teachingfinder {
|
|||
* @param studyplan $plan Studyplan to check
|
||||
* @return bool If teaching in this plan
|
||||
*/
|
||||
public static function is_teaching_studyplan(studyplan $plan,$userid) {
|
||||
public static function is_teaching_studyplan(studyplan $plan, $userid) {
|
||||
global $DB;
|
||||
$count = $DB->count_records(self::TABLE, ['teacher_id' => $userid, "studyplan_id" => $plan->id()]);
|
||||
return ($count > 0)?true:false;
|
||||
|
@ -80,7 +79,6 @@ class teachingfinder {
|
|||
return ($count > 0)?true:false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if current user is teaching in a specific studyplan
|
||||
* (Does not update the cache if results are 0)
|
||||
|
@ -89,7 +87,7 @@ class teachingfinder {
|
|||
*/
|
||||
public static function am_teaching_studyplan(studyplan $plan) {
|
||||
global $USER;
|
||||
return self::is_teaching_studyplan($plan,$USER->id);
|
||||
return self::is_teaching_studyplan($plan, $USER->id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,7 +101,7 @@ class teachingfinder {
|
|||
return self::is_teaching($USER->id);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Check if a user is teaching in a specific course
|
||||
* @param int $courseid ID of the course
|
||||
* @param int $userid ID of the user
|
||||
|
@ -114,14 +112,14 @@ class teachingfinder {
|
|||
return is_enrolled($coursecontext, $userid, 'mod/assign:grade');
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Check if current user is teaching in a specific course
|
||||
* @param int $courseid ID of the course
|
||||
* @return bool True if teaching in the course
|
||||
*/
|
||||
public static function am_teaching_course($courseid) {
|
||||
global $USER;
|
||||
return self::is_teaching_course($courseid,$USER->id);
|
||||
return self::is_teaching_course($courseid, $USER->id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -45,21 +45,20 @@ class utilityservice extends \external_api {
|
|||
*/
|
||||
const CAP_VIEW = "local/treestudyplan:viewuserreports";
|
||||
|
||||
|
||||
protected static function load_mform($formname, $params, $ajaxformdata = null) {
|
||||
global $CFG;
|
||||
/* We don't need to load the form php file (class autoloading will handle that)
|
||||
but we do need to check it's existence to give a nice developer warning
|
||||
and protect against some forms of hacking
|
||||
and protect against some forms of hacking
|
||||
*/
|
||||
$modmoodleform = "$CFG->dirroot/local/treestudyplan/classes/form/{$formname}.php";
|
||||
if (!file_exists($modmoodleform)) {
|
||||
throw new \moodle_exception('noformfile', 'local_treestudyplan','',$formname);
|
||||
throw new \moodle_exception('noformfile', 'local_treestudyplan', '', $formname);
|
||||
}
|
||||
|
||||
|
||||
$mformclassname = "\\local_treestudyplan\\form\\{$formname}";
|
||||
// Check if the form is a subclass of formbase.
|
||||
if ( is_a($mformclassname,"\\local_treestudyplan\\form\\formbase",true)) {
|
||||
if ( is_a($mformclassname, "\\local_treestudyplan\\form\\formbase", true)) {
|
||||
$jsonparams = json_decode($params);
|
||||
$mform = new $mformclassname( $jsonparams, $ajaxformdata);
|
||||
return $mform;
|
||||
|
@ -92,8 +91,7 @@ class utilityservice extends \external_api {
|
|||
global $OUTPUT, $PAGE, $CFG;
|
||||
|
||||
\external_api::validate_context(\context_system::instance());
|
||||
require_login(null,false,null);
|
||||
|
||||
require_login(null, false, null);
|
||||
|
||||
// Hack alert: Set a default URL to stop the annoying debug.
|
||||
$PAGE->set_url('/');
|
||||
|
@ -106,7 +104,7 @@ class utilityservice extends \external_api {
|
|||
// Load the form before any output is started.
|
||||
$mform = self::load_mform($formname, $params);
|
||||
// Perform actual render.
|
||||
$html = $mform->render();
|
||||
$html = $mform->render();
|
||||
|
||||
$jsfooter = $PAGE->requires->get_end_code();
|
||||
$output = ['html' => $html, 'javascript' => $jsfooter];
|
||||
|
@ -130,7 +128,7 @@ class utilityservice extends \external_api {
|
|||
/**
|
||||
* Parameter description for webservice function submit_cm_editform
|
||||
*/
|
||||
public static function submit_mform_parameters() : \external_function_parameters {
|
||||
public static function submit_mform_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
'formname' => new \external_value(PARAM_COMPONENT, 'name of the treestudyplan form to parse'),
|
||||
'params' => new \external_value(PARAM_RAW, 'JSON encoded parameters for form initialization'),
|
||||
|
@ -141,7 +139,7 @@ class utilityservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function submit_cm_editform
|
||||
*/
|
||||
public static function submit_mform_returns() : \external_description {
|
||||
public static function submit_mform_returns(): \external_description {
|
||||
return success::structure(); // Success structure includes data component which encodes date in json format.
|
||||
}
|
||||
|
||||
|
@ -154,24 +152,23 @@ class utilityservice extends \external_api {
|
|||
*/
|
||||
public static function submit_mform($formname, $params, $formdata) {
|
||||
\external_api::validate_context(\context_system::instance());
|
||||
require_login(null,false,null);
|
||||
require_login(null, false, null);
|
||||
|
||||
$ajaxformdata = [];
|
||||
parse_str($formdata,$ajaxformdata);
|
||||
parse_str($formdata, $ajaxformdata);
|
||||
|
||||
// Load the form, provide submitted form data and perform security checks
|
||||
$mform = self::load_mform($formname, $params, $ajaxformdata);
|
||||
|
||||
|
||||
$return = $mform->process_submission();
|
||||
// Pass form processing result as success data component.
|
||||
return success::success($return)->model();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parameter description for webservice function submit_cm_editform
|
||||
*/
|
||||
public static function getsettings_parameters() : \external_function_parameters {
|
||||
public static function getsettings_parameters(): \external_function_parameters {
|
||||
return new \external_function_parameters( [
|
||||
] );
|
||||
}
|
||||
|
@ -179,7 +176,7 @@ class utilityservice extends \external_api {
|
|||
/**
|
||||
* Return value description for webservice function submit_cm_editform
|
||||
*/
|
||||
public static function getsettings_returns() : \external_description {
|
||||
public static function getsettings_returns(): \external_description {
|
||||
return new \external_single_structure([
|
||||
"hivizdropslots" => new \external_value(PARAM_BOOL, 'High visibility drop slots for items'),
|
||||
"toolboxleft" => new \external_value(PARAM_BOOL, 'Start toolbox default on left side'),
|
||||
|
@ -192,13 +189,12 @@ class utilityservice extends \external_api {
|
|||
*/
|
||||
public static function getsettings() {
|
||||
\external_api::validate_context(\context_system::instance());
|
||||
require_login(null,false,null);
|
||||
require_login(null, false, null);
|
||||
|
||||
return [
|
||||
"hivizdropslots" => get_config("local_treestudyplan","hivizdropslots"),
|
||||
"toolboxleft" => get_config("local_treestudyplan","toolboxleft")
|
||||
"hivizdropslots" => get_config("local_treestudyplan", "hivizdropslots"),
|
||||
"toolboxleft" => get_config("local_treestudyplan", "toolboxleft")
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -66,8 +66,8 @@ cli_writeln("Creating {$amount} new badges");
|
|||
$fortunepath = "/usr/games/fortune";
|
||||
if (!is_executable($fortunepath)) {
|
||||
// Get a fortune if it is available.
|
||||
cli_error('/usr/bin/fortune not found, which is needed for this script. Please install fortune',2);
|
||||
}
|
||||
cli_error('/usr/bin/fortune not found, which is needed for this script. Please install fortune', 2);
|
||||
}
|
||||
|
||||
// Get administrator role and log in as.
|
||||
$user = get_admin();
|
||||
|
@ -76,7 +76,7 @@ if (!$user) {
|
|||
cli_error("Unable to find admin user in DB.");
|
||||
}
|
||||
|
||||
$auth = empty($user->auth) ? 'manual' : $user->auth;
|
||||
$auth = empty($user->auth) ? 'manual' : $user->auth;
|
||||
if ($auth == 'nologin' || !is_enabled_auth($auth)) {
|
||||
cli_error(sprintf("User authentication is either 'nologin' or disabled. Check Moodle authentication method for '%s'",
|
||||
$user->username));
|
||||
|
@ -87,7 +87,6 @@ $authplugin->sync_roles($user);
|
|||
login_attempt_valid($user);
|
||||
complete_user_login($user);
|
||||
|
||||
|
||||
for ($i=0; $i<$amount; $i++) {
|
||||
$fortune = shell_exec("{$fortunepath} -n 160 ");
|
||||
$pieces = explode(" ", $fortune);
|
||||
|
@ -95,11 +94,10 @@ for ($i=0; $i<$amount; $i++) {
|
|||
|
||||
$fordb = new \stdClass();
|
||||
$fordb->id = null;
|
||||
|
||||
|
||||
$now = time();
|
||||
|
||||
$randomicon = new randomimage(10,256,256);
|
||||
|
||||
$randomicon = new randomimage(10, 256, 256);
|
||||
|
||||
$fordb->name = $name;
|
||||
$fordb->version = 1;
|
||||
|
@ -134,7 +132,7 @@ for ($i=0; $i<$amount; $i++) {
|
|||
$newid = $DB->insert_record('badge', $fordb, true);
|
||||
|
||||
// Trigger event, badge created.
|
||||
$eventparams = array('objectid' => $newid, 'context' => $PAGE->context);
|
||||
$eventparams = ['objectid' => $newid, 'context' => $PAGE->context];
|
||||
$event = \core\event\badge_created::create($eventparams);
|
||||
$event->trigger();
|
||||
|
||||
|
@ -143,4 +141,3 @@ for ($i=0; $i<$amount; $i++) {
|
|||
cli_writeln("Created new badge '{$name}'");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ if (!$user) {
|
|||
cli_error("Unable to find admin user in DB.");
|
||||
}
|
||||
|
||||
$auth = empty($user->auth) ? 'manual' : $user->auth;
|
||||
$auth = empty($user->auth) ? 'manual' : $user->auth;
|
||||
if ($auth == 'nologin' || !is_enabled_auth($auth)) {
|
||||
cli_error(sprintf("User authentication is either 'nologin' or disabled. Check Moodle authentication method for '%s'",
|
||||
$user->username));
|
||||
|
|
15
coach.php
15
coach.php
|
@ -28,21 +28,18 @@ require_once($CFG->libdir.'/weblib.php');
|
|||
|
||||
$systemcontext = context_system::instance();
|
||||
|
||||
$PAGE->set_url("/local/treestudyplan/coach.php", array());
|
||||
$PAGE->set_url("/local/treestudyplan/coach.php", []);
|
||||
require_login();
|
||||
|
||||
|
||||
$PAGE->set_pagelayout('base');
|
||||
$PAGE->set_context($systemcontext);
|
||||
$PAGE->set_title(get_string('coaching_plans', 'local_treestudyplan'));
|
||||
$PAGE->set_heading(get_string('coaching_plans', 'local_treestudyplan'));
|
||||
|
||||
|
||||
premium::require_premium();
|
||||
if ( ! (\get_config("local_treestudyplan","enablecoach")) ) {
|
||||
throw new \moodle_exception("error:coachdisabled","local_treestudyplan");
|
||||
if ( ! (\get_config("local_treestudyplan", "enablecoach")) ) {
|
||||
throw new \moodle_exception("error:coachdisabled", "local_treestudyplan");
|
||||
}
|
||||
|
||||
|
||||
// Load javascripts and specific css.
|
||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue/bootstrap-vue.css'));
|
||||
|
@ -77,11 +74,11 @@ print $OUTPUT->header();
|
|||
<a href='#' @click.prevent='closeStudyplan'
|
||||
><i style='font-size: 150%;' class='fa fa-chevron-left'></i> <?php t('back');?></a>
|
||||
<span><?php t("studyplan_select"); ?></span>
|
||||
<s-studyplan-details
|
||||
v-model="displayedstudyplan"
|
||||
<s-studyplan-details
|
||||
v-model="displayedstudyplan"
|
||||
v-if="displayedstudyplan.description"
|
||||
></s-studyplan-details>
|
||||
<div class="flex-grow-1"><!-- Spacer to align student selector right --></div>
|
||||
<div class="flex-grow-1"><!-- Spacer to align student selector right --></div>
|
||||
<span><?php t('selectstudent_btn') ?></span>
|
||||
<s-prevnext-selector
|
||||
:options="associatedstudents"
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$services = [
|
||||
|
||||
|
||||
];
|
||||
|
||||
$functions = [
|
||||
|
@ -227,7 +227,7 @@ $functions = [
|
|||
'ajax' => true,
|
||||
'capabilities' => '',
|
||||
'loginrequired' => true,
|
||||
],
|
||||
],
|
||||
'local_treestudyplan_search_related_badges' => [ // Web service function name.
|
||||
'classname' => '\local_treestudyplan\studyplanservice', // Class containing the external function.
|
||||
'methodname' => 'search_related_badges', // External function name.
|
||||
|
@ -236,7 +236,7 @@ $functions = [
|
|||
'ajax' => true,
|
||||
'capabilities' => '',
|
||||
'loginrequired' => true,
|
||||
],
|
||||
],
|
||||
|
||||
/***************************
|
||||
* Association functions
|
||||
|
|
|
@ -532,8 +532,6 @@ function xmldb_local_treestudyplan_upgrade($oldversion) {
|
|||
$dbman->add_field($table, $field);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Treestudyplan savepoint reached.
|
||||
upgrade_plugin_savepoint(true, 2024022502, 'local', 'treestudyplan');
|
||||
|
@ -564,13 +562,13 @@ function xmldb_local_treestudyplan_upgrade($oldversion) {
|
|||
$table->add_field('timeenrolled', XMLDB_TYPE_INTEGER, '12', null, null, null, null);
|
||||
$table->add_field('enrolled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
|
||||
$table->add_field('enrolledby', XMLDB_TYPE_INTEGER, '18', null, null, null, null);
|
||||
|
||||
|
||||
// Adding keys to table local_treestudyplan_lineuser.
|
||||
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
|
||||
$table->add_key('line_id-id', XMLDB_KEY_FOREIGN, ['line_id'], 'local_treestudyplan_line', ['id']);
|
||||
$table->add_key('user_id-id', XMLDB_KEY_FOREIGN, ['user_id'], 'user', ['id']);
|
||||
$table->add_key('enrolledby-id', XMLDB_KEY_FOREIGN, ['enrolledby'], 'user', ['id']);
|
||||
|
||||
|
||||
// Conditionally launch create table for local_treestudyplan_lineuser.
|
||||
if (!$dbman->table_exists($table)) {
|
||||
$dbman->create_table($table);
|
||||
|
@ -634,7 +632,7 @@ function xmldb_local_treestudyplan_upgrade($oldversion) {
|
|||
}
|
||||
|
||||
if ($oldversion < 2024052400) {
|
||||
|
||||
|
||||
// Changing the default of field template on table local_treestudyplan to 0.
|
||||
$table = new xmldb_table('local_treestudyplan');
|
||||
$field = new xmldb_field('template', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'suspended');
|
||||
|
@ -649,12 +647,9 @@ function xmldb_local_treestudyplan_upgrade($oldversion) {
|
|||
// Launch change of default for field suspended.
|
||||
$dbman->change_field_default($table, $field);
|
||||
|
||||
|
||||
// Treestudyplan savepoint reached.
|
||||
upgrade_plugin_savepoint(true, 2024052400, 'local', 'treestudyplan');
|
||||
}
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
2
doc.php
2
doc.php
|
@ -26,7 +26,7 @@ require_once($CFG->libdir.'/weblib.php');
|
|||
|
||||
$systemcontext = context_system::instance();
|
||||
|
||||
$PAGE->set_url("/local/treestudyplan/doc.php", array());
|
||||
$PAGE->set_url("/local/treestudyplan/doc.php", []);
|
||||
if ($CFG->debugdeveloper) {
|
||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css'));
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ if (!empty($add)) {
|
|||
);
|
||||
|
||||
} else if (!empty($update)) {
|
||||
$data = $DB->get_record("local_treestudyplan_invit", array('id' => $update));
|
||||
$data = $DB->get_record("local_treestudyplan_invit", ['id' => $update]);
|
||||
$data->update = $update;
|
||||
if (empty($data) || $data->user_id != $USER->id) {
|
||||
throw new \moodle_exception('invalidaction', 'local_treestudyplan');;
|
||||
|
@ -64,7 +64,7 @@ if (!empty($add)) {
|
|||
}
|
||||
|
||||
} else if (!empty($resend)) {
|
||||
$data = $DB->get_record("local_treestudyplan_invit", array('id' => $resend));
|
||||
$data = $DB->get_record("local_treestudyplan_invit", ['id' => $resend]);
|
||||
$data->resend = $resend;
|
||||
if (empty($data) || $data->user_id != $USER->id) {
|
||||
throw new \moodle_exception('invalidaction', 'local_treestudyplan');;
|
||||
|
@ -77,7 +77,7 @@ if (!empty($add)) {
|
|||
print $OUTPUT->footer();
|
||||
exit;
|
||||
} else if (!empty($delete)) {
|
||||
$data = $DB->get_record("local_treestudyplan_invit", array('id' => $delete));
|
||||
$data = $DB->get_record("local_treestudyplan_invit", ['id' => $delete]);
|
||||
$data->delete = $delete;
|
||||
if (empty($data) || $data->user_id != $USER->id) {
|
||||
throw new \moodle_exception('invalidaction', 'local_treestudyplan');;
|
||||
|
|
|
@ -31,7 +31,7 @@ use local_treestudyplan\debug;
|
|||
|
||||
$systemcontext = context_system::instance();
|
||||
|
||||
$PAGE->set_url("/local/treestudyplan/edit-plan.php", array());
|
||||
$PAGE->set_url("/local/treestudyplan/edit-plan.php", []);
|
||||
require_login();
|
||||
|
||||
// Figure out the context (category or system, based on either category or context parameter).
|
||||
|
@ -73,19 +73,19 @@ if ($studyplancontext->id > 1) {
|
|||
$PAGE->navbar->add(get_string('cfg_plans', 'local_treestudyplan'));
|
||||
|
||||
// Coursecat context
|
||||
$cat = \core_course_category::get($studyplancontext->instanceid,IGNORE_MISSING,true); // We checck visibility later
|
||||
} else {
|
||||
$cat = \core_course_category::get($studyplancontext->instanceid, IGNORE_MISSING, true); // We checck visibility later
|
||||
} else {
|
||||
// System context
|
||||
$cat = \core_course_category::top();
|
||||
}
|
||||
|
||||
if (!$cat->is_uservisible()) {
|
||||
|
||||
throw new \moodle_exception("error:cannotviewcategory","local_treestudyplan","/local/treestudyplan/edit_plan.php",$contextname);
|
||||
throw new \moodle_exception("error:cannotviewcategory", "local_treestudyplan", "/local/treestudyplan/edit_plan.php", $contextname);
|
||||
}
|
||||
|
||||
if (!has_capability('local/treestudyplan:editstudyplan', $studyplancontext)) {
|
||||
throw new \moodle_exception("error:nostudyplaneditaccess","local_treestudyplan","/local/treestudyplan/edit_plan.php",$contextname);
|
||||
throw new \moodle_exception("error:nostudyplaneditaccess", "local_treestudyplan", "/local/treestudyplan/edit_plan.php", $contextname);
|
||||
}
|
||||
|
||||
// Load javascripts and specific css.
|
||||
|
@ -94,7 +94,7 @@ if ($CFG->debugdeveloper) {
|
|||
$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, [
|
||||
"defaultAggregation" => get_config("local_treestudyplan","aggregation_mode"),
|
||||
"defaultAggregation" => get_config("local_treestudyplan", "aggregation_mode"),
|
||||
]]);
|
||||
|
||||
/**
|
||||
|
@ -121,17 +121,17 @@ print $OUTPUT->header();
|
|||
<div v-cloak>
|
||||
<div v-if='!activestudyplan && usedcontexts && !loadingstudyplan' class='ml-3 mb-3 s-context-selector'>
|
||||
<b-form-select text='<?php print($contextname);?>' :value="contextid" @change='switchContext'
|
||||
:class="(!(usedcontexts.length))?'text-primary':''">
|
||||
:class="(!(usedcontexts.length)) ? 'text-primary' : ''">
|
||||
<b-form-select-option v-if='!(usedcontexts.length)' :value="contextid"
|
||||
:class="'text-primary'">
|
||||
<span><?php t("loading",null,"core"); ?>...</span></b-form-select-option>
|
||||
<span><?php t("loading", null, "core"); ?>...</span></b-form-select-option>
|
||||
<b-form-select-option v-for='ctx in usedcontexts' :key='ctx.id' :value="ctx.context_id"
|
||||
:class="(ctx.studyplancount > 0) ? 'font-weight-bold' : ''"
|
||||
><span v-for="(p, i) in ctx.category.path"
|
||||
><span v-if="i>0"> / </span>{{ p }}</span> <span>({{ ctx.studyplancount }})</span>
|
||||
</b-form-select-option>
|
||||
</b-form-select>
|
||||
<div v-if="!(usedcontexts.length)" style="position: relative; top: 0.3rem; width: 1.2rem; height: 1.2rem; font-size: 0.7rem;"
|
||||
<div v-if="!(usedcontexts.length)" style="position: relative; top: 0.3rem; width: 1.2rem; height: 1.2rem; font-size: 0.7rem;"
|
||||
class="spinner-border text-primary" role="status"></div>
|
||||
|
||||
</div>
|
||||
|
@ -154,15 +154,15 @@ print $OUTPUT->header();
|
|||
v-model="create.studyplan"
|
||||
type="button"
|
||||
variant="primary"
|
||||
default-aggregation="<?php print(get_config("local_treestudyplan","aggregation_mode")); ?>"
|
||||
default-aggregation="<?php print(get_config("local_treestudyplan", "aggregation_mode")); ?>"
|
||||
:contextid='contextid'
|
||||
><i class='fa fa-plus'></i> {{ text.studyplan_add }}</t-studyplan-edit>
|
||||
<b-button
|
||||
variant='danger' href='#' role='presentation' @click="import_studyplan "
|
||||
><i class='fa fa-upload'></i> {{ text.advanced_import_from_file }}</b-button
|
||||
><mform v-if="premiumenabled && templatecount > 0"
|
||||
name="studyplan_fromtemplateform"
|
||||
:params="{contextid: contextid }"
|
||||
name="studyplan_fromtemplateform"
|
||||
:params="{contextid: contextid }"
|
||||
@saved="onStudyPlanCreated"
|
||||
variant="success"
|
||||
type="button"
|
||||
|
|
|
@ -31,7 +31,7 @@ $invitedurl = "/local/treestudyplan/invited.php";
|
|||
|
||||
$systemcontext = context_system::instance();
|
||||
|
||||
$PAGE->set_url("/local/treestudyplan/invitations.php", array());
|
||||
$PAGE->set_url("/local/treestudyplan/invitations.php", []);
|
||||
require_login();
|
||||
|
||||
$PAGE->set_pagelayout('base');
|
||||
|
@ -45,12 +45,12 @@ $PAGE->requires->js_call_amd('local_treestudyplan/page-invitemanager', 'init');
|
|||
// Retrieve list of courses that the student is enrolled in.
|
||||
$sent = optional_param('sent', '', PARAM_INT);
|
||||
if (!empty($sent)) {
|
||||
$invite = $DB->get_record('local_treestudyplan_invit', array('id' => $sent));
|
||||
$invite = $DB->get_record('local_treestudyplan_invit', ['id' => $sent]);
|
||||
\core\notification::success(get_string('invite_resent_msg', 'local_treestudyplan', $invite));
|
||||
|
||||
};
|
||||
|
||||
if (!get_config("local_treestudyplan","enableplansharing")) {
|
||||
if (!get_config("local_treestudyplan", "enableplansharing")) {
|
||||
$PAGE->set_title(get_string('accessdenied', 'admin'));
|
||||
$PAGE->set_heading(get_string('accessdenied', 'admin'));
|
||||
|
||||
|
@ -59,7 +59,7 @@ if (!get_config("local_treestudyplan","enableplansharing")) {
|
|||
// Render page for skill level 0 (global).
|
||||
|
||||
print "<div class='box errorbox alert alert-danger'>";
|
||||
print get_string('accessdenied','admin');
|
||||
print get_string('accessdenied', 'admin');
|
||||
print "</div>";
|
||||
|
||||
print $OUTPUT->footer();
|
||||
|
@ -71,7 +71,7 @@ if (!get_config("local_treestudyplan","enableplansharing")) {
|
|||
|
||||
print "<p>".get_string('invite_description', 'local_treestudyplan')."</p>";
|
||||
|
||||
$invites = $DB->get_records('local_treestudyplan_invit', array('user_id' => $USER->id));
|
||||
$invites = $DB->get_records('local_treestudyplan_invit', ['user_id' => $USER->id]);
|
||||
|
||||
print "<h3>".get_string('invite_tablecaption', 'local_treestudyplan')."</h3>";
|
||||
print "<table class='m-manage_invites'>";
|
||||
|
|
|
@ -41,13 +41,13 @@ $PAGE->set_context($systemcontext);
|
|||
|
||||
// See if we can get a valid user for this invited.
|
||||
$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", ['key' => $invitekey]);
|
||||
|
||||
$invite = $DB->get_record_select("local_treestudyplan_invit",
|
||||
$DB->sql_compare_text("invitekey"). " = " . $DB->sql_compare_text(":invitekey"),
|
||||
['invitekey' => $invitekey]);
|
||||
|
||||
if (!get_config("local_treestudyplan","enableplansharing")) {
|
||||
if (!get_config("local_treestudyplan", "enableplansharing")) {
|
||||
$PAGE->set_title(get_string('accessdenied', 'admin'));
|
||||
$PAGE->set_heading(get_string('accessdenied', 'admin'));
|
||||
|
||||
|
@ -56,7 +56,7 @@ if (!get_config("local_treestudyplan","enableplansharing")) {
|
|||
// Render page for skill level 0 (global).
|
||||
|
||||
print "<div class='box errorbox alert alert-danger'>";
|
||||
print get_string('accessdenied','admin');
|
||||
print get_string('accessdenied', 'admin');
|
||||
print "</div>";
|
||||
|
||||
print $OUTPUT->footer();
|
||||
|
@ -85,7 +85,7 @@ if (!get_config("local_treestudyplan","enableplansharing")) {
|
|||
}
|
||||
$PAGE->requires->js_call_amd('local_treestudyplan/page-myreport', 'init', ['invited', $invitekey]);
|
||||
|
||||
$student = $DB->get_record('user', array('id' => $invite->user_id));
|
||||
$student = $DB->get_record('user', ['id' => $invite->user_id]);
|
||||
$PAGE->set_title(get_string('report_invited', 'local_treestudyplan', "{$student->firstname} {$student->lastname}" ));
|
||||
$PAGE->set_heading(get_string('report_invited', 'local_treestudyplan', "{$student->firstname} {$student->lastname}"));
|
||||
|
||||
|
|
|
@ -67,12 +67,12 @@ $string["invite_date"] = "Date";
|
|||
$string["invite_resent_msg"] = 'The invitation for {$a->name}<{$a->email}> has been sent';
|
||||
$string["invite_mail_subject"] = 'Shared grade card of {$a->sender}';
|
||||
$string["invite_mail_text"] = '
|
||||
<p>Dear {$a->invitee},</p>
|
||||
<p>Dear {$a->invitee}, </p>
|
||||
<p>I\'d like to invite you to view my study plan and progess.</p>
|
||||
<p>The link below gives you access at any time to view the most recent results. Feel free to bookmark this link in your browser.</p>
|
||||
<p>Click the link below to view the study plan:<br>
|
||||
<a href="{$a->link}">{$a->link}</a></p>
|
||||
<p>Kind regards,<br>
|
||||
<p>Kind regards, <br>
|
||||
{$a->sender}</p>
|
||||
';
|
||||
|
||||
|
@ -271,7 +271,6 @@ $string["studyplan_past"] = "Past study plans";
|
|||
$string["studyplan_present"] = "Current study plans";
|
||||
$string["studyplan_future"] = "Upcoming study plans";
|
||||
|
||||
|
||||
$string["link_myreport"] = "My study plan";
|
||||
$string["link_viewplan"] = "Study plans";
|
||||
$string["link_editplan"] = "Manage study plans";
|
||||
|
@ -416,7 +415,6 @@ $string["currentpage"] = "Currently active page:";
|
|||
$string["advanced_bulk_course_timing"] = 'Sync course timing to periods';
|
||||
$string["advanced_bulk_course_timing_desc"] = 'Synchronize the start and end date of all courses in the currently active studyplan page to periods in which they are placed.';
|
||||
|
||||
|
||||
$string["advanced_cascade_cohortsync_title"] = "Cascade cohort sync";
|
||||
$string["advanced_cascade_cohortsync_desc"] = "Add cohort sync enrolment to each course in this study plan for all cohorts linked to this study plan";
|
||||
$string["advanced_cascade_cohortsync"] = "Cascade cohort sync";
|
||||
|
@ -497,7 +495,6 @@ $string["setting_premium_key"] = 'Activation key';
|
|||
$string["settingdesc_premium_key"] = 'Paste the premium key you received in the box above.<br> <b>Attention!</b> The lines <i>----- BEGIN ACTIVATION KEY -----</i> and <i>----- END ACTIVATION KEY -----</i> are part of the key.';
|
||||
$string["setting_premium_debug"] = 'Debug info for premium key';
|
||||
|
||||
|
||||
$string["premiumfeature:morestudyplans"] = 'Creating more than 5 studyplans in a single category is a premium feature.';
|
||||
$string["premiumfeature:morecategories"] = 'Creating studyplans in more than 20 categories is a premium feature.';
|
||||
$string["premiumfeature:warning"] = 'The features on this page are only accessible if your site has premium features enabled.';
|
||||
|
|
|
@ -41,7 +41,6 @@ $string["treestudyplan:selectowngradables"] = 'Docenten kunnen in hun eigen curs
|
|||
$string["treestudyplan:lineunenrol"] = "Beheer inschrijvingen van studenten in leerlijnen";
|
||||
$string["treestudyplan:coach"] = "Beschikbaar als coach";
|
||||
|
||||
|
||||
$string["report"] = 'Voortgangsrapport';
|
||||
$string["report_invited"] = 'Voortgang van {$a}';
|
||||
$string["report_index"] = 'Studieplannen van studenten inzien';
|
||||
|
@ -333,7 +332,6 @@ $string["core_aggregator_desc"] = 'Gebruik de ingesteld cursusvoltooiing';
|
|||
$string["competency_aggregator_title"] = 'Cursuscompetenties';
|
||||
$string["competency_aggregator_desc"] = 'Gebruik de bij de cursus ingestelde competenties';
|
||||
|
||||
|
||||
$string["setting_bistate_heading"] = 'Standaardwaarden voor Behaald + Vereiste leerdoelen ';
|
||||
$string["settingdesc_bistate_heading"] = 'Stel de standaardwaarden in voor deze verzamelmethode';
|
||||
|
||||
|
@ -369,7 +367,6 @@ $string["settingdesc_copystudylinesnewpage"] = 'Bij aanmaken van een nieuw tabbl
|
|||
$string["setting_continueperiodnumberingnewpage"] = 'Perioden doornummeren op nieuw tabblad';
|
||||
$string["settingdesc_continueperiodnumberingnewpage"] = 'Bij aanmaken van een nieuw tabblad, wordt de standaardnaam van perioden doorgenummerd (b.v. P5, P6, P7, P8) in plaats van herstart (P1, P2, P3, P4)';
|
||||
|
||||
|
||||
$string["grade_include"] = 'Doel';
|
||||
$string["grade_require"] = 'Verplicht';
|
||||
$string["required_goal"] = 'Verplicht leerdoel';
|
||||
|
|
40
lib.php
40
lib.php
|
@ -44,7 +44,6 @@ function local_treestudyplan_unit_get_editor_options(context $context) {
|
|||
'trusttext' => 0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create primary navigation links for studyplan if needed
|
||||
*/
|
||||
|
@ -56,7 +55,7 @@ function local_treestudyplan_autofill_customusermenuitems() {
|
|||
"/local/treestudyplan/view-plan.php" => ["included" => false, "strkey" => "link_viewplan"],
|
||||
"/local/treestudyplan/edit-plan.php" => ["included" => false, "strkey" => "link_editplan"],
|
||||
];
|
||||
if ((premium::enabled() && \get_config("local_treestudyplan","enablecoach"))) {
|
||||
if ((premium::enabled() && \get_config("local_treestudyplan", "enablecoach"))) {
|
||||
// Also include the coach role if enabled
|
||||
$navitems["/local/treestudyplan/coach.php"] = ["included" => false, "strkey" => "link_coach"];
|
||||
}
|
||||
|
@ -118,7 +117,7 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) {
|
|||
Studieplannen beheren|/local/treestudyplan/edit-plan.php.
|
||||
|
||||
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).
|
||||
We will add all the hrefs that should be hidden to this variable below.
|
||||
*/
|
||||
|
@ -140,7 +139,7 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) {
|
|||
// Create studyplan node.
|
||||
$node = navigation_node::create(
|
||||
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", []),
|
||||
global_navigation::TYPE_SYSTEM,
|
||||
null,
|
||||
"local_treestudyplan_myreport",
|
||||
|
@ -152,7 +151,7 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) {
|
|||
// Create invitenode node.
|
||||
$invitenode = navigation_node::create(
|
||||
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", []),
|
||||
global_navigation::TYPE_CUSTOM ,
|
||||
null,
|
||||
"local_treestudyplan_invitemgmt",
|
||||
|
@ -169,7 +168,7 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) {
|
|||
|| webservicehelper::has_capability_in_any_category('local/treestudyplan:viewuserreports')) {
|
||||
$node = navigation_node::create(
|
||||
get_string("link_viewplan", "local_treestudyplan"),
|
||||
new moodle_url($CFG->wwwroot . "/local/treestudyplan/view-plan.php", array()),
|
||||
new moodle_url($CFG->wwwroot . "/local/treestudyplan/view-plan.php", []),
|
||||
global_navigation::TYPE_SYSTEM ,
|
||||
null,
|
||||
"local_treestudyplan_viewplan",
|
||||
|
@ -186,7 +185,7 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) {
|
|||
) {
|
||||
$node = navigation_node::create(
|
||||
get_string("link_editplan", "local_treestudyplan"),
|
||||
new moodle_url($CFG->wwwroot . "/local/treestudyplan/edit-plan.php", array()),
|
||||
new moodle_url($CFG->wwwroot . "/local/treestudyplan/edit-plan.php", []),
|
||||
global_navigation::TYPE_SYSTEM ,
|
||||
null,
|
||||
"local_treestudyplan_editplan",
|
||||
|
@ -198,19 +197,19 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) {
|
|||
} else {
|
||||
$hideprimaryhrefs[] = "/local/treestudyplan/edit-plan.php";
|
||||
}
|
||||
|
||||
$coachsql = "SELECT COUNT('id') FROM {local_treestudyplan_coach} as c
|
||||
|
||||
$coachsql = "SELECT COUNT('id') FROM {local_treestudyplan_coach} as c
|
||||
INNER JOIN {local_treestudyplan} AS t ON c.studyplan_id = t.id
|
||||
WHERE c.user_id = :user_id";
|
||||
|
||||
if ( (premium::enabled() && \get_config("local_treestudyplan","enablecoach")) &&
|
||||
if ( (premium::enabled() && \get_config("local_treestudyplan", "enablecoach")) &&
|
||||
(has_capability('local/treestudyplan:coach', context_system::instance())
|
||||
|| webservicehelper::has_capability_in_any_category('local/treestudyplan:coach')
|
||||
) && $DB->count_records_sql($coachsql,["user_id" => $USER->id]) > 0
|
||||
) && $DB->count_records_sql($coachsql, ["user_id" => $USER->id]) > 0
|
||||
) {
|
||||
$node = navigation_node::create(
|
||||
get_string("link_coach", "local_treestudyplan"),
|
||||
new moodle_url($CFG->wwwroot . "/local/treestudyplan/coach.php", array()),
|
||||
new moodle_url($CFG->wwwroot . "/local/treestudyplan/coach.php", []),
|
||||
global_navigation::TYPE_SYSTEM ,
|
||||
null,
|
||||
"local_treestudyplan_coach",
|
||||
|
@ -231,7 +230,7 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) {
|
|||
// Create invitenode node.
|
||||
$invitenode = navigation_node::create(
|
||||
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", []),
|
||||
global_navigation::TYPE_USER ,
|
||||
null,
|
||||
"local_treestudyplan_invitemgmt",
|
||||
|
@ -315,7 +314,7 @@ function local_treestudyplan_reset_fontawesome_icon_map() {
|
|||
*/
|
||||
function local_treestudyplan_send_invite($inviteid) {
|
||||
global $DB, $USER, $CFG;
|
||||
$invite = $DB->get_record("local_treestudyplan_invit", array('id' => $inviteid));
|
||||
$invite = $DB->get_record("local_treestudyplan_invit", ['id' => $inviteid]);
|
||||
|
||||
$noreply = 'noreply@' . get_host_from_url($CFG->wwwroot);
|
||||
$mailer = get_mailer();
|
||||
|
@ -433,20 +432,18 @@ function local_treestudyplan_pluginfile(
|
|||
bool $forcedownload,
|
||||
array $options = []
|
||||
): bool {
|
||||
global $DB,$USER;
|
||||
global $DB, $USER;
|
||||
|
||||
|
||||
$studyplan_filecaps = ["local/treestudyplan:editstudyplan","local/treestudyplan:viewuserreports"];
|
||||
$studyplanfilecaps = ["local/treestudyplan:editstudyplan", "local/treestudyplan:viewuserreports"];
|
||||
|
||||
// Check the contextlevel is as expected - the studyplan plugin only uses system context for storing files.
|
||||
// This avoids headaches when moving studyplans between contexts, while the security impact is minimal...
|
||||
// This avoids headaches when moving studyplans between contexts, while the security impact is minimal...
|
||||
if ($context->contextlevel != CONTEXT_SYSTEM) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Make sure the filearea is one of those used by the plugin.
|
||||
if (in_array($filearea,["studyplan","icon","studyplanpage"])) {
|
||||
if (in_array($filearea, ["studyplan", "icon", "studyplanpage"])) {
|
||||
// The args is an array containing [itemid, path].
|
||||
// Fetch the itemid from the path.
|
||||
$itemid = array_shift($args);
|
||||
|
@ -476,7 +473,7 @@ function local_treestudyplan_pluginfile(
|
|||
return false;
|
||||
}
|
||||
|
||||
} else if (in_array($filearea,['defaulticon'])) {
|
||||
} else if (in_array($filearea, ['defaulticon'])) {
|
||||
// The args is an array containing [itemid, path].
|
||||
// Fetch the itemid from the path.
|
||||
$itemid = array_shift($args);
|
||||
|
@ -506,4 +503,3 @@ function local_treestudyplan_pluginfile(
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
|
14
myreport.php
14
myreport.php
|
@ -29,17 +29,17 @@ use local_treestudyplan\teachingfinder;
|
|||
|
||||
$systemcontext = context_system::instance();
|
||||
|
||||
$PAGE->set_url("/local/treestudyplan/myreport.php", array());
|
||||
$PAGE->set_url("/local/treestudyplan/myreport.php", []);
|
||||
require_login();
|
||||
|
||||
$PAGE->set_pagelayout('base');
|
||||
$PAGE->set_context($systemcontext);
|
||||
|
||||
//$teachermode = has_capability("local/treestudyplan:viewuserreports", $systemcontext);
|
||||
$am_teaching = teachingfinder::is_teaching($USER->id);
|
||||
$have_plans = studyplan::exist_for_user($USER->id);
|
||||
$amteaching = teachingfinder::is_teaching($USER->id);
|
||||
$haveplans = studyplan::exist_for_user($USER->id);
|
||||
|
||||
if ($am_teaching) {
|
||||
if ($amteaching) {
|
||||
$PAGE->set_title(get_string('myreport_teachermode', 'local_treestudyplan'));
|
||||
$PAGE->set_heading(get_string('myreport_teachermode', 'local_treestudyplan'));
|
||||
} else {
|
||||
|
@ -52,7 +52,7 @@ $PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/boot
|
|||
if ($CFG->debugdeveloper) {
|
||||
$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css'));
|
||||
}
|
||||
$PAGE->requires->js_call_amd('local_treestudyplan/page-myreport', 'init', [$am_teaching ? 'teaching' : 'own']);
|
||||
$PAGE->requires->js_call_amd('local_treestudyplan/page-myreport', 'init', [$amteaching ? 'teaching' : 'own']);
|
||||
|
||||
/**
|
||||
* Shortcut function to provide translations
|
||||
|
@ -70,7 +70,7 @@ print $OUTPUT->header();
|
|||
|
||||
print '<div class="m-buttonbar" style="margin-bottom: 1em; text-align: right;">';
|
||||
|
||||
if (get_config("local_treestudyplan","enableplansharing") && !$am_teaching) {
|
||||
if (get_config("local_treestudyplan", "enableplansharing") && !$amteaching) {
|
||||
print '<a class="btn btn-primary" href="invitations.php" id="manage_invites">';
|
||||
print ' <i class="fa fa-share"></i> '.t('manage_invites').'</a>';
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ print " <span class='sr-only'>Loading...</span>";
|
|||
print " </div>";
|
||||
print " </div>";
|
||||
print " <div v-cloak>";
|
||||
if ($am_teaching) {
|
||||
if ($amteaching) {
|
||||
print " <r-report type='teaching' teachermode ></r-report>";
|
||||
} else {
|
||||
print " <r-report type='own' :userid='userid'></r-report>";
|
||||
|
|
|
@ -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/>.
|
||||
/**
|
||||
* Report
|
||||
* Report
|
||||
* @package local_treestudyplan
|
||||
* @copyright 2023 P.M. Kuipers
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
|
@ -45,18 +45,16 @@ $contextname = $ci->pathstr();
|
|||
$firstperiod = optional_param('firstperiod', 0, PARAM_INT); // First period to show
|
||||
$lastperiod = optional_param('lastperiod', 0, PARAM_INT); // Last periode to show
|
||||
|
||||
|
||||
|
||||
$PAGE->set_pagelayout('report');
|
||||
$PAGE->set_title(get_string('studyplan_report', 'local_treestudyplan'));
|
||||
$PAGE->set_heading(get_string('studyplan_report', 'local_treestudyplan'));
|
||||
|
||||
if (!premium::enabled()) {
|
||||
throw new \moodle_exception("error:nopremiumaccess","local_treestudyplan","",premium::statusdescription());
|
||||
throw new \moodle_exception("error:nopremiumaccess", "local_treestudyplan", "", premium::statusdescription());
|
||||
}
|
||||
|
||||
if(!has_capability('local/treestudyplan:viewuserreports', $context)) {
|
||||
throw new \moodle_exception("error:nostudyplanviewaccess","local_treestudyplan","",$contextname);
|
||||
if (!has_capability('local/treestudyplan:viewuserreports', $context)) {
|
||||
throw new \moodle_exception("error:nostudyplanviewaccess", "local_treestudyplan", "", $contextname);
|
||||
}
|
||||
|
||||
// Load javascripts and specific css.
|
||||
|
@ -66,7 +64,6 @@ if ($CFG->debugdeveloper) {
|
|||
}
|
||||
$PAGE->requires->js_call_amd('local_treestudyplan/page-result-overview', 'init', [$studyplan->id(), $page->id(), $firstperiod, $lastperiod]);
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut function to provide translations
|
||||
*
|
||||
|
@ -80,8 +77,8 @@ function t($str, $param = null, $plugin = 'local_treestudyplan') {
|
|||
}
|
||||
|
||||
print $OUTPUT->header();
|
||||
print "<h3><b>{$contextname}</b> / {$studyplan->name()}</h3>";
|
||||
if($studyplan->name() != $page->fullname()) {
|
||||
print "<h3><b>{$contextname}</b> / {$studyplan->name()}</h3>";
|
||||
if ($studyplan->name() != $page->fullname()) {
|
||||
print "<h4>{$page->fullname()}</h4>";
|
||||
}
|
||||
?>
|
||||
|
@ -104,8 +101,8 @@ if($studyplan->name() != $page->fullname()) {
|
|||
<div class="col-sm-6">
|
||||
<select class="custom-select" :value="page.id" @change="selectedPage">
|
||||
<template v-if="studyplan">
|
||||
<option v-for="p in studyplan.pages"
|
||||
:key="p.id"
|
||||
<option v-for="p in studyplan.pages"
|
||||
:key="p.id"
|
||||
:value="p.id"
|
||||
:selected="(page.id == p.id)?true:false"
|
||||
>{{p.fullname}}</option>
|
||||
|
@ -119,8 +116,8 @@ if($studyplan->name() != $page->fullname()) {
|
|||
<div class="col-sm-2">
|
||||
<select class="custom-select" @change="selectedFirstPeriod">
|
||||
<template v-if="page">
|
||||
<option v-for="p in page.perioddesc"
|
||||
:key="p.id"
|
||||
<option v-for="p in page.perioddesc"
|
||||
:key="p.id"
|
||||
:value="p.period"
|
||||
:selected="(structure.firstperiod == p.period)?true:false"
|
||||
>{{p.fullname}}</option>
|
||||
|
@ -133,7 +130,7 @@ if($studyplan->name() != $page->fullname()) {
|
|||
<template v-if="page">
|
||||
<template v-for="p in page.perioddesc">
|
||||
<option v-if="p.period >= structure.firstperiod"
|
||||
:key="p.id"
|
||||
:key="p.id"
|
||||
:value="p.period"
|
||||
:selected="(structure.lastperiod == p.period)?true:false"
|
||||
>{{p.fullname}}</option>
|
||||
|
|
50
settings.php
50
settings.php
|
@ -6,7 +6,7 @@
|
|||
// 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,.
|
||||
// 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.
|
||||
|
@ -56,12 +56,12 @@ if ($hassiteconfig) {
|
|||
));
|
||||
|
||||
// Default image for study plans
|
||||
$page->add(new admin_setting_configstoredfile('local_treestudyplan/defaulticon',
|
||||
get_string('setting_defaulticon', 'local_treestudyplan'),
|
||||
$page->add(new admin_setting_configstoredfile('local_treestudyplan/defaulticon',
|
||||
get_string('setting_defaulticon', 'local_treestudyplan'),
|
||||
get_string('settingdesc_defaulticon', 'local_treestudyplan'),
|
||||
'defaulticon', 0,
|
||||
[
|
||||
'maxfiles' => 1,
|
||||
'maxfiles' => 1,
|
||||
'accepted_types' => ['.jpg', '.png']]
|
||||
));
|
||||
|
||||
|
@ -89,7 +89,7 @@ if ($hassiteconfig) {
|
|||
get_string('settingdesc_display_heading', 'local_treestudyplan')
|
||||
));
|
||||
|
||||
$displayfields = ["shortname" => get_string("shortname"), "idnumber" => get_string("idnumber"), "fullname" => get_string("fullname"), ];
|
||||
$displayfields = ["shortname" => get_string("shortname"), "idnumber" => get_string("idnumber"), "fullname" => get_string("fullname") ];
|
||||
$infofields = ["" => get_string('none'), "description" => get_string("description"), "contacts" => get_string("teachers"), "idnumber" => get_string("idnumber")];
|
||||
$handler = \core_customfield\handler::get_handler('core_course', 'course');
|
||||
|
||||
|
@ -106,49 +106,49 @@ if ($hassiteconfig) {
|
|||
}
|
||||
}
|
||||
}
|
||||
//get_config("local_treestudyplan","enableplansharing")
|
||||
//get_config("local_treestudyplan", "enableplansharing")
|
||||
$page->add(new admin_setting_configcheckbox('local_treestudyplan/enableplansharing',
|
||||
get_string('setting_enableplansharing', 'local_treestudyplan'),
|
||||
get_string('settingdesc_enableplansharing', 'local_treestudyplan'),
|
||||
true,
|
||||
));
|
||||
|
||||
//get_config("local_treestudyplan","timelessperiods")
|
||||
//get_config("local_treestudyplan", "timelessperiods")
|
||||
$page->add(new admin_setting_configcheckbox('local_treestudyplan/timelessperiods',
|
||||
get_string('setting_timelessperiods', 'local_treestudyplan'),
|
||||
get_string('settingdesc_timelessperiods', 'local_treestudyplan'),
|
||||
false,
|
||||
));
|
||||
|
||||
//get_config("local_treestudyplan","limitcourselist")
|
||||
//get_config("local_treestudyplan", "limitcourselist")
|
||||
$page->add(new admin_setting_configcheckbox('local_treestudyplan/limitcourselist',
|
||||
get_string('setting_limitcourselist', 'local_treestudyplan'),
|
||||
get_string('settingdesc_limitcourselist', 'local_treestudyplan'),
|
||||
false,
|
||||
));
|
||||
|
||||
//get_config("local_treestudyplan","hivizdropslots")
|
||||
//get_config("local_treestudyplan", "hivizdropslots")
|
||||
$page->add(new admin_setting_configcheckbox('local_treestudyplan/hivizdropslots',
|
||||
get_string('setting_hivizdropslots', 'local_treestudyplan'),
|
||||
get_string('settingdesc_hivizdropslots', 'local_treestudyplan'),
|
||||
false,
|
||||
));
|
||||
|
||||
//get_config("local_treestudyplan","toolboxleft")
|
||||
//get_config("local_treestudyplan", "toolboxleft")
|
||||
$page->add(new admin_setting_configcheckbox('local_treestudyplan/toolboxleft',
|
||||
get_string('setting_toolboxleft', 'local_treestudyplan'),
|
||||
get_string('settingdesc_toolboxleft', 'local_treestudyplan'),
|
||||
true,
|
||||
));
|
||||
|
||||
//get_config("local_treestudyplan","copystudylinesnewpage")
|
||||
|
||||
//get_config("local_treestudyplan", "copystudylinesnewpage")
|
||||
$page->add(new admin_setting_configcheckbox('local_treestudyplan/copystudylinesnewpage',
|
||||
get_string('setting_copystudylinesnewpage', 'local_treestudyplan'),
|
||||
get_string('settingdesc_copystudylinesnewpage', 'local_treestudyplan'),
|
||||
false,
|
||||
));
|
||||
|
||||
//get_config("local_treestudyplan","continueperiodnumberingnewpage")
|
||||
//get_config("local_treestudyplan", "continueperiodnumberingnewpage")
|
||||
$page->add(new admin_setting_configcheckbox('local_treestudyplan/continueperiodnumberingnewpage',
|
||||
get_string('setting_continueperiodnumberingnewpage', 'local_treestudyplan'),
|
||||
get_string('settingdesc_continueperiodnumberingnewpage', 'local_treestudyplan'),
|
||||
|
@ -156,7 +156,7 @@ if ($hassiteconfig) {
|
|||
));
|
||||
|
||||
if (premium::enabled()) {
|
||||
//get_config("local_treestudyplan","enablecoach")
|
||||
//get_config("local_treestudyplan", "enablecoach")
|
||||
$page->add(new admin_setting_configcheckbox('local_treestudyplan/enablecoach',
|
||||
get_string('setting_enablecoach', 'local_treestudyplan'),
|
||||
get_string('settingdesc_enablecoach', 'local_treestudyplan'),
|
||||
|
@ -182,8 +182,8 @@ if ($hassiteconfig) {
|
|||
get_string('settingdesc_infofields_heading', 'local_treestudyplan')
|
||||
));
|
||||
|
||||
$positions = [ "above" => get_string('infofield_position_above', 'local_treestudyplan'),
|
||||
"below" => get_string("infofield_position_below", 'local_treestudyplan'),
|
||||
$positions = [ "above" => get_string('infofield_position_above', 'local_treestudyplan'),
|
||||
"below" => get_string("infofield_position_below", 'local_treestudyplan'),
|
||||
];
|
||||
|
||||
for ($i=1;$i<=5;$i++) {
|
||||
|
@ -211,19 +211,19 @@ if ($hassiteconfig) {
|
|||
get_string('setting_competency_displayname', 'local_treestudyplan'),
|
||||
get_string('settingdesc_competency_displayname', 'local_treestudyplan'),
|
||||
"idnumber",
|
||||
["shortname" => get_string("name","core",),
|
||||
"idnumber" => get_string("idnumber","core",),
|
||||
"description" => get_string("description","core",)]
|
||||
["shortname" => get_string("name", "core", ),
|
||||
"idnumber" => get_string("idnumber", "core", ),
|
||||
"description" => get_string("description", "core", )]
|
||||
));
|
||||
|
||||
|
||||
$page->add(new admin_setting_configselect('local_treestudyplan/competency_detailfield',
|
||||
get_string('setting_competency_detailfield', 'local_treestudyplan'),
|
||||
get_string('settingdesc_competency_detailfield', 'local_treestudyplan'),
|
||||
"shortname",
|
||||
["" => get_string("none","core",),
|
||||
"shortname" => get_string("name","core",),
|
||||
"idnumber" => get_string("idnumber","core",),
|
||||
"description" => get_string("description","core",)]
|
||||
["" => get_string("none", "core", ),
|
||||
"shortname" => get_string("name", "core", ),
|
||||
"idnumber" => get_string("idnumber", "core", ),
|
||||
"description" => get_string("description", "core", )]
|
||||
));
|
||||
|
||||
$page->add(new admin_setting_heading('local_treestudyplan/competency_aggregation_heading',
|
||||
|
@ -381,7 +381,6 @@ if ($hassiteconfig) {
|
|||
get_string('cfg_help', 'local_treestudyplan', null, true),
|
||||
$CFG->wwwroot . '/local/treestudyplan/doc.php/index.htm'));
|
||||
|
||||
|
||||
/**************************************
|
||||
*
|
||||
* Settings page: Premium registration
|
||||
|
@ -418,7 +417,6 @@ if ($hassiteconfig) {
|
|||
));
|
||||
}
|
||||
|
||||
|
||||
// Add settings page2 to the admin settings category.
|
||||
$ADMIN->add('local_treestudyplan', $pagepremium);
|
||||
}
|
||||
|
|
36
test.php
36
test.php
|
@ -1,11 +1,11 @@
|
|||
<?php
|
||||
function sitematch($key,$site){
|
||||
function sitematch($key, $site) {
|
||||
// Add double slashes to key and site if no scheme is set.
|
||||
// Basically: if no double slashes present before any dots,shashes or @s.
|
||||
if(!\preg_match_all('#^[^./@]*?//#',$key )) {
|
||||
// Basically: if no double slashes present before any dots, shashes or @s.
|
||||
if (!\preg_match_all('#^[^./@]*?//#', $key )) {
|
||||
$key = "//".$key;
|
||||
}
|
||||
if(!\preg_match_all('#^[^./@]*?//#',$site)) {
|
||||
if (!\preg_match_all('#^[^./@]*?//#', $site)) {
|
||||
$site = "//".$site;
|
||||
}
|
||||
// Use parse_url() to split path and host.
|
||||
|
@ -23,17 +23,17 @@ function sitematch($key,$site){
|
|||
}
|
||||
|
||||
// First match the host part.
|
||||
$keyparts = \array_reverse(\explode(".",$keyurl->host));
|
||||
$siteparts = \array_reverse(\explode(".",$siteurl->host));
|
||||
$keyparts = \array_reverse(\explode(".", $keyurl->host));
|
||||
$siteparts = \array_reverse(\explode(".", $siteurl->host));
|
||||
|
||||
// Trim starting www from both parts, since site.domain and www.site.domain should be treated as the same.
|
||||
if (($x = \array_pop($keyparts)) != "www") {\array_push($keyparts,$x);}
|
||||
if (($x = \array_pop($siteparts)) != "www") {\array_push($siteparts,$x);}
|
||||
if (($x = \array_pop($keyparts)) != "www") {\array_push($keyparts, $x);}
|
||||
if (($x = \array_pop($siteparts)) != "www") {\array_push($siteparts, $x);}
|
||||
|
||||
for ($i = 0; $i < count($keyparts); $i++) {
|
||||
// No match if the site does not have a part, but the key does. Unless the key part is *
|
||||
if (!isset($siteparts[$i]) ) {
|
||||
if($keyparts[$i] != "*") {
|
||||
if ($keyparts[$i] != "*") {
|
||||
return false;
|
||||
} else {
|
||||
$i++; //increment $i by one before break, to make sure the comparison following this loop holds.
|
||||
|
@ -43,7 +43,7 @@ function sitematch($key,$site){
|
|||
|
||||
// Now do a proper case insensitive check for matching.
|
||||
// Uses fnmatch to easily handle shell type wildcards.
|
||||
if ( ! \fnmatch($keyparts[$i],$siteparts[$i],\FNM_CASEFOLD)) {
|
||||
if ( ! \fnmatch($keyparts[$i], $siteparts[$i], \FNM_CASEFOLD)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -54,19 +54,19 @@ function sitematch($key,$site){
|
|||
|
||||
// If we made it here then the host part matches. Now check the path.
|
||||
// If path is /*, matches all subpaths including /
|
||||
$keypath = empty($keyurl->path)?"/":$keyurl->path;
|
||||
$sitepath = empty($siteurl->path)?"/":$siteurl->path;
|
||||
|
||||
$keypath = empty($keyurl->path) ? "/" : $keyurl->path;
|
||||
$sitepath = empty($siteurl->path) ? "/" : $siteurl->path;
|
||||
|
||||
// Trim trailing / from both paths before comparison
|
||||
if (\strlen($sitepath) > 1) {
|
||||
$sitepath = \rtrim($sitepath,"/");
|
||||
$sitepath = \rtrim($sitepath, "/");
|
||||
}
|
||||
if (\strlen($keypath) > 1) {
|
||||
$keypath = \rtrim($keypath,"/");
|
||||
$keypath = \rtrim($keypath, "/");
|
||||
}
|
||||
|
||||
// Do a case insensitive fnmatch on the site so wildcards are matched too.
|
||||
return \fnmatch($keypath,$sitepath,\FNM_CASEFOLD);
|
||||
return \fnmatch($keypath, $sitepath, \FNM_CASEFOLD);
|
||||
}
|
||||
|
||||
$tests = [
|
||||
|
@ -74,10 +74,10 @@ $tests = [
|
|||
["*/*", "https://www.miqra.nl"],
|
||||
["*", "https://clients.openedu.nl/fith"],
|
||||
["clients.openedu.nl/fith", "https://clients.openedu.nl/fith/"],
|
||||
["clients.openedu.nl/fith/", "https://clients.openedu.nl/fith"]
|
||||
["clients.openedu.nl/fith/", "https://clients.openedu.nl/fith"],
|
||||
];
|
||||
|
||||
foreach($tests as $test) {
|
||||
[$key, $site] = $test;
|
||||
print("Checking key '{$key}' on site '{$site}': " . (sitematch($key,$site)?"MATCH":"FAIL") . "\n");
|
||||
print("Checking key '{$key}' on site '{$site}': " . (sitematch($key, $site)?"MATCH":"FAIL") . "\n");
|
||||
}
|
|
@ -29,7 +29,7 @@ require_once($CFG->libdir.'/weblib.php');
|
|||
|
||||
$systemcontext = context_system::instance();
|
||||
|
||||
$PAGE->set_url("/local/treestudyplan/view-plan.php", array());
|
||||
$PAGE->set_url("/local/treestudyplan/view-plan.php", []);
|
||||
require_login();
|
||||
|
||||
// Figure out the context (category or system, based on either category or context parameter).
|
||||
|
@ -64,9 +64,6 @@ if ($categoryid > 0) {
|
|||
$ci = new contextinfo($studyplancontext);
|
||||
$contextname = $ci->pathstr();
|
||||
|
||||
|
||||
|
||||
|
||||
$PAGE->set_pagelayout('base');
|
||||
//$PAGE->set_context($studyplancontext);
|
||||
$PAGE->set_title(get_string('view_plan', 'local_treestudyplan')." - ".$contextname);
|
||||
|
@ -77,18 +74,18 @@ if ($studyplancontext->id > 1) {
|
|||
$PAGE->navbar->add(get_string('view_plan', 'local_treestudyplan'));
|
||||
|
||||
// Coursecat context
|
||||
$cat = \core_course_category::get($studyplancontext->instanceid,IGNORE_MISSING,true); // We checck visibility later
|
||||
} else {
|
||||
$cat = \core_course_category::get($studyplancontext->instanceid, IGNORE_MISSING, true); // We checck visibility later
|
||||
} else {
|
||||
// System context
|
||||
$cat = \core_course_category::top();
|
||||
}
|
||||
|
||||
if (!$cat->is_uservisible()) {
|
||||
throw new \moodle_exception("error:cannotviewcategory","local_treestudyplan","/local/treestudyplan/view_plan.php",$contextname);
|
||||
throw new \moodle_exception("error:cannotviewcategory", "local_treestudyplan", "/local/treestudyplan/view_plan.php", $contextname);
|
||||
}
|
||||
|
||||
if(!has_capability('local/treestudyplan:viewuserreports', $studyplancontext)) {
|
||||
throw new \moodle_exception("error:nostudyplanviewaccess","local_treestudyplan","/local/treestudyplan/view_plan.php",$contextname);
|
||||
if (!has_capability('local/treestudyplan:viewuserreports', $studyplancontext)) {
|
||||
throw new \moodle_exception("error:nostudyplanviewaccess", "local_treestudyplan", "/local/treestudyplan/view_plan.php", $contextname);
|
||||
}
|
||||
|
||||
// Load javascripts and specific css.
|
||||
|
@ -121,16 +118,16 @@ print $OUTPUT->header();
|
|||
<div v-cloak>
|
||||
<div v-if='!activestudyplan && usedcontexts' class='ml-3 mb-3 s-context-selector'>
|
||||
<b-form-select text='<?php print($contextname);?>' :value="contextid" @change='switchContext'
|
||||
:class="(!(usedcontexts.length))?'text-primary':''">
|
||||
:class="(!(usedcontexts.length)) ? 'text-primary' : ''">
|
||||
<b-form-select-option v-if='!(usedcontexts.length)' :value="contextid"
|
||||
:class="'text-primary'">
|
||||
<span><?php t("loading",null,"core"); ?>...</span></b-form-select-option>
|
||||
<b-form-select-option v-for='ctx in usedcontexts' :key='ctx.id' :value="ctx.context_id"
|
||||
<span><?php t("loading", null, "core"); ?>...</span></b-form-select-option>
|
||||
<b-form-select-option v-for='ctx in usedcontexts' :key='ctx.id' :value="ctx.context_id"
|
||||
:class="(ctx.studyplancount > 0) ? 'font-weight-bold' : ''"
|
||||
><span v-for="(p, i) in ctx.category.path"><span v-if="i>0"> / </span>{{ p }}</span>
|
||||
<span>({{ ctx.studyplancount }})</span></b-form-select-option>
|
||||
</b-form-select>
|
||||
<div v-if="!(usedcontexts.length)" style="position: relative; top: 0.3rem; width: 1.2rem; height: 1.2rem; font-size: 0.7rem;"
|
||||
<div v-if="!(usedcontexts.length)" style="position: relative; top: 0.3rem; width: 1.2rem; height: 1.2rem; font-size: 0.7rem;"
|
||||
class="spinner-border text-primary" role="status"></div>
|
||||
</div>
|
||||
<h3 v-else><?php print $contextname; ?></h3>
|
||||
|
@ -147,11 +144,11 @@ print $OUTPUT->header();
|
|||
:value='studyplan.id'
|
||||
>{{ studyplan.name }}</b-form-select-option>
|
||||
</b-form-select>
|
||||
<s-studyplan-details
|
||||
v-model="displayedstudyplan"
|
||||
<s-studyplan-details
|
||||
v-model="displayedstudyplan"
|
||||
v-if="displayedstudyplan.description"
|
||||
></s-studyplan-details>
|
||||
<div class="flex-grow-1"><!-- Spacer to align student selector right --></div>
|
||||
<div class="flex-grow-1"><!-- Spacer to align student selector right --></div>
|
||||
<div>
|
||||
<span><?php t('selectstudent_btn') ?></span>
|
||||
<s-prevnext-selector
|
||||
|
|
Loading…
Reference in New Issue
Block a user