Moodle code style fixes part 3
This commit is contained in:
		
							parent
							
								
									acf3409890
								
							
						
					
					
						commit
						a531ce80d7
					
				
					 38 changed files with 445 additions and 469 deletions
				
			
		|  | @ -36,13 +36,13 @@ const GRADECFG_TABLE = "local_treestudyplan_gradecfg"; | ||||||
| 
 | 
 | ||||||
| $scales = \grade_scale::fetch_all_global(); | $scales = \grade_scale::fetch_all_global(); | ||||||
| $mappings = $DB->get_records(GRADECFG_TABLE); | $mappings = $DB->get_records(GRADECFG_TABLE); | ||||||
| $scale_cfgs = []; | $scalecfgs = []; | ||||||
| $grade_cfgs = []; | $gradecfgs = []; | ||||||
| foreach ($mappings as $cfg) { | foreach ($mappings as $cfg) { | ||||||
|     if (!empty($cfg->scale_id)) { |     if (!empty($cfg->scale_id)) { | ||||||
|         $scale_cfgs[$cfg->scale_id] = $cfg; |         $scalecfgs[$cfg->scale_id] = $cfg; | ||||||
|     } else if (!empty($cfg->grade_points)) { |     } else if (!empty($cfg->grade_points)) { | ||||||
|         $grade_cfgs[$cfg->grade_points] = $cfg; |         $gradecfgs[$cfg->grade_points] = $cfg; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -51,8 +51,8 @@ print $OUTPUT->header(); | ||||||
| if ($_POST["action"] == "update") { | if ($_POST["action"] == "update") { | ||||||
|     // First loop through the scales to see which need to be updated.
 |     // First loop through the scales to see which need to be updated.
 | ||||||
|     foreach ($scales as $scale) { |     foreach ($scales as $scale) { | ||||||
|         if (array_key_exists($scale->id, $scale_cfgs)) { |         if (array_key_exists($scale->id, $scalecfgs)) { | ||||||
|             $scalecfg = $scale_cfgs[$scale->id]; |             $scalecfg = $scalecfgs[$scale->id]; | ||||||
| 
 | 
 | ||||||
|             $needupdate = false; |             $needupdate = false; | ||||||
|             foreach (["min_progress", "min_completed"] as $handle) { |             foreach (["min_progress", "min_completed"] as $handle) { | ||||||
|  | @ -84,19 +84,18 @@ if ($_POST["action"] == "update") { | ||||||
|                 // Insert into database and add to the list of scale configs.
 |                 // Insert into database and add to the list of scale configs.
 | ||||||
|                 $id = $DB->insert_record(GRADECFG_TABLE, $scalecfg); |                 $id = $DB->insert_record(GRADECFG_TABLE, $scalecfg); | ||||||
|                 $scalecfg = $DB->get_record(GRADECFG_TABLE, ['id' => $id]); |                 $scalecfg = $DB->get_record(GRADECFG_TABLE, ['id' => $id]); | ||||||
|                 $scale_cfgs[$id] = $scalecfg; |                 $scalecfgs[$id] = $scalecfg; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     // Now, loop through the gradepoints to parse .
 |     // Now, loop through the gradepoints to parse .
 | ||||||
|     $deletelist = []; |     $deletelist = []; | ||||||
|     foreach ($grade_cfgs as $gradecfg) { |     foreach ($gradecfgs as $gradecfg) { | ||||||
|         $deletekey = "g_{$gradecfg->grade_points}_delete"; |         $deletekey = "g_{$gradecfg->grade_points}_delete"; | ||||||
|         if (array_key_exists($deletekey, $_POST) && boolval($_POST[$deletekey]) === true) { |         if (array_key_exists($deletekey, $_POST) && boolval($_POST[$deletekey]) === true) { | ||||||
|             $DB->delete_records(GRADECFG_TABLE, ["id" => $gradecfg->id]); |             $DB->delete_records(GRADECFG_TABLE, ["id" => $gradecfg->id]); | ||||||
|             $deletelist[] = $gradecfg; |             $deletelist[] = $gradecfg; | ||||||
|         } else |         } else { | ||||||
|         { |  | ||||||
|             foreach (["min_progress", "min_completed"] as $handle) { |             foreach (["min_progress", "min_completed"] as $handle) { | ||||||
|                 $key = "g_{$gradecfg->grade_points}_{$handle}"; |                 $key = "g_{$gradecfg->grade_points}_{$handle}"; | ||||||
|                 if (array_key_exists($key, $_POST) && is_numeric($_POST[$key])) { |                 if (array_key_exists($key, $_POST) && is_numeric($_POST[$key])) { | ||||||
|  | @ -105,19 +104,21 @@ if ($_POST["action"] == "update") { | ||||||
|             } |             } | ||||||
|             $DB->update_record(GRADECFG_TABLE, $gradecfg); |             $DB->update_record(GRADECFG_TABLE, $gradecfg); | ||||||
|             // reload to ensure proper rounding is done.
 |             // reload to ensure proper rounding is done.
 | ||||||
|             $grade_cfgs[$gradecfg->grade_points] = $DB->get_record(GRADECFG_TABLE, ['id' => $gradecfg->id]); |             $gradecfgs[$gradecfg->grade_points] = $DB->get_record(GRADECFG_TABLE, ['id' => $gradecfg->id]); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     foreach ($deletelist as $gradeconfig) { |     foreach ($deletelist as $gradeconfig) { | ||||||
|         unset($grade_cfgs[$gradecfg->grade_points]); |         unset($gradecfgs[$gradecfg->grade_points]); | ||||||
|     } |     } | ||||||
|     unset($deletelist); |     unset($deletelist); | ||||||
| 
 | 
 | ||||||
|     // And add an optionally existing new gradepoint setting.
 |     // And add an optionally existing new gradepoint setting.
 | ||||||
|     if (array_key_exists("g_new_gradepoints", $_POST) && !empty($_POST["g_new_gradepoints"])  && is_numeric($_POST["g_new_gradepoints"]) ) { |     if (array_key_exists("g_new_gradepoints", $_POST)  | ||||||
|  |         && !empty($_POST["g_new_gradepoints"])   | ||||||
|  |         && is_numeric($_POST["g_new_gradepoints"]) ) { | ||||||
|         $gp = intval($_POST["g_new_gradepoints"]); |         $gp = intval($_POST["g_new_gradepoints"]); | ||||||
|         if (!array_key_exists($gp, $grade_cfgs)) { |         if (!array_key_exists($gp, $gradecfgs)) { | ||||||
|             $gradecfg = (object)[ "grade_points" => $gp]; |             $gradecfg = (object)[ "grade_points" => $gp]; | ||||||
|             $requireinsert = false; |             $requireinsert = false; | ||||||
|             foreach (["min_progress", "min_completed"] as $handle) { |             foreach (["min_progress", "min_completed"] as $handle) { | ||||||
|  | @ -132,7 +133,7 @@ if ($_POST["action"] == "update") { | ||||||
|                 $id = $DB->insert_record(GRADECFG_TABLE, $gradecfg); |                 $id = $DB->insert_record(GRADECFG_TABLE, $gradecfg); | ||||||
|                 // reload to ensure proper rounding is done.
 |                 // reload to ensure proper rounding is done.
 | ||||||
|                 $gradecfg = $DB->get_record(GRADECFG_TABLE, ['id' => $id]); |                 $gradecfg = $DB->get_record(GRADECFG_TABLE, ['id' => $id]); | ||||||
|                 $grade_cfgs[$id] = $gradecfg; |                 $gradecfgs[$id] = $gradecfg; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -146,45 +147,45 @@ $data = []; | ||||||
| foreach ($scales as $scale) { | foreach ($scales as $scale) { | ||||||
|     $scale->load_items(); |     $scale->load_items(); | ||||||
|     $scalecfg = null; |     $scalecfg = null; | ||||||
|     if (array_key_exists($scale->id, $scale_cfgs)) { |     if (array_key_exists($scale->id, $scalecfgs)) { | ||||||
|         $scalecfg = $scale_cfgs[$scale->id]; |         $scalecfg = $scalecfgs[$scale->id]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     $attrs_c = ['value' => '', 'disabled' => 'disabled', ]; |     $attrsc = ['value' => '', 'disabled' => 'disabled', ]; | ||||||
|     $attrs_p = ['value' => '', 'disabled' => 'disabled', ]; |     $attrsp = ['value' => '', 'disabled' => 'disabled', ]; | ||||||
| 
 | 
 | ||||||
|     if (!isset($scalecfg) || $scalecfg->min_completed == "") { |     if (!isset($scalecfg) || $scalecfg->min_completed == "") { | ||||||
|         $attrs_c["selected"] = "selected"; |         $attrsc["selected"] = "selected"; | ||||||
|     } |     } | ||||||
|     if (!isset($scalecfg) || $scalecfg->min_progress == "") { |     if (!isset($scalecfg) || $scalecfg->min_progress == "") { | ||||||
|         $attrs_p["selected"] = "selected"; |         $attrsp["selected"] = "selected"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     $options_completed = html_writer::tag("option", get_string('select_scaleitem', 'local_treestudyplan'), $attrs_c); |     $optionscompleted = html_writer::tag("option", get_string('select_scaleitem', 'local_treestudyplan'), $attrsc); | ||||||
|     $options_progress = html_writer::tag("option", get_string('select_scaleitem', 'local_treestudyplan'), $attrs_p); |     $optionsprogress = html_writer::tag("option", get_string('select_scaleitem', 'local_treestudyplan'), $attrsp); | ||||||
|     $key = 1; // Start counting by one, as used in sum aggregations.
 |     $key = 1; // Start counting by one, as used in sum aggregations.
 | ||||||
| 
 | 
 | ||||||
|     foreach ($scale->scale_items as $value) { |     foreach ($scale->scale_items as $value) { | ||||||
|         $attrs_c = ["value" => $key]; |         $attrsc = ["value" => $key]; | ||||||
|         $attrs_p = ["value" => $key]; |         $attrsp = ["value" => $key]; | ||||||
| 
 | 
 | ||||||
|         if (isset($scalecfg)) { |         if (isset($scalecfg)) { | ||||||
|             if (intval($scalecfg->min_completed) == $key) { |             if (intval($scalecfg->min_completed) == $key) { | ||||||
|                 $attrs_c["selected"] = "selected"; |                 $attrsc["selected"] = "selected"; | ||||||
|             } |             } | ||||||
|             if (intval($scalecfg->min_progress) == $key) { |             if (intval($scalecfg->min_progress) == $key) { | ||||||
|                 $attrs_p["selected"] = "selected"; |                 $attrsp["selected"] = "selected"; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         $options_progress .= html_writer::tag("option", $value, $attrs_p); |         $optionsprogress .= html_writer::tag("option", $value, $attrsp); | ||||||
|         $options_completed .= html_writer::tag("option", $value, $attrs_c); |         $optionscompleted .= html_writer::tag("option", $value, $attrsc); | ||||||
|         $key++; |         $key++; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	$row = []; | 	$row = []; | ||||||
| 	$row[] = $scale->name; | 	$row[] = $scale->name; | ||||||
| 	//$row[] = html_writer::tag("select", $options_progress, ['name' => "s_{$scale->id}_min_progress", 'autocomplete' => 'off']) ;.
 | 	//$row[] = html_writer::tag("select", $optionsprogress, ['name' => "s_{$scale->id}_min_progress", 'autocomplete' => 'off']) ;.
 | ||||||
| 	$row[] = html_writer::tag("select", $options_completed, ['name' => "s_{$scale->id}_min_completed", 'autocomplete' => 'off']) ; | 	$row[] = html_writer::tag("select", $optionscompleted, ['name' => "s_{$scale->id}_min_completed", 'autocomplete' => 'off']) ; | ||||||
| 	$data[] = $row; | 	$data[] = $row; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -209,7 +210,7 @@ print $OUTPUT->heading(get_string('cfg_grades_scales', 'local_treestudyplan')); | ||||||
| print html_writer::tag('div', html_writer::table($table), ['class'=>'flexible-wrap']); | print html_writer::tag('div', html_writer::table($table), ['class'=>'flexible-wrap']); | ||||||
| 
 | 
 | ||||||
| $data = []; | $data = []; | ||||||
| foreach ($grade_cfgs as $g) { | foreach ($gradecfgs as $g) { | ||||||
|     $row = []; |     $row = []; | ||||||
| 	$row[] = $g->grade_points; | 	$row[] = $g->grade_points; | ||||||
| //    $row[] = html_writer::tag("input", null, ['name' => "g_{$g->grade_points}_min_progress", 'value' => "{$g->min_progress}", 'type' => 'text', "class" => "float", 'autocomplete' => 'off']) ;.
 | //    $row[] = html_writer::tag("input", null, ['name' => "g_{$g->grade_points}_min_progress", 'value' => "{$g->min_progress}", 'type' => 'text', "class" => "float", 'autocomplete' => 'off']) ;.
 | ||||||
|  |  | ||||||
|  | @ -26,13 +26,13 @@ require_once($CFG->libdir.'/externallib.php'); | ||||||
| 
 | 
 | ||||||
| abstract class aggregator { | abstract class aggregator { | ||||||
|     private const FALLBACK = "bistate"; |     private const FALLBACK = "bistate"; | ||||||
|     private static $mod_supported = []; |     private static $modsupported = []; | ||||||
| 
 | 
 | ||||||
|     public static function supported($mod) { |     public static function supported($mod) { | ||||||
|         if (!array_key_exists($mod, self::$mod_supported)) { |         if (!array_key_exists($mod, self::$modsupported)) { | ||||||
|             self::$mod_supported[$mod] = class_exists(self::aggregator_name($mod)); |             self::$modsupported[$mod] = class_exists(self::aggregator_name($mod)); | ||||||
|         } |         } | ||||||
|         return self::$mod_supported[$mod]; |         return self::$modsupported[$mod]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private static function aggregator_name($mod) { |     private static function aggregator_name($mod) { | ||||||
|  | @ -51,8 +51,8 @@ abstract class aggregator { | ||||||
| 
 | 
 | ||||||
|     public static function create($mod, $configstr) { |     public static function create($mod, $configstr) { | ||||||
|         if (self::supported($mod)) { |         if (self::supported($mod)) { | ||||||
|             $ag_class = self::aggregator_name($mod); |             $agclass = self::aggregator_name($mod); | ||||||
|             return new $ag_class($configstr); |             return new $agclass($configstr); | ||||||
|         } else { |         } else { | ||||||
|             throw new \InvalidArgumentException("Cannot find aggregator '{$mod}'"); |             throw new \InvalidArgumentException("Cannot find aggregator '{$mod}'"); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -112,12 +112,12 @@ class associationservice extends \external_api | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	// Actual functions.
 | 	// Actual functions.
 | ||||||
| 	public static function list_cohort($like='', $exclude_id=null, $context_id=1) | 	public static function list_cohort($like='', $excludeid=null, $contextid=1) | ||||||
| 	{ | 	{ | ||||||
|         global $CFG, $DB; |         global $CFG, $DB; | ||||||
| 
 | 
 | ||||||
|         // Only allow this if the user has the right to edit in this context.
 |         // Only allow this if the user has the right to edit in this context.
 | ||||||
|         $context = webservicehelper::find_context($context_id); |         $context = webservicehelper::find_context($contextid); | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, $context); |         webservicehelper::require_capabilities(self::CAP_EDIT, $context); | ||||||
| 
 | 
 | ||||||
|         $pattern = "%{$like}%"; |         $pattern = "%{$like}%"; | ||||||
|  | @ -126,14 +126,14 @@ class associationservice extends \external_api | ||||||
| 
 | 
 | ||||||
|         $sql =  "SELECT c.* from {cohort} c LEFT JOIN {local_treestudyplan_cohort} j ON c.id = j.cohort_id"; |         $sql =  "SELECT c.* from {cohort} c LEFT JOIN {local_treestudyplan_cohort} j ON c.id = j.cohort_id"; | ||||||
|         $sql .= " WHERE c.visible = 1 AND(name LIKE :pattern_nm OR idnumber LIKE :pattern_id)"; |         $sql .= " WHERE c.visible = 1 AND(name LIKE :pattern_nm OR idnumber LIKE :pattern_id)"; | ||||||
|         if (isset($exclude_id) && is_numeric($exclude_id)) { |         if (isset($excludeid) && is_numeric($excludeid)) { | ||||||
|             $sql .= " AND  (j.studyplan_id IS NULL OR j.studyplan_id != :exclude_id)"; |             $sql .= " AND  (j.studyplan_id IS NULL OR j.studyplan_id != :exclude_id)"; | ||||||
|             $params['exclude_id'] = $exclude_id; |             $params['exclude_id'] = $excludeid; | ||||||
|         } |         } | ||||||
|         if ($context_id > 1) { // system context returns all cohorts, including system cohorts.
 |         if ($contextid > 1) { // system context returns all cohorts, including system cohorts.
 | ||||||
|             // otherwise, .
 |             // otherwise, .
 | ||||||
|             $sql .= " AND contextid = :context_id"; |             $sql .= " AND contextid = :context_id"; | ||||||
|             $params['context_id'] = $context_id; |             $params['context_id'] = $contextid; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         $cohorts = []; |         $cohorts = []; | ||||||
|  | @ -160,12 +160,12 @@ class associationservice extends \external_api | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	// Actual functions.
 | 	// Actual functions.
 | ||||||
| 	public static function find_user($like, $exclude_id=null, $context_id=1) | 	public static function find_user($like, $excludeid=null, $contextid=1) | ||||||
| 	{ | 	{ | ||||||
| 		global $CFG, $DB; | 		global $CFG, $DB; | ||||||
| 
 | 
 | ||||||
|         // Only allow this if the user has the right to edit in this context (using system rights would make things more confusing).
 |         // Only allow this if the user has the right to edit in this context (using system rights would make things more confusing).
 | ||||||
|         $context = webservicehelper::find_context($context_id); |         $context = webservicehelper::find_context($contextid); | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, $context); |         webservicehelper::require_capabilities(self::CAP_EDIT, $context); | ||||||
| 
 | 
 | ||||||
|         $pattern = "%{$like}%"; |         $pattern = "%{$like}%"; | ||||||
|  | @ -175,9 +175,9 @@ class associationservice extends \external_api | ||||||
|                   ]; |                   ]; | ||||||
|         $sql =  "SELECT u.* from {user} u LEFT JOIN {local_treestudyplan_user} j ON u.id = j.user_id"; |         $sql =  "SELECT u.* from {user} u LEFT JOIN {local_treestudyplan_user} j ON u.id = j.user_id"; | ||||||
|         $sql .= " WHERE u.deleted != 1 AND (firstname LIKE :pattern_fn OR lastname LIKE :pattern_ln OR username LIKE :pattern_un)"; |         $sql .= " WHERE u.deleted != 1 AND (firstname LIKE :pattern_fn OR lastname LIKE :pattern_ln OR username LIKE :pattern_un)"; | ||||||
|         if (isset($exclude_id) && is_numeric($exclude_id)) { |         if (isset($excludeid) && is_numeric($excludeid)) { | ||||||
|             $sql .= " AND  (j.studyplan_id IS NULL OR j.studyplan_id != :exclude_id)"; |             $sql .= " AND  (j.studyplan_id IS NULL OR j.studyplan_id != :exclude_id)"; | ||||||
|             $params['exclude_id'] = $exclude_id; |             $params['exclude_id'] = $excludeid; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         $users = []; |         $users = []; | ||||||
|  | @ -208,17 +208,17 @@ class associationservice extends \external_api | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	// Actual functions.
 | 	// Actual functions.
 | ||||||
| 	public static function connect_cohort($studyplan_id, $cohort_id) | 	public static function connect_cohort($studyplanid, $cohortid) | ||||||
| 	{ | 	{ | ||||||
|         global $CFG, $DB; |         global $CFG, $DB; | ||||||
| 
 | 
 | ||||||
|         $studyplan = studyplan::findById($studyplan_id); |         $studyplan = studyplan::findById($studyplanid); | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context()); | ||||||
| 
 | 
 | ||||||
|         if (!$DB->record_exists('local_treestudyplan_cohort', ['studyplan_id' => $studyplan_id, 'cohort_id' => $cohort_id])) { |         if (!$DB->record_exists('local_treestudyplan_cohort', ['studyplan_id' => $studyplanid, 'cohort_id' => $cohortid])) { | ||||||
|             $id = $DB->insert_record('local_treestudyplan_cohort', [ |             $id = $DB->insert_record('local_treestudyplan_cohort', [ | ||||||
|                 'studyplan_id' => $studyplan_id, |                 'studyplan_id' => $studyplanid, | ||||||
|                 'cohort_id' => $cohort_id, |                 'cohort_id' => $cohortid, | ||||||
|             ]); |             ]); | ||||||
| 
 | 
 | ||||||
|             $studyplan->mark_csync_changed(); |             $studyplan->mark_csync_changed(); | ||||||
|  | @ -247,17 +247,17 @@ class associationservice extends \external_api | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	// Actual functions.
 | 	// Actual functions.
 | ||||||
| 	public static function disconnect_cohort($studyplan_id, $cohort_id) | 	public static function disconnect_cohort($studyplanid, $cohortid) | ||||||
| 	{ | 	{ | ||||||
| 		global $CFG, $DB; | 		global $CFG, $DB; | ||||||
| 
 | 
 | ||||||
|         $studyplan = studyplan::findById($studyplan_id); |         $studyplan = studyplan::findById($studyplanid); | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context()); | ||||||
| 
 | 
 | ||||||
|         if ($DB->record_exists('local_treestudyplan_cohort', ['studyplan_id' => $studyplan_id, 'cohort_id' => $cohort_id])) { |         if ($DB->record_exists('local_treestudyplan_cohort', ['studyplan_id' => $studyplanid, 'cohort_id' => $cohortid])) { | ||||||
|             $DB->delete_records('local_treestudyplan_cohort', [ |             $DB->delete_records('local_treestudyplan_cohort', [ | ||||||
|                 'studyplan_id' => $studyplan_id, |                 'studyplan_id' => $studyplanid, | ||||||
|                 'cohort_id' => $cohort_id, |                 'cohort_id' => $cohortid, | ||||||
|             ]); |             ]); | ||||||
| 
 | 
 | ||||||
|             $studyplan->mark_csync_changed(); |             $studyplan->mark_csync_changed(); | ||||||
|  | @ -286,17 +286,17 @@ class associationservice extends \external_api | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	// Actual functions.
 | 	// Actual functions.
 | ||||||
| 	public static function connect_user($studyplan_id, $user_id) | 	public static function connect_user($studyplanid, $userid) | ||||||
| 	{ | 	{ | ||||||
| 		global $CFG, $DB; | 		global $CFG, $DB; | ||||||
| 
 | 
 | ||||||
|         $studyplan = studyplan::findById($studyplan_id); |         $studyplan = studyplan::findById($studyplanid); | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context()); | ||||||
| 
 | 
 | ||||||
|         if (!$DB->record_exists('local_treestudyplan_user', ['studyplan_id' => $studyplan_id, 'user_id' => $user_id])) { |         if (!$DB->record_exists('local_treestudyplan_user', ['studyplan_id' => $studyplanid, 'user_id' => $userid])) { | ||||||
|             $id = $DB->insert_record('local_treestudyplan_user', [ |             $id = $DB->insert_record('local_treestudyplan_user', [ | ||||||
|                 'studyplan_id' => $studyplan_id, |                 'studyplan_id' => $studyplanid, | ||||||
|                 'user_id' => $user_id, |                 'user_id' => $userid, | ||||||
|             ]); |             ]); | ||||||
|             $studyplan->mark_csync_changed(); |             $studyplan->mark_csync_changed(); | ||||||
| 
 | 
 | ||||||
|  | @ -324,16 +324,16 @@ class associationservice extends \external_api | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	// Actual functions.
 | 	// Actual functions.
 | ||||||
| 	public static function disconnect_user($studyplan_id, $user_id) | 	public static function disconnect_user($studyplanid, $userid) | ||||||
| 	{ | 	{ | ||||||
| 		global $CFG, $DB; | 		global $CFG, $DB; | ||||||
|         $studyplan = studyplan::findById($studyplan_id); |         $studyplan = studyplan::findById($studyplanid); | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context()); | ||||||
| 
 | 
 | ||||||
|         if ($DB->record_exists('local_treestudyplan_user', ['studyplan_id' => $studyplan_id, 'user_id' => $user_id])) { |         if ($DB->record_exists('local_treestudyplan_user', ['studyplan_id' => $studyplanid, 'user_id' => $userid])) { | ||||||
|             $DB->delete_records('local_treestudyplan_user', [ |             $DB->delete_records('local_treestudyplan_user', [ | ||||||
|                 'studyplan_id' => $studyplan_id, |                 'studyplan_id' => $studyplanid, | ||||||
|                 'user_id' => $user_id, |                 'user_id' => $userid, | ||||||
|             ]); |             ]); | ||||||
| 
 | 
 | ||||||
|             $studyplan->mark_csync_changed(); |             $studyplan->mark_csync_changed(); | ||||||
|  | @ -357,15 +357,15 @@ class associationservice extends \external_api | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	// Actual functions.
 | 	// Actual functions.
 | ||||||
| 	public static function associated_users($studyplan_id) | 	public static function associated_users($studyplanid) | ||||||
| 	{ | 	{ | ||||||
| 		global $CFG, $DB; | 		global $CFG, $DB; | ||||||
|         $studyplan = studyplan::findById($studyplan_id); |         $studyplan = studyplan::findById($studyplanid); | ||||||
|         webservicehelper::require_capabilities(self::CAP_VIEW, $studyplan->context()); |         webservicehelper::require_capabilities(self::CAP_VIEW, $studyplan->context()); | ||||||
| 
 | 
 | ||||||
|         $sql = "SELECT DISTINCT u.* FROM {user} u INNER JOIN {local_treestudyplan_user} j ON j.user_id = u.id"; |         $sql = "SELECT DISTINCT u.* FROM {user} u INNER JOIN {local_treestudyplan_user} j ON j.user_id = u.id"; | ||||||
|         $sql .= " WHERE j.studyplan_id = :studyplan_id"; |         $sql .= " WHERE j.studyplan_id = :studyplan_id"; | ||||||
|         $rs = $DB->get_recordset_sql($sql, ['studyplan_id' => $studyplan_id]); |         $rs = $DB->get_recordset_sql($sql, ['studyplan_id' => $studyplanid]); | ||||||
| 
 | 
 | ||||||
|         $users = []; |         $users = []; | ||||||
|         foreach ($rs as $u) { |         foreach ($rs as $u) { | ||||||
|  | @ -389,15 +389,15 @@ class associationservice extends \external_api | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	// Actual functions.
 | 	// Actual functions.
 | ||||||
| 	public static function associated_cohorts($studyplan_id) | 	public static function associated_cohorts($studyplanid) | ||||||
| 	{ | 	{ | ||||||
| 		global $CFG, $DB; | 		global $CFG, $DB; | ||||||
|         $studyplan = studyplan::findById($studyplan_id); |         $studyplan = studyplan::findById($studyplanid); | ||||||
|         webservicehelper::require_capabilities(self::CAP_VIEW, $studyplan->context()); |         webservicehelper::require_capabilities(self::CAP_VIEW, $studyplan->context()); | ||||||
| 
 | 
 | ||||||
|         $sql = "SELECT DISTINCT c.* FROM {cohort} c INNER JOIN {local_treestudyplan_cohort} j ON j.cohort_id = c.id"; |         $sql = "SELECT DISTINCT c.* FROM {cohort} c INNER JOIN {local_treestudyplan_cohort} j ON j.cohort_id = c.id"; | ||||||
|         $sql .= " WHERE j.studyplan_id = :studyplan_id"; |         $sql .= " WHERE j.studyplan_id = :studyplan_id"; | ||||||
|         $rs = $DB->get_recordset_sql($sql, ['studyplan_id' => $studyplan_id]); |         $rs = $DB->get_recordset_sql($sql, ['studyplan_id' => $studyplanid]); | ||||||
|         $cohorts = []; |         $cohorts = []; | ||||||
|         foreach ($rs as $c) { |         foreach ($rs as $c) { | ||||||
|             $cohorts[] = self::make_cohort_model($c); |             $cohorts[] = self::make_cohort_model($c); | ||||||
|  | @ -420,11 +420,11 @@ class associationservice extends \external_api | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	// Actual functions.
 | 	// Actual functions.
 | ||||||
| 	public static function all_associated($studyplan_id) | 	public static function all_associated($studyplanid) | ||||||
| 	{ | 	{ | ||||||
| 		global $CFG, $DB; | 		global $CFG, $DB; | ||||||
| 
 | 
 | ||||||
|         $studyplan = studyplan::findById($studyplan_id); |         $studyplan = studyplan::findById($studyplanid); | ||||||
|         webservicehelper::require_capabilities(self::CAP_VIEW, $studyplan->context()); |         webservicehelper::require_capabilities(self::CAP_VIEW, $studyplan->context()); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -436,8 +436,8 @@ class associationservice extends \external_api | ||||||
|                 LEFT JOIN {cohort_members}              cm ON u.id = cm.userid |                 LEFT JOIN {cohort_members}              cm ON u.id = cm.userid | ||||||
|                 LEFT JOIN {local_treestudyplan_cohort}  tc ON cm.cohortid = tc.cohort_id |                 LEFT JOIN {local_treestudyplan_cohort}  tc ON cm.cohortid = tc.cohort_id | ||||||
|                 LEFT JOIN {local_treestudyplan_user}    tu ON u.id = tu.user_id |                 LEFT JOIN {local_treestudyplan_user}    tu ON u.id = tu.user_id | ||||||
|                 WHERE tc.studyplan_id = {$studyplan_id} |                 WHERE tc.studyplan_id = {$studyplanid} | ||||||
|                    OR tu.studyplan_id = {$studyplan_id} |                    OR tu.studyplan_id = {$studyplanid} | ||||||
|                 ORDER BY u.lastname, u.firstname";
 |                 ORDER BY u.lastname, u.firstname";
 | ||||||
|         $rs = $DB->get_recordset_sql($sql); |         $rs = $DB->get_recordset_sql($sql); | ||||||
| 
 | 
 | ||||||
|  | @ -454,16 +454,16 @@ class associationservice extends \external_api | ||||||
|         return usort($list, function($a, $b) { |         return usort($list, function($a, $b) { | ||||||
|             $m= []; |             $m= []; | ||||||
|             if (preg_match("/.*?([A-Z].*)/", $a['lastname'], $m)) { |             if (preg_match("/.*?([A-Z].*)/", $a['lastname'], $m)) { | ||||||
|                 $sort_ln_a = $m[1]; |                 $sortln_a = $m[1]; | ||||||
|             } else { |             } else { | ||||||
|                 $sort_ln_a = $a['lastname']; |                 $sortln_a = $a['lastname']; | ||||||
|             } |             } | ||||||
|             if (preg_match("/.*?([A-Z].*)/", $b['lastname'], $m)) { |             if (preg_match("/.*?([A-Z].*)/", $b['lastname'], $m)) { | ||||||
|                 $sort_ln_b = $m[1]; |                 $sortln_b = $m[1]; | ||||||
|             } else { |             } else { | ||||||
|                 $sort_ln_b = $b['lastname']; |                 $sortln_b = $b['lastname']; | ||||||
|             } |             } | ||||||
|             $cmp= $sort_ln_a <=> $sort_ln_b; |             $cmp= $sortln_a <=> $sortln_b; | ||||||
|             return  ($cmp != 0)?$cmp:$a['firstname'] <=> $b['firstname']; |             return  ($cmp != 0)?$cmp:$a['firstname'] <=> $b['firstname']; | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  | @ -481,9 +481,9 @@ class associationservice extends \external_api | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	// Actual functions.
 | 	// Actual functions.
 | ||||||
| 	public static function cascade_cohortsync($studyplan_id) | 	public static function cascade_cohortsync($studyplanid) | ||||||
| 	{ | 	{ | ||||||
|         $studyplan = studyplan::findById($studyplan_id); |         $studyplan = studyplan::findById($studyplanid); | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, $studyplan->context()); | ||||||
| 
 | 
 | ||||||
|         $enroller = new cascadecohortsync($studyplan); |         $enroller = new cascadecohortsync($studyplan); | ||||||
|  |  | ||||||
|  | @ -154,10 +154,10 @@ class badgeinfo { | ||||||
|         return $badge; |         return $badge; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     function count_issued(array $student_ids) { |     function count_issued(array $studentids) { | ||||||
|         $issuecount = 0; |         $issuecount = 0; | ||||||
| 
 | 
 | ||||||
|         foreach ($student_ids as $userid) { |         foreach ($studentids as $userid) { | ||||||
|             if ($this->badge->is_issued($userid)) { |             if ($this->badge->is_issued($userid)) { | ||||||
|                 $issuecount++; |                 $issuecount++; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  | @ -45,8 +45,7 @@ class completion { | ||||||
|     public static function label($completion) { |     public static function label($completion) { | ||||||
|         if (array_key_exists($completion, self::LABELS)) { |         if (array_key_exists($completion, self::LABELS)) { | ||||||
|             return self::LABELS[$completion]; |             return self::LABELS[$completion]; | ||||||
|         } else |         } else { | ||||||
|         { |  | ||||||
|             return self::LABELS[self::INCOMPLETE]; |             return self::LABELS[self::INCOMPLETE]; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -27,33 +27,33 @@ use \grade_item; | ||||||
| 
 | 
 | ||||||
| class completionscanner | class completionscanner | ||||||
| { | { | ||||||
|     private static $mod_supported = []; |     private static $modsupported = []; | ||||||
|     private static $course_students = []; |     private static $coursestudents = []; | ||||||
|     private $scanner = null; |     private $scanner = null; | ||||||
|     private $course = null; |     private $course = null; | ||||||
|     private $cm = null; |     private $cm = null; | ||||||
|     private $gi = null; |     private $gi = null; | ||||||
|     private $pending_cache = []; |     private $pendingcache = []; | ||||||
| 
 | 
 | ||||||
|     public static function supported($mod) { |     public static function supported($mod) { | ||||||
|         if (!array_key_exists($mod, self::$mod_supported)) { |         if (!array_key_exists($mod, self::$modsupported)) { | ||||||
|             self::$mod_supported[$mod] = class_exists("\local_treestudyplan\\local\\ungradedscanners\\{$mod}_scanner"); |             self::$modsupported[$mod] = class_exists("\local_treestudyplan\\local\\ungradedscanners\\{$mod}_scanner"); | ||||||
|         } |         } | ||||||
|         return self::$mod_supported[$mod]; |         return self::$modsupported[$mod]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function get_course_students($courseid) { |     public static function get_course_students($courseid) { | ||||||
|         global $CFG; |         global $CFG; | ||||||
|         if (!array_key_exists($courseid, self::$course_students)) { |         if (!array_key_exists($courseid, self::$coursestudents)) { | ||||||
|             $students = []; |             $students = []; | ||||||
|             $context = \context_course::instance($courseid); |             $context = \context_course::instance($courseid); | ||||||
|             foreach (explode(', ', $CFG->gradebookroles) as $roleid) { |             foreach (explode(', ', $CFG->gradebookroles) as $roleid) { | ||||||
|                 $roleid = trim($roleid); |                 $roleid = trim($roleid); | ||||||
|                 $students = array_keys(get_role_users($roleid, $context, false, 'u.id', 'u.id ASC')); |                 $students = array_keys(get_role_users($roleid, $context, false, 'u.id', 'u.id ASC')); | ||||||
|             } |             } | ||||||
|             self::$course_students[$courseid] = $students; |             self::$coursestudents[$courseid] = $students; | ||||||
|         } |         } | ||||||
|         return self::$course_students[$courseid]; |         return self::$coursestudents[$courseid]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function __construct(\completion_criteria $crit, $course) { |     public function __construct(\completion_criteria $crit, $course) { | ||||||
|  | @ -112,8 +112,8 @@ class completionscanner | ||||||
|         $students = self::get_course_students($this->courseid); |         $students = self::get_course_students($this->courseid); | ||||||
|         $completed = 0; |         $completed = 0; | ||||||
|         $ungraded = 0; |         $ungraded = 0; | ||||||
|         $completed_pass = 0; |         $completedpass = 0; | ||||||
|         $completed_fail = 0; |         $completedfail = 0; | ||||||
|         foreach ($students as $userid) { |         foreach ($students as $userid) { | ||||||
|             if ($this->pending($userid)) { |             if ($this->pending($userid)) { | ||||||
|                 // First check if the completion needs grading.
 |                 // First check if the completion needs grading.
 | ||||||
|  | @ -123,13 +123,13 @@ class completionscanner | ||||||
| 
 | 
 | ||||||
|                 if ($this->crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) { |                 if ($this->crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) { | ||||||
|                     // If it's an activity completion, add all the relevant activities as sub-items.
 |                     // If it's an activity completion, add all the relevant activities as sub-items.
 | ||||||
|                     $completion_status = $this->completioninfo->get_grade_completion($this->cm, $userid); |                     $completionstatus = $this->completioninfo->get_grade_completion($this->cm, $userid); | ||||||
| 
 | 
 | ||||||
|                     if ($completion_status == COMPLETION_COMPLETE_PASS) { |                     if ($completionstatus == COMPLETION_COMPLETE_PASS) { | ||||||
|                         $completed_pass++; |                         $completedpass++; | ||||||
|                     } else if ($completion_status == COMPLETION_COMPLETE_FAIL) { |                     } else if ($completionstatus == COMPLETION_COMPLETE_FAIL) { | ||||||
|                         $completed_fail++; |                         $completedfail++; | ||||||
|                     } else if ($completion_status == COMPLETION_COMPLETE) { |                     } else if ($completionstatus == COMPLETION_COMPLETE) { | ||||||
|                         $completed++; |                         $completed++; | ||||||
|                     } |                     } | ||||||
|                 } else{ |                 } else{ | ||||||
|  | @ -145,8 +145,8 @@ class completionscanner | ||||||
|         return [ |         return [ | ||||||
|             'ungraded' => $ungraded, |             'ungraded' => $ungraded, | ||||||
|             'completed' => $completed, |             'completed' => $completed, | ||||||
|             'completed_pass' => $completed_pass, |             'completed_pass' => $completedpass, | ||||||
|             'completed_fail' => $completed_fail, |             'completed_fail' => $completedfail, | ||||||
|             'students' => count($students), |             'students' => count($students), | ||||||
|         ]; |         ]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -35,7 +35,7 @@ class corecompletioninfo { | ||||||
|     private $course; |     private $course; | ||||||
|     private $completion; |     private $completion; | ||||||
|     private $modinfo; |     private $modinfo; | ||||||
|     private static $COMPLETION_HANDLES = null; |     private static $COMPLETIONHANDLES = null; | ||||||
| 
 | 
 | ||||||
|     public function id() { |     public function id() { | ||||||
|         return $this->course->id; |         return $this->course->id; | ||||||
|  | @ -48,10 +48,10 @@ class corecompletioninfo { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     static public function completiontypes() { |     static public function completiontypes() { | ||||||
|         global $COMPLETION_CRITERIA_TYPES; |         global $COMPLETIONCRITERIA_TYPES; | ||||||
|         // Just return the keys of the global array COMPLETION_CRITERIA_TYPES, so we don't have to manually.
 |         // Just return the keys of the global array COMPLETION_CRITERIA_TYPES, so we don't have to manually.
 | ||||||
|         // add any completion types....
 |         // add any completion types....
 | ||||||
|         return \array_keys($COMPLETION_CRITERIA_TYPES); |         return \array_keys($COMPLETIONCRITERIA_TYPES); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | @ -59,16 +59,16 @@ class corecompletioninfo { | ||||||
|      * @param $completion The completion code as defined in completionlib.php to translate to a text handle |      * @param $completion The completion code as defined in completionlib.php to translate to a text handle | ||||||
|      */ |      */ | ||||||
|     static public function completion_handle($completion) { |     static public function completion_handle($completion) { | ||||||
|         if (empty(self::$COMPLETION_HANDLES)) { |         if (empty(self::$COMPLETIONHANDLES)) { | ||||||
|             // Cache the translation table, to avoid overhead.
 |             // Cache the translation table, to avoid overhead.
 | ||||||
|             self::$COMPLETION_HANDLES = [ |             self::$COMPLETIONHANDLES = [ | ||||||
|                 COMPLETION_INCOMPLETE => "incomplete", |                 COMPLETION_INCOMPLETE => "incomplete", | ||||||
|                 COMPLETION_COMPLETE => "complete", |                 COMPLETION_COMPLETE => "complete", | ||||||
|                 COMPLETION_COMPLETE_PASS => "complete-pass", |                 COMPLETION_COMPLETE_PASS => "complete-pass", | ||||||
|                 COMPLETION_COMPLETE_FAIL => "complete-fail", |                 COMPLETION_COMPLETE_FAIL => "complete-fail", | ||||||
|                 COMPLETION_COMPLETE_FAIL_HIDDEN => "complete-fail"]; // the front end won't differentiate between hidden or not.
 |                 COMPLETION_COMPLETE_FAIL_HIDDEN => "complete-fail"]; // the front end won't differentiate between hidden or not.
 | ||||||
|         } |         } | ||||||
|         return self::$COMPLETION_HANDLES[$completion] ?? "undefined"; |         return self::$COMPLETIONHANDLES[$completion] ?? "undefined"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function completion_item_editor_structure($value=VALUE_REQUIRED) { |     public static function completion_item_editor_structure($value=VALUE_REQUIRED) { | ||||||
|  | @ -155,7 +155,7 @@ class corecompletioninfo { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function editor_model() { |     public function editor_model() { | ||||||
|         global $DB, $CFG, $COMPLETION_CRITERIA_TYPES; |         global $DB, $CFG, $COMPLETIONCRITERIA_TYPES; | ||||||
| 
 | 
 | ||||||
|         $conditions = []; |         $conditions = []; | ||||||
|         $aggregation = "all"; // default.
 |         $aggregation = "all"; // default.
 | ||||||
|  | @ -174,7 +174,7 @@ class corecompletioninfo { | ||||||
|                 if (count($criterias) > 0 ) // Only take it into account if the criteria count is > 0.
 |                 if (count($criterias) > 0 ) // Only take it into account if the criteria count is > 0.
 | ||||||
|                 { |                 { | ||||||
|                     $cinfo = [ |                     $cinfo = [ | ||||||
|                         "type" => $COMPLETION_CRITERIA_TYPES[$type], |                         "type" => $COMPLETIONCRITERIA_TYPES[$type], | ||||||
|                         "aggregation" => self::aggregation_handle($this->completion->get_aggregation_method($type)), |                         "aggregation" => self::aggregation_handle($this->completion->get_aggregation_method($type)), | ||||||
|                         "title" => reset($criterias)->get_type_title(), |                         "title" => reset($criterias)->get_type_title(), | ||||||
|                         "items" => [], |                         "items" => [], | ||||||
|  | @ -325,7 +325,7 @@ class corecompletioninfo { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function user_model($userid) { |     public function user_model($userid) { | ||||||
|         global $DB, $COMPLETION_CRITERIA_TYPES; |         global $DB, $COMPLETIONCRITERIA_TYPES; | ||||||
| 
 | 
 | ||||||
|         $progress = $this->get_advanced_progress_percentage($userid); |         $progress = $this->get_advanced_progress_percentage($userid); | ||||||
|         $info = [ |         $info = [ | ||||||
|  | @ -349,7 +349,7 @@ class corecompletioninfo { | ||||||
|                     $typeaggregation = $this->completion->get_aggregation_method($type); |                     $typeaggregation = $this->completion->get_aggregation_method($type); | ||||||
|                     $completed = $this->aggregate_completions($typeaggregation, $completions); |                     $completed = $this->aggregate_completions($typeaggregation, $completions); | ||||||
|                     $cinfo = [ |                     $cinfo = [ | ||||||
|                         "type" => $COMPLETION_CRITERIA_TYPES[$type], |                         "type" => $COMPLETIONCRITERIA_TYPES[$type], | ||||||
|                         "aggregation" => self::aggregation_handle($typeaggregation), |                         "aggregation" => self::aggregation_handle($typeaggregation), | ||||||
|                         "completed" => $completed, |                         "completed" => $completed, | ||||||
|                         "status" => $completed?"complete":"incomplete", |                         "status" => $completed?"complete":"incomplete", | ||||||
|  | @ -376,10 +376,10 @@ class corecompletioninfo { | ||||||
|                         if ($type == COMPLETION_CRITERIA_TYPE_ACTIVITY) { |                         if ($type == COMPLETION_CRITERIA_TYPE_ACTIVITY) { | ||||||
|                             $cm = $this->modinfo->get_cm($criteria->moduleinstance); |                             $cm = $this->modinfo->get_cm($criteria->moduleinstance); | ||||||
|                             // If it's an activity completion, add all the relevant activities as sub-items.
 |                             // If it's an activity completion, add all the relevant activities as sub-items.
 | ||||||
|                             $completion_status = $this->completion->get_grade_completion($cm, $userid); |                             $completionstatus = $this->completion->get_grade_completion($cm, $userid); | ||||||
|                             $iinfo['status'] = self::completion_handle($completion_status); |                             $iinfo['status'] = self::completion_handle($completionstatus); | ||||||
|                             // Re-evaluate the completed value, to make sure COMPLETE_FAIL doesn't creep in as completed.
 |                             // Re-evaluate the completed value, to make sure COMPLETE_FAIL doesn't creep in as completed.
 | ||||||
|                             $iinfo['completed'] = in_array($completion_status, [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS]); |                             $iinfo['completed'] = in_array($completionstatus, [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS]); | ||||||
|                             // Determine the grade (retrieve from grade item, not from completion).
 |                             // Determine the grade (retrieve from grade item, not from completion).
 | ||||||
|                             $grade = $this->get_grade($cm, $userid); |                             $grade = $this->get_grade($cm, $userid); | ||||||
|                             $iinfo['grade'] = $grade->grade; |                             $iinfo['grade'] = $grade->grade; | ||||||
|  | @ -388,7 +388,7 @@ class corecompletioninfo { | ||||||
| 
 | 
 | ||||||
|                             $anypending = $anypending || $grade->pending; |                             $anypending = $anypending || $grade->pending; | ||||||
|                             // Overwrite the status with progress if something has been graded, or is pending.
 |                             // Overwrite the status with progress if something has been graded, or is pending.
 | ||||||
|                             if ($completion_status != COMPLETION_INCOMPLETE || $anypending) { |                             if ($completionstatus != COMPLETION_INCOMPLETE || $anypending) { | ||||||
|                                 if ($cinfo["status"] == "incomplete") { |                                 if ($cinfo["status"] == "incomplete") { | ||||||
|                                     $cinfo["status"] = "progress"; |                                     $cinfo["status"] = "progress"; | ||||||
|                                 } |                                 } | ||||||
|  | @ -455,8 +455,7 @@ class corecompletioninfo { | ||||||
|                     if (isset($scale)) { |                     if (isset($scale)) { | ||||||
|                         // get scale value.
 |                         // get scale value.
 | ||||||
|                         $result->grade = $scale->get_nearest_item($grade->finalgrade); |                         $result->grade = $scale->get_nearest_item($grade->finalgrade); | ||||||
|                     } else |                     } else { | ||||||
|                     { |  | ||||||
|                         // round final grade to 1 decimal point.
 |                         // round final grade to 1 decimal point.
 | ||||||
|                         $result->grade =  round($grade->finalgrade, 1); |                         $result->grade =  round($grade->finalgrade, 1); | ||||||
|                     } |                     } | ||||||
|  | @ -496,8 +495,7 @@ class corecompletioninfo { | ||||||
|                     if (isset($scale)) { |                     if (isset($scale)) { | ||||||
|                         // get scale value.
 |                         // get scale value.
 | ||||||
|                         return $scale->get_nearest_item($grade->finalgrade); |                         return $scale->get_nearest_item($grade->finalgrade); | ||||||
|                     } else |                     } else { | ||||||
|                     { |  | ||||||
|                         // round final grade to 1 decimal point.
 |                         // round final grade to 1 decimal point.
 | ||||||
|                         return round($grade->finalgrade, 1); |                         return round($grade->finalgrade, 1); | ||||||
|                     } |                     } | ||||||
|  | @ -627,7 +625,7 @@ class corecompletioninfo { | ||||||
|         // Now that we have all completions sorted by type, we can be smart about how to do the count.
 |         // Now that we have all completions sorted by type, we can be smart about how to do the count.
 | ||||||
|         $count = 0; |         $count = 0; | ||||||
|         $completed = 0; |         $completed = 0; | ||||||
|         $completion_percentage = 0; |         $completionpercentage = 0; | ||||||
|         foreach ($critcount as $c) { |         foreach ($critcount as $c) { | ||||||
|             // Take only types that are actually present into account.
 |             // Take only types that are actually present into account.
 | ||||||
|             if ($c->count > 0) { |             if ($c->count > 0) { | ||||||
|  | @ -644,10 +642,10 @@ class corecompletioninfo { | ||||||
|                 // Overwrite data if current type is more complete.
 |                 // Overwrite data if current type is more complete.
 | ||||||
|                 if ($aggregation == COMPLETION_AGGREGATION_ANY) { |                 if ($aggregation == COMPLETION_AGGREGATION_ANY) { | ||||||
|                     $pct = $cmpl/$ct; |                     $pct = $cmpl/$ct; | ||||||
|                     if ($pct > $completion_percentage) { |                     if ($pct > $completionpercentage) { | ||||||
|                         $count = $ct; |                         $count = $ct; | ||||||
|                         $completed = $cmpl; |                         $completed = $cmpl; | ||||||
|                         $completion_percentage = $pct; |                         $completionpercentage = $pct; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 // if ALL completion for the types, add the count for this type to that of the others.
 |                 // if ALL completion for the types, add the count for this type to that of the others.
 | ||||||
|  |  | ||||||
|  | @ -78,8 +78,7 @@ class courseinfo { | ||||||
|         global $USER, $DB; |         global $USER, $DB; | ||||||
|         if ($userid <= 0) { |         if ($userid <= 0) { | ||||||
|             $usr = $USER; |             $usr = $USER; | ||||||
|         } else |         } else { | ||||||
|         { |  | ||||||
|             $usr = $DB->get_record('user', ['id' => $userid, 'deleted' => 0]); |             $usr = $DB->get_record('user', ['id' => $userid, 'deleted' => 0]); | ||||||
|         } |         } | ||||||
|         return($usr && is_enrolled($this->coursecontext, $usr, 'local/treestudyplan:selectowngradables')); |         return($usr && is_enrolled($this->coursecontext, $usr, 'local/treestudyplan:selectowngradables')); | ||||||
|  |  | ||||||
|  | @ -32,8 +32,8 @@ use \grade_item; | ||||||
| class coursemoduleinfo { | class coursemoduleinfo { | ||||||
|     private $id; |     private $id; | ||||||
|     private $cm; |     private $cm; | ||||||
|     private $cm_info; |     private $cminfo; | ||||||
|     private $db_record; |     private $dbrecord; | ||||||
| 
 | 
 | ||||||
|     public function __construct($id) { |     public function __construct($id) { | ||||||
|         global $DB; |         global $DB; | ||||||
|  |  | ||||||
|  | @ -69,10 +69,10 @@ class courseservice extends \external_api | ||||||
|         return  new \external_single_structure($s, "CourseCat info", $value); |         return  new \external_single_structure($s, "CourseCat info", $value); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function map_categories($root_id = 0) { |     public static function map_categories($rootid = 0) { | ||||||
|         global $CFG, $DB; |         global $CFG, $DB; | ||||||
| 
 | 
 | ||||||
|         $root = \core_course_category::get($root_id); |         $root = \core_course_category::get($rootid); | ||||||
|         $context = $root->get_context(); |         $context = $root->get_context(); | ||||||
|         // Make sure the user has access to the context for editing purposes.
 |         // Make sure the user has access to the context for editing purposes.
 | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, $context); |         webservicehelper::require_capabilities(self::CAP_EDIT, $context); | ||||||
|  | @ -81,11 +81,11 @@ class courseservice extends \external_api | ||||||
| 
 | 
 | ||||||
|         if ($root->id == 0) { |         if ($root->id == 0) { | ||||||
|             // on the system level, determine the user's topmost allowed catecories.
 |             // on the system level, determine the user's topmost allowed catecories.
 | ||||||
|             $user_top = \core_course_category::user_top(); |             $usertop = \core_course_category::user_top(); | ||||||
|             if ($user_top->id == 0) { // top category..
 |             if ($usertop->id == 0) { // top category..
 | ||||||
|                 $children = $root->get_children(); // returns a list of çore_course_category, let it overwrite $children.
 |                 $children = $root->get_children(); // returns a list of çore_course_category, let it overwrite $children.
 | ||||||
|             } else { |             } else { | ||||||
|                 $children = [$user_top]; |                 $children = [$usertop]; | ||||||
|             } |             } | ||||||
|         } else if ($root->is_uservisible()) { |         } else if ($root->is_uservisible()) { | ||||||
|             $children = [$root]; |             $children = [$root]; | ||||||
|  | @ -117,13 +117,13 @@ class courseservice extends \external_api | ||||||
|     protected static function map_category(\core_course_category $cat, $lazy=false) { |     protected static function map_category(\core_course_category $cat, $lazy=false) { | ||||||
|         global $DB; |         global $DB; | ||||||
|         $catcontext = $cat->get_context(); |         $catcontext = $cat->get_context(); | ||||||
|         $ctx_info = new contextinfo($catcontext); |         $ctxinfo = new contextinfo($catcontext); | ||||||
|         $children = $cat->get_children(); // only shows children visible to the current user.
 |         $children = $cat->get_children(); // only shows children visible to the current user.
 | ||||||
|         $courses = $cat->get_courses(); |         $courses = $cat->get_courses(); | ||||||
|         $model = [ |         $model = [ | ||||||
|             "id" => $cat->id, |             "id" => $cat->id, | ||||||
|             "context_id" => $catcontext->id, |             "context_id" => $catcontext->id, | ||||||
|             "category" => $ctx_info->model(), |             "category" => $ctxinfo->model(), | ||||||
|             "haschildren" => !empty($children), |             "haschildren" => !empty($children), | ||||||
|             "hascourses" => !empty($courses), |             "hascourses" => !empty($courses), | ||||||
|         ]; |         ]; | ||||||
|  | @ -236,11 +236,11 @@ class courseservice extends \external_api | ||||||
|         } else { // $operation == "view" || default.
 |         } else { // $operation == "view" || default.
 | ||||||
|             $capability = self::CAP_VIEW; |             $capability = self::CAP_VIEW; | ||||||
|         } |         } | ||||||
|         $context_ids = []; |         $contextids = []; | ||||||
|         $rs = $DB->get_recordset_sql("SELECT DISTINCT context_id, COUNT(*) as num FROM {local_treestudyplan}
 |         $rs = $DB->get_recordset_sql("SELECT DISTINCT context_id, COUNT(*) as num FROM {local_treestudyplan}
 | ||||||
|                                          GROUP BY context_id");
 |                                          GROUP BY context_id");
 | ||||||
|         foreach ($rs as $r) { |         foreach ($rs as $r) { | ||||||
|             $context_ids[$r->context_id] = $r->num; |             $contextids[$r->context_id] = $r->num; | ||||||
|         } |         } | ||||||
|         $rs->close(); |         $rs->close(); | ||||||
| 
 | 
 | ||||||
|  | @ -253,8 +253,8 @@ class courseservice extends \external_api | ||||||
|         foreach ($cats as $cat) { |         foreach ($cats as $cat) { | ||||||
|             $count = 0; |             $count = 0; | ||||||
|             $ctxid = $cat->get_context()->id; |             $ctxid = $cat->get_context()->id; | ||||||
|             if (array_key_exists($ctxid, $context_ids)) { |             if (array_key_exists($ctxid, $contextids)) { | ||||||
|                 $count = $context_ids[$ctxid]; |                 $count = $contextids[$ctxid]; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             $o = static::map_category($cat, true); |             $o = static::map_category($cat, true); | ||||||
|  | @ -272,11 +272,11 @@ class courseservice extends \external_api | ||||||
|             $capability = self::CAP_VIEW; |             $capability = self::CAP_VIEW; | ||||||
|         } |         } | ||||||
|         // retrieve context ids used.
 |         // retrieve context ids used.
 | ||||||
|         $context_ids = []; |         $contextids = []; | ||||||
|         $rs = $DB->get_recordset_sql("SELECT DISTINCT context_id, COUNT(*) as num FROM {local_treestudyplan}
 |         $rs = $DB->get_recordset_sql("SELECT DISTINCT context_id, COUNT(*) as num FROM {local_treestudyplan}
 | ||||||
|                                          GROUP BY context_id");
 |                                          GROUP BY context_id");
 | ||||||
|         foreach ($rs as $r) { |         foreach ($rs as $r) { | ||||||
|             $context_ids[$r->context_id] = $r->num; |             $contextids[$r->context_id] = $r->num; | ||||||
|         } |         } | ||||||
|         $rs->close(); |         $rs->close(); | ||||||
| 
 | 
 | ||||||
|  | @ -288,8 +288,8 @@ class courseservice extends \external_api | ||||||
|         foreach ($cats as $cat) { |         foreach ($cats as $cat) { | ||||||
|             $count = 0; |             $count = 0; | ||||||
|             $ctxid = $cat->get_context()->id; |             $ctxid = $cat->get_context()->id; | ||||||
|             if (array_key_exists($ctxid, $context_ids)) { |             if (array_key_exists($ctxid, $contextids)) { | ||||||
|                 $count = $context_ids[$ctxid]; |                 $count = $contextids[$ctxid]; | ||||||
|             } |             } | ||||||
|             $o = new \stdClass(); |             $o = new \stdClass(); | ||||||
|             $o->cat = $cat; |             $o->cat = $cat; | ||||||
|  |  | ||||||
|  | @ -245,12 +245,10 @@ class gradeinfo { | ||||||
|                 $finalgrade = "-"; |                 $finalgrade = "-"; | ||||||
|             } else if (isset($this->scale)) { |             } else if (isset($this->scale)) { | ||||||
|                 $finalgrade = $this->scale->get_nearest_item($grade->finalgrade); |                 $finalgrade = $this->scale->get_nearest_item($grade->finalgrade); | ||||||
|             } else |             } else { | ||||||
|             { |  | ||||||
|                 $finalgrade = round($grade->finalgrade, 1); |                 $finalgrade = round($grade->finalgrade, 1); | ||||||
|             } |             } | ||||||
|         } else |         } else { | ||||||
|         { |  | ||||||
|             $finalgrade = "-"; |             $finalgrade = "-"; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -290,13 +288,13 @@ class gradeinfo { | ||||||
|     } |     } | ||||||
|     public static function import(studyitem $item, array $model) { |     public static function import(studyitem $item, array $model) { | ||||||
|         if ($item->type() == studyitem::COURSE) { |         if ($item->type() == studyitem::COURSE) { | ||||||
|             $course_id = $item->courseid(); |             $courseid = $item->courseid(); | ||||||
|             $gradeitems= grade_item::fetch_all(['itemtype' => 'mod', 'courseid' => $course_id]); |             $gradeitems= grade_item::fetch_all(['itemtype' => 'mod', 'courseid' => $courseid]); | ||||||
|             foreach ($gradeitems as $gi) { |             foreach ($gradeitems as $gi) { | ||||||
|                 $gi_name =  empty($outcome)?$gi->itemname:$outcome->name; |                 $giname =  empty($outcome)?$gi->itemname:$outcome->name; | ||||||
|                 $gi_type = $gi->itemmodule; |                 $gitype = $gi->itemmodule; | ||||||
| 
 | 
 | ||||||
|                 if ($gi_name == $model["name"] && $gi_type == $model["type"]) { |                 if ($giname == $model["name"] && $gitype == $model["type"]) { | ||||||
|                     // we have a match.
 |                     // we have a match.
 | ||||||
|                     if (!isset($model["selected"])) { $model["selected"] = true;} |                     if (!isset($model["selected"])) { $model["selected"] = true;} | ||||||
|                     if (!isset($model["required"])) { $model["required"] = false;} |                     if (!isset($model["required"])) { $model["required"] = false;} | ||||||
|  | @ -368,27 +366,27 @@ class gradeinfo { | ||||||
|         return $list; |         return $list; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function include_grade(int $grade_id, int $item_id, bool $include, bool $required=false) { |     public static function include_grade(int $gradeid, int $itemid, bool $include, bool $required=false) { | ||||||
|         global $DB; |         global $DB; | ||||||
|         $table = 'local_treestudyplan_gradeinc'; |         $table = 'local_treestudyplan_gradeinc'; | ||||||
|         if ($include) { |         if ($include) { | ||||||
|             // make sure a record exits.
 |             // make sure a record exits.
 | ||||||
|             $r = $DB->get_record($table, ['studyitem_id' => $item_id, 'grade_item_id' => $grade_id]); |             $r = $DB->get_record($table, ['studyitem_id' => $itemid, 'grade_item_id' => $gradeid]); | ||||||
|             if ($r) { |             if ($r) { | ||||||
|                 $r->include = 1; |                 $r->include = 1; | ||||||
|                 $r->required = boolval($required)?1:0; |                 $r->required = boolval($required)?1:0; | ||||||
|                 $id = $DB->update_record($table, $r); |                 $id = $DB->update_record($table, $r); | ||||||
|             } else { |             } else { | ||||||
|                 $DB->insert_record($table, [ |                 $DB->insert_record($table, [ | ||||||
|                     'studyitem_id' => $item_id, |                     'studyitem_id' => $itemid, | ||||||
|                     'grade_item_id' => $grade_id, |                     'grade_item_id' => $gradeid, | ||||||
|                     'include' => 1, |                     'include' => 1, | ||||||
|                     'required' =>boolval($required)?1:0] |                     'required' =>boolval($required)?1:0] | ||||||
|                 ); |                 ); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             // remove if it should not be included.
 |             // remove if it should not be included.
 | ||||||
|             $r = $DB->get_record($table, ['studyitem_id' => $item_id, 'grade_item_id' => $grade_id]); |             $r = $DB->get_record($table, ['studyitem_id' => $itemid, 'grade_item_id' => $gradeid]); | ||||||
|             if ($r) { |             if ($r) { | ||||||
|                 $DB->delete_records($table, ['id' => $r->id]); |                 $DB->delete_records($table, ['id' => $r->id]); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  | @ -30,31 +30,31 @@ use \grade_item; | ||||||
| // $gi->iteminstance.
 | // $gi->iteminstance.
 | ||||||
| class gradingscanner | class gradingscanner | ||||||
| { | { | ||||||
|     private static $mod_supported = []; |     private static $modsupported = []; | ||||||
|     private static $course_students = []; |     private static $coursestudents = []; | ||||||
|     private $scanner = null; |     private $scanner = null; | ||||||
|     private $gi = null; |     private $gi = null; | ||||||
|     private $pending_cache = []; |     private $pendingcache = []; | ||||||
| 
 | 
 | ||||||
|     public static function supported($mod) { |     public static function supported($mod) { | ||||||
|         if (!array_key_exists($mod, self::$mod_supported)) { |         if (!array_key_exists($mod, self::$modsupported)) { | ||||||
|             self::$mod_supported[$mod] = class_exists("\local_treestudyplan\\local\\ungradedscanners\\{$mod}_scanner"); |             self::$modsupported[$mod] = class_exists("\local_treestudyplan\\local\\ungradedscanners\\{$mod}_scanner"); | ||||||
|         } |         } | ||||||
|         return self::$mod_supported[$mod]; |         return self::$modsupported[$mod]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function get_course_students($courseid) { |     public static function get_course_students($courseid) { | ||||||
|         global $CFG; |         global $CFG; | ||||||
|         if (!array_key_exists($courseid, self::$course_students)) { |         if (!array_key_exists($courseid, self::$coursestudents)) { | ||||||
|             $students = []; |             $students = []; | ||||||
|             $context = \context_course::instance($courseid); |             $context = \context_course::instance($courseid); | ||||||
|             foreach (explode(', ', $CFG->gradebookroles) as $roleid) { |             foreach (explode(', ', $CFG->gradebookroles) as $roleid) { | ||||||
|                 $roleid = trim($roleid); |                 $roleid = trim($roleid); | ||||||
|                 $students = array_keys(get_role_users($roleid, $context, false, 'u.id', 'u.id ASC')); |                 $students = array_keys(get_role_users($roleid, $context, false, 'u.id', 'u.id ASC')); | ||||||
|             } |             } | ||||||
|             self::$course_students[$courseid] = $students; |             self::$coursestudents[$courseid] = $students; | ||||||
|         } |         } | ||||||
|         return self::$course_students[$courseid]; |         return self::$coursestudents[$courseid]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function __construct(grade_item $gi) { |     public function __construct(grade_item $gi) { | ||||||
|  | @ -96,8 +96,8 @@ class gradingscanner | ||||||
|         $students = self::get_course_students($this->courseid); |         $students = self::get_course_students($this->courseid); | ||||||
|         $completed = 0; |         $completed = 0; | ||||||
|         $ungraded = 0; |         $ungraded = 0; | ||||||
|         $completed_pass = 0; |         $completedpass = 0; | ||||||
|         $completed_fail = 0; |         $completedfail = 0; | ||||||
|         foreach ($students as $userid) { |         foreach ($students as $userid) { | ||||||
|             if ($this->pending($userid)) { |             if ($this->pending($userid)) { | ||||||
|                 // First check if the completion needs grading.
 |                 // First check if the completion needs grading.
 | ||||||
|  | @ -106,13 +106,12 @@ class gradingscanner | ||||||
|                 $grade = $this->gi->get_final($userid); |                 $grade = $this->gi->get_final($userid); | ||||||
|                 if (!is_numeric($grade->finalgrade) && empty($grade->finalgrade)) { |                 if (!is_numeric($grade->finalgrade) && empty($grade->finalgrade)) { | ||||||
|                     //skip.
 |                     //skip.
 | ||||||
|                 } else |                 } else { | ||||||
|                 { |  | ||||||
|                     //compare grade to minimum grade.
 |                     //compare grade to minimum grade.
 | ||||||
|                     if ($this->grade_passed($grade)) { |                     if ($this->grade_passed($grade)) { | ||||||
|                         $completed_pass++; |                         $completedpass++; | ||||||
|                     } else { |                     } else { | ||||||
|                         $completed_fail++; |                         $completedfail++; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | @ -121,8 +120,8 @@ class gradingscanner | ||||||
|         return [ |         return [ | ||||||
|             'ungraded' => $ungraded, |             'ungraded' => $ungraded, | ||||||
|             'completed' => $completed, |             'completed' => $completed, | ||||||
|             'completed_pass' => $completed_pass, |             'completed_pass' => $completedpass, | ||||||
|             'completed_fail' => $completed_fail, |             'completed_fail' => $completedfail, | ||||||
|             'students' => count($students), |             'students' => count($students), | ||||||
|         ]; |         ]; | ||||||
| 
 | 
 | ||||||
|  | @ -139,8 +138,7 @@ class gradingscanner | ||||||
|             $gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]); |             $gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]); | ||||||
|         } else if ($this->gi->grademin == 0) { |         } else if ($this->gi->grademin == 0) { | ||||||
|             $gradecfg = $DB->get_record($table, ["grade_points"=>$this->gi->grademax]); |             $gradecfg = $DB->get_record($table, ["grade_points"=>$this->gi->grademax]); | ||||||
|         } else |         } else { | ||||||
|         { |  | ||||||
|             $gradecfg = null; |             $gradecfg = null; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -33,12 +33,12 @@ class bistate_aggregator extends \local_treestudyplan\aggregator { | ||||||
|     public const DEPRECATED = false; |     public const DEPRECATED = false; | ||||||
|     private const DEFAULT_CONDITION = "50"; |     private const DEFAULT_CONDITION = "50"; | ||||||
| 
 | 
 | ||||||
|     private $thresh_excellent = 1.0;            // Minimum fraction that must be completed to aggregate as excellent (usually 1.0).
 |     private $threshexcellent = 1.0;            // Minimum fraction that must be completed to aggregate as excellent (usually 1.0).
 | ||||||
|     private $thresh_good = 0.8;                 // Minimum fraction that must be completed to aggregate as good.
 |     private $threshgood = 0.8;                 // Minimum fraction that must be completed to aggregate as good.
 | ||||||
|     private $thresh_completed = 0.66;           // Minimum fraction that must be completed to aggregate as completed.
 |     private $threshcompleted = 0.66;           // Minimum fraction that must be completed to aggregate as completed.
 | ||||||
|     private $use_failed = True;                 // Support failed completion yes/no.
 |     private $usefailed = True;                 // Support failed completion yes/no.
 | ||||||
|     private $thresh_progress = 0.33;              // Minimum fraction that must be failed to aggregate as failed instead of progress.
 |     private $threshprogress = 0.33;              // Minimum fraction that must be failed to aggregate as failed instead of progress.
 | ||||||
|     private $accept_pending_as_submitted = False;  // Also count ungraded but submitted .
 |     private $acceptpending_as_submitted = False;  // Also count ungraded but submitted .
 | ||||||
| 
 | 
 | ||||||
|     public function __construct($configstr) { |     public function __construct($configstr) { | ||||||
|         // allow public constructor for testing purposes.
 |         // allow public constructor for testing purposes.
 | ||||||
|  | @ -104,10 +104,10 @@ class bistate_aggregator extends \local_treestudyplan\aggregator { | ||||||
| 
 | 
 | ||||||
|         // return te following conditions.
 |         // return te following conditions.
 | ||||||
|         // Possible states:.
 |         // Possible states:.
 | ||||||
|         // - completion::EXCELLENT  - At least $thresh_excellent fraction of goals are complete and all required goals are met.
 |         // - completion::EXCELLENT  - At least $threshexcellent fraction of goals are complete and all required goals are met.
 | ||||||
|         // - completion::GOOD       - At least $thresh_good fraction of goals are complete and all required goals are met.
 |         // - completion::GOOD       - At least $threshgood fraction of goals are complete and all required goals are met.
 | ||||||
|         // - completion::COMPLETED  - At least $thresh_complete fraction of goals are completed and all required goals are met.
 |         // - completion::COMPLETED  - At least $threshcomplete fraction of goals are completed and all required goals are met.
 | ||||||
|         // - completion::FAILED     - At least $thresh_progress fraction of goals is not failed.
 |         // - completion::FAILED     - At least $threshprogress fraction of goals is not failed.
 | ||||||
|         // - completion::INCOMPLETE - No goals have been started.
 |         // - completion::INCOMPLETE - No goals have been started.
 | ||||||
|         // - completion::PROGRESS   - All other states.
 |         // - completion::PROGRESS   - All other states.
 | ||||||
| 
 | 
 | ||||||
|  | @ -118,33 +118,33 @@ class bistate_aggregator extends \local_treestudyplan\aggregator { | ||||||
|         $failed = 0; |         $failed = 0; | ||||||
|         $started = 0; |         $started = 0; | ||||||
| 
 | 
 | ||||||
|         $total_required = 0; |         $totalrequired = 0; | ||||||
|         $required_met = 0; |         $requiredmet = 0; | ||||||
| 
 | 
 | ||||||
|         $MIN_PROGRESS = ($this->accept_pending_as_submitted)?completion::PENDING:completion::PROGRESS; |         $MINPROGRESS = ($this->accept_pending_as_submitted)?completion::PENDING:completion::PROGRESS; | ||||||
| 
 | 
 | ||||||
|         foreach ($completions as $index => $c) { |         foreach ($completions as $index => $c) { | ||||||
| 
 | 
 | ||||||
|             $completed += ($c >= completion::COMPLETED)?1:0; |             $completed += ($c >= completion::COMPLETED)?1:0; | ||||||
|             $progress  += ($c >= $MIN_PROGRESS)?1:0; |             $progress  += ($c >= $MINPROGRESS)?1:0; | ||||||
|             $failed    += ($c <= completion::FAILED)?1:0; |             $failed    += ($c <= completion::FAILED)?1:0; | ||||||
|         } |         } | ||||||
|         $started = $progress + $failed; |         $started = $progress + $failed; | ||||||
|         $allrequiredmet = ($required_met >= $total_required); |         $allrequiredmet = ($requiredmet >= $totalrequired); | ||||||
| 
 | 
 | ||||||
|         $fraction_completed = ($total >0)?(floatval($completed)/floatval($total)):0.0; |         $fractioncompleted = ($total >0)?(floatval($completed)/floatval($total)):0.0; | ||||||
|         $fraction_progress  = ($total >0)?(floatval($progress)/floatval($total)):0.0; |         $fractionprogress  = ($total >0)?(floatval($progress)/floatval($total)):0.0; | ||||||
|         $fraction_failed    = ($total >0)?(floatval($failed)/floatval($total)):0.0; |         $fractionfailed    = ($total >0)?(floatval($failed)/floatval($total)):0.0; | ||||||
|         $fraction_started   = ($total >0)?(floatval($started)/floatval($total)):0.0; |         $fractionstarted   = ($total >0)?(floatval($started)/floatval($total)):0.0; | ||||||
| 
 | 
 | ||||||
|         if ($total == 0) { |         if ($total == 0) { | ||||||
|             return completion::INCOMPLETE; |             return completion::INCOMPLETE; | ||||||
|         } |         } | ||||||
|         if ($fraction_completed >= $this->thresh_excellent && $allrequiredmet) { |         if ($fractioncompleted >= $this->thresh_excellent && $allrequiredmet) { | ||||||
|             return completion::EXCELLENT; |             return completion::EXCELLENT; | ||||||
|         } else if ($fraction_completed >= $this->thresh_good && $allrequiredmet) { |         } else if ($fractioncompleted >= $this->thresh_good && $allrequiredmet) { | ||||||
|             return completion::GOOD; |             return completion::GOOD; | ||||||
|         } else if ($fraction_completed >= $this->thresh_completed && $allrequiredmet) { |         } else if ($fractioncompleted >= $this->thresh_completed && $allrequiredmet) { | ||||||
|             return completion::COMPLETED; |             return completion::COMPLETED; | ||||||
|         } else if ($started == 0) { |         } else if ($started == 0) { | ||||||
|             return completion::INCOMPLETE; |             return completion::INCOMPLETE; | ||||||
|  | @ -239,8 +239,7 @@ class bistate_aggregator extends \local_treestudyplan\aggregator { | ||||||
|                 $gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]); |                 $gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]); | ||||||
|             } else if ($gradeitem->grademin == 0) { |             } else if ($gradeitem->grademin == 0) { | ||||||
|                 $gradecfg = $DB->get_record($table, ["grade_points"=>$gradeitem->grademax]); |                 $gradecfg = $DB->get_record($table, ["grade_points"=>$gradeitem->grademax]); | ||||||
|             } else |             } else { | ||||||
|             { |  | ||||||
|                 $gradecfg = null; |                 $gradecfg = null; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -32,7 +32,7 @@ use \local_treestudyplan\debug; | ||||||
| 
 | 
 | ||||||
| class core_aggregator extends \local_treestudyplan\aggregator { | class core_aggregator extends \local_treestudyplan\aggregator { | ||||||
|     public const DEPRECATED = false; |     public const DEPRECATED = false; | ||||||
|     private $accept_pending_as_submitted = False;  // Also count ungraded but submitted .
 |     private $acceptpending_as_submitted = False;  // Also count ungraded but submitted .
 | ||||||
| 
 | 
 | ||||||
|     public function __construct($configstr) { |     public function __construct($configstr) { | ||||||
|         // allow public constructor for testing purposes.
 |         // allow public constructor for testing purposes.
 | ||||||
|  | @ -192,8 +192,7 @@ class core_aggregator extends \local_treestudyplan\aggregator { | ||||||
|                 $gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]); |                 $gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]); | ||||||
|             } else if ($gradeitem->grademin == 0) { |             } else if ($gradeitem->grademin == 0) { | ||||||
|                 $gradecfg = $DB->get_record($table, ["grade_points"=>$gradeitem->grademax]); |                 $gradecfg = $DB->get_record($table, ["grade_points"=>$gradeitem->grademax]); | ||||||
|             } else |             } else { | ||||||
|             { |  | ||||||
|                 $gradecfg = null; |                 $gradecfg = null; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -40,19 +40,19 @@ class tristate_aggregator extends \local_treestudyplan\aggregator { | ||||||
|     protected function aggregate_completion(array $a, $condition = "50") { |     protected function aggregate_completion(array $a, $condition = "50") { | ||||||
|         if (in_array($condition, ['ALL', '67', '50', 'ANY'])) { |         if (in_array($condition, ['ALL', '67', '50', 'ANY'])) { | ||||||
|             // condition is one of the valid conditions.
 |             // condition is one of the valid conditions.
 | ||||||
|             $c_completed = 0; |             $ccompleted = 0; | ||||||
|             $c_excellent = 0; |             $cexcellent = 0; | ||||||
|             $c_progress = 0; |             $cprogress = 0; | ||||||
|             $c_pending = 0; |             $cpending = 0; | ||||||
|             $count = sizeof($a); |             $count = sizeof($a); | ||||||
| 
 | 
 | ||||||
|             if ($count > 0) { |             if ($count > 0) { | ||||||
| 
 | 
 | ||||||
|                 foreach ($a as $c) { |                 foreach ($a as $c) { | ||||||
|                     $c_progress += ($c>=completion::PROGRESS)?1:0; |                     $cprogress += ($c>=completion::PROGRESS)?1:0; | ||||||
|                     $c_completed += ($c>=completion::COMPLETED)?1:0; |                     $ccompleted += ($c>=completion::COMPLETED)?1:0; | ||||||
|                     $c_excellent += ($c>=completion::EXCELLENT)?1:0; |                     $cexcellent += ($c>=completion::EXCELLENT)?1:0; | ||||||
|                     $c_pending += ($c>=completion::PENDING)?1:0; |                     $cpending += ($c>=completion::PENDING)?1:0; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 $required = [ |                 $required = [ | ||||||
|  | @ -62,16 +62,16 @@ class tristate_aggregator extends \local_treestudyplan\aggregator { | ||||||
|                     'ANY' => 1, |                     'ANY' => 1, | ||||||
|                     ][$condition]; |                     ][$condition]; | ||||||
| 
 | 
 | ||||||
|                 if ($c_excellent >= $required) { |                 if ($cexcellent >= $required) { | ||||||
|                     return completion::EXCELLENT; |                     return completion::EXCELLENT; | ||||||
|                 } else if ($c_completed >= $required) { |                 } else if ($ccompleted >= $required) { | ||||||
|                     return completion::COMPLETED; |                     return completion::COMPLETED; | ||||||
|                 } else { |                 } else { | ||||||
|                     // Return PROGRESS if one or more completions are COMPLETED or EXCELLENT, but the aggregation margin is not met.
 |                     // Return PROGRESS if one or more completions are COMPLETED or EXCELLENT, but the aggregation margin is not met.
 | ||||||
|                     // state PROGRESS will not carry on if aggregations are chained.
 |                     // state PROGRESS will not carry on if aggregations are chained.
 | ||||||
|                     if ($c_progress > 0) { |                     if ($cprogress > 0) { | ||||||
|                         return completion::PROGRESS; |                         return completion::PROGRESS; | ||||||
|                     } else if ($c_pending > 0) { |                     } else if ($cpending > 0) { | ||||||
|                         return completion::PENDING; |                         return completion::PENDING; | ||||||
|                     } else { |                     } else { | ||||||
|                         return completion::INCOMPLETE; |                         return completion::INCOMPLETE; | ||||||
|  | @ -80,8 +80,7 @@ class tristate_aggregator extends \local_treestudyplan\aggregator { | ||||||
|             } else { |             } else { | ||||||
|                 return completion::INCOMPLETE; |                 return completion::INCOMPLETE; | ||||||
|             } |             } | ||||||
|         } else |         } else { | ||||||
|         { |  | ||||||
|             // indeterminable, return null.
 |             // indeterminable, return null.
 | ||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -184,8 +184,7 @@ class gradegenerator { | ||||||
|                 $gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]); |                 $gradecfg = $DB->get_record($table, ["scale_id"=>$scale->id]); | ||||||
|             } else if ($gi->grademin == 0) { |             } else if ($gi->grademin == 0) { | ||||||
|                 $gradecfg = $DB->get_record($table, ["grade_points"=>$gi->grademax]); |                 $gradecfg = $DB->get_record($table, ["grade_points"=>$gi->grademax]); | ||||||
|             } else |             } else { | ||||||
|             { |  | ||||||
|                 $gradecfg = null; |                 $gradecfg = null; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ require_once($CFG->dirroot.'/webservice/lib.php'); | ||||||
| class webservicehelper { | class webservicehelper { | ||||||
|     /** @var \context_system */ |     /** @var \context_system */ | ||||||
|     private static $systemcontext = null; |     private static $systemcontext = null; | ||||||
|     private static $validated_contexts = []; |     private static $validatedcontexts = []; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Test for capability in the given context for the current user and throw a \webservice_access_exception if not |      * Test for capability in the given context for the current user and throw a \webservice_access_exception if not | ||||||
|  | @ -120,7 +120,7 @@ class webservicehelper { | ||||||
|     public static function find_context($contextid): \context{ |     public static function find_context($contextid): \context{ | ||||||
|         if (isset($contextid) && is_int($contextid) && $contextid > 0) { |         if (isset($contextid) && is_int($contextid) && $contextid > 0) { | ||||||
| 
 | 
 | ||||||
|             if (!in_array($contextid, self::$validated_contexts)) { // Cache the context and make sure it is only validated once...
 |             if (!in_array($contextid, self::$validatedcontexts)) { // Cache the context and make sure it is only validated once...
 | ||||||
|                 try { |                 try { | ||||||
|                     $context = \context::instance_by_id($contextid); |                     $context = \context::instance_by_id($contextid); | ||||||
|                 } |                 } | ||||||
|  | @ -129,9 +129,9 @@ class webservicehelper { | ||||||
|                 } |                 } | ||||||
|                 // Validate the found context.
 |                 // Validate the found context.
 | ||||||
|                 \external_api::validate_context($context); |                 \external_api::validate_context($context); | ||||||
|                 self::$validated_contexts[$contextid] = $context; |                 self::$validatedcontexts[$contextid] = $context; | ||||||
|             } |             } | ||||||
|             return self::$validated_contexts[$contextid]; |             return self::$validatedcontexts[$contextid]; | ||||||
|         } else{ |         } else{ | ||||||
|             return static::system_context(); // This function ensures the system context is validated just once this call.
 |             return static::system_context(); // This function ensures the system context is validated just once this call.
 | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -54,22 +54,22 @@ class assign_scanner extends scanner_base { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     public function count_ungraded($course_userids=[]) { |     public function count_ungraded($courseuserids=[]) { | ||||||
|         $ungraded = $this->get_ungraded_submissions(); |         $ungraded = $this->get_ungraded_submissions(); | ||||||
| 
 | 
 | ||||||
|         if (count($course_userids) > 0) { |         if (count($courseuserids) > 0) { | ||||||
|             $ungraded = array_intersect($ungraded, $course_userids); |             $ungraded = array_intersect($ungraded, $courseuserids); | ||||||
|         } |         } | ||||||
|         return count($ungraded); |         return count($ungraded); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function count_graded($course_userids=[]) { |     public function count_graded($courseuserids=[]) { | ||||||
|         $ungraded = $this->get_ungraded_submissions(); |         $ungraded = $this->get_ungraded_submissions(); | ||||||
|         $graded = $this->get_graded_users(); |         $graded = $this->get_graded_users(); | ||||||
| 
 | 
 | ||||||
|         if (count($course_userids) > 0) { |         if (count($courseuserids) > 0) { | ||||||
|             $ungraded = array_intersect($ungraded, $course_userids); |             $ungraded = array_intersect($ungraded, $courseuserids); | ||||||
|             $graded = array_intersect($graded, $course_userids); |             $graded = array_intersect($graded, $courseuserids); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // determine how many id's have a grade, but also an ungraded submission.
 |         // determine how many id's have a grade, but also an ungraded submission.
 | ||||||
|  |  | ||||||
|  | @ -43,8 +43,8 @@ class quiz_scanner extends scanner_base { | ||||||
|         $submissions = []; |         $submissions = []; | ||||||
|         foreach ($rs as $r) { |         foreach ($rs as $r) { | ||||||
|             // Now, check if .
 |             // Now, check if .
 | ||||||
|             $maxstate_sql = "SELECT MAX(qas.sequencenumber) FROM {question_attempt_steps} qas WHERE qas.questionattemptid = {$r->attempt_id}"; |             $maxstatesql = "SELECT MAX(qas.sequencenumber) FROM {question_attempt_steps} qas WHERE qas.questionattemptid = {$r->attempt_id}"; | ||||||
|             $max = $DB->get_field_sql($maxstate_sql); |             $max = $DB->get_field_sql($maxstatesql); | ||||||
|             if ($r->sequencenumber == $max) { |             if ($r->sequencenumber == $max) { | ||||||
|                 $submissions[$r->userid] = true; // set array index based on user id, to avoid checking if value is in array.
 |                 $submissions[$r->userid] = true; // set array index based on user id, to avoid checking if value is in array.
 | ||||||
|             } |             } | ||||||
|  | @ -53,15 +53,15 @@ class quiz_scanner extends scanner_base { | ||||||
|         return array_keys($submissions); |         return array_keys($submissions); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function count_ungraded($course_userids=[]) { |     public function count_ungraded($courseuserids=[]) { | ||||||
|         $ungraded = $this->get_ungraded_submissions(); |         $ungraded = $this->get_ungraded_submissions(); | ||||||
|         if (count($course_userids) > 0) { |         if (count($courseuserids) > 0) { | ||||||
|             $ungraded = array_intersect($ungraded, $course_userids); |             $ungraded = array_intersect($ungraded, $courseuserids); | ||||||
|         } |         } | ||||||
|         return count($ungraded); |         return count($ungraded); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function count_graded($course_userids=[]) { |     public function count_graded($courseuserids=[]) { | ||||||
|         // count all users who submitted one or more finished tests.
 |         // count all users who submitted one or more finished tests.
 | ||||||
|         global $DB; |         global $DB; | ||||||
|         $sql = "SELECT DISTINCT g.userid
 |         $sql = "SELECT DISTINCT g.userid
 | ||||||
|  | @ -72,8 +72,8 @@ class quiz_scanner extends scanner_base { | ||||||
| 
 | 
 | ||||||
|         $graded = $DB->get_fieldset_sql($sql); |         $graded = $DB->get_fieldset_sql($sql); | ||||||
| 
 | 
 | ||||||
|         if (count($course_userids) > 0) { |         if (count($courseuserids) > 0) { | ||||||
|             $graded = array_intersect($graded, $course_userids); |             $graded = array_intersect($graded, $courseuserids); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return count($graded); |         return count($graded); | ||||||
|  |  | ||||||
|  | @ -31,9 +31,9 @@ abstract class scanner_base { | ||||||
|         $this->gi = $gi; |         $this->gi = $gi; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public abstract function count_ungraded($course_userids=[]); |     public abstract function count_ungraded($courseuserids=[]); | ||||||
| 
 | 
 | ||||||
|     public abstract function count_graded($course_userids=[]); |     public abstract function count_graded($courseuserids=[]); | ||||||
| 
 | 
 | ||||||
|     public abstract function has_ungraded_submission($userid); |     public abstract function has_ungraded_submission($userid); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -175,10 +175,10 @@ class provider implements   \core_privacy\local\metadata\provider, | ||||||
|         // find studyplans in context.
 |         // find studyplans in context.
 | ||||||
|         if ($context->contextlevel == CONTEXT_COURSECAT) { |         if ($context->contextlevel == CONTEXT_COURSECAT) { | ||||||
|             $sql = "SELECT s.id FROM {local_treestudyplan} WHERE ( a.user_id = :userid AND s.context_id = :contextid)"; |             $sql = "SELECT s.id FROM {local_treestudyplan} WHERE ( a.user_id = :userid AND s.context_id = :contextid)"; | ||||||
|             $plan_ids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id]); |             $planids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id]); | ||||||
| 
 | 
 | ||||||
|             foreach ($plan_ids as $plan_id) { |             foreach ($planids as $planid) { | ||||||
|                 $DB->delete_records("local_treestudyplan_user", ["studyplan_id" => $plan_id]); |                 $DB->delete_records("local_treestudyplan_user", ["studyplan_id" => $planid]); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -198,10 +198,10 @@ class provider implements   \core_privacy\local\metadata\provider, | ||||||
|             if ($context->contextlevel == CONTEXT_SYSTEM) { |             if ($context->contextlevel == CONTEXT_SYSTEM) { | ||||||
|                 $sql = "SELECT s.id FROM {local_treestudyplan} INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
 |                 $sql = "SELECT s.id FROM {local_treestudyplan} INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
 | ||||||
|                         WHERE ( a.user_id = :userid AND ( s.context_id IS NULL OR s.context_id == 0 OR s.context_id = :contextid))";
 |                         WHERE ( a.user_id = :userid AND ( s.context_id IS NULL OR s.context_id == 0 OR s.context_id = :contextid))";
 | ||||||
|                 $plan_ids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id, "userid" => $user->id]); |                 $planids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id, "userid" => $user->id]); | ||||||
| 
 | 
 | ||||||
|                 foreach ($plan_ids as $plan_id) { |                 foreach ($planids as $planid) { | ||||||
|                     $DB->delete_records("local_treestudyplan_user", ["studyplan_id" => $plan_id, "user_id" => $user->id]); |                     $DB->delete_records("local_treestudyplan_user", ["studyplan_id" => $planid, "user_id" => $user->id]); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 // Also delete all invitations for this user.
 |                 // Also delete all invitations for this user.
 | ||||||
|  | @ -210,10 +210,10 @@ class provider implements   \core_privacy\local\metadata\provider, | ||||||
|             } else if ($context->contextlevel == CONTEXT_COURSECAT) { |             } else if ($context->contextlevel == CONTEXT_COURSECAT) { | ||||||
|                 $sql = "SELECT s.id FROM {local_treestudyplan} INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
 |                 $sql = "SELECT s.id FROM {local_treestudyplan} INNER JOIN {local_treestudyplan_user} a ON a.studyplan_id = s.id
 | ||||||
|                         WHERE ( a.user_id = :userid AND s.context_id = :contextid)";
 |                         WHERE ( a.user_id = :userid AND s.context_id = :contextid)";
 | ||||||
|                 $plan_ids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id, "userid" => $user->id]); |                 $planids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id, "userid" => $user->id]); | ||||||
| 
 | 
 | ||||||
|                 foreach ($plan_ids as $plan_id) { |                 foreach ($planids as $planid) { | ||||||
|                     $DB->delete_records("local_treestudyplan_user", ["studyplan_id" => $plan_id, "user_id" => $user->id]); |                     $DB->delete_records("local_treestudyplan_user", ["studyplan_id" => $planid, "user_id" => $user->id]); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | @ -263,12 +263,12 @@ class provider implements   \core_privacy\local\metadata\provider, | ||||||
|         $users = $userlist->get_userids(); |         $users = $userlist->get_userids(); | ||||||
|         list($userinsql, $userinparams) = $DB->get_in_or_equal($users, SQL_PARAMS_NAMED, 'user'); |         list($userinsql, $userinparams) = $DB->get_in_or_equal($users, SQL_PARAMS_NAMED, 'user'); | ||||||
| 
 | 
 | ||||||
|         $plan_ids = []; |         $planids = []; | ||||||
|         if ($context->contextlevel == CONTEXT_SYSTEM) { |         if ($context->contextlevel == CONTEXT_SYSTEM) { | ||||||
|             // Determine the relevant plan_ids for this context.
 |             // Determine the relevant plan_ids for this context.
 | ||||||
|             $sql = "SELECT s.id FROM {local_treestudyplan}
 |             $sql = "SELECT s.id FROM {local_treestudyplan}
 | ||||||
|                     WHERE ( s.context_id IS NULL OR s.context_id == 0 OR s.context_id = :contextid)) ";
 |                     WHERE ( s.context_id IS NULL OR s.context_id == 0 OR s.context_id = :contextid)) ";
 | ||||||
|             $plan_ids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id, ]); |             $planids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id, ]); | ||||||
|             // If plan ids not empty, they will be processed later.
 |             // If plan ids not empty, they will be processed later.
 | ||||||
| 
 | 
 | ||||||
|             // Also delete all invitations for these users.
 |             // Also delete all invitations for these users.
 | ||||||
|  | @ -278,14 +278,14 @@ class provider implements   \core_privacy\local\metadata\provider, | ||||||
|         } else if ($context->contextlevel == CONTEXT_COURSECAT) { |         } else if ($context->contextlevel == CONTEXT_COURSECAT) { | ||||||
|             $sql = "SELECT s.id FROM {local_treestudyplan}
 |             $sql = "SELECT s.id FROM {local_treestudyplan}
 | ||||||
|                     WHERE (s.context_id = :contextid)";
 |                     WHERE (s.context_id = :contextid)";
 | ||||||
|             $plan_ids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id, ]); |             $planids = $DB->get_fieldset_sql($sql, ["contextid"=>$context->id, ]); | ||||||
|             // If plan ids not empty, they will be processed later.
 |             // If plan ids not empty, they will be processed later.
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Now delete the studyplan associations if relevant.
 |         // Now delete the studyplan associations if relevant.
 | ||||||
|         if (count($plan_ids) >0 && count($users) >0) { |         if (count($planids) >0 && count($users) >0) { | ||||||
| 
 | 
 | ||||||
|             list($planinsql, $planinputparams) = $DB->get_in_or_equal($plan_ids, SQL_PARAMS_NAMED, 'plan'); |             list($planinsql, $planinputparams) = $DB->get_in_or_equal($planids, SQL_PARAMS_NAMED, 'plan'); | ||||||
|             $params = $userinparams+$planinputparams; |             $params = $userinparams+$planinputparams; | ||||||
|             $sql = "user_id {$userinsql} and studyplan_id {$planinsql}"; |             $sql = "user_id {$userinsql} and studyplan_id {$planinsql}"; | ||||||
|             $DB->delete_records_select('local_treestudyplan_user', $sql, $params); |             $DB->delete_records_select('local_treestudyplan_user', $sql, $params); | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ class studyitem { | ||||||
| 
 | 
 | ||||||
|     public const TABLE = "local_treestudyplan_item"; |     public const TABLE = "local_treestudyplan_item"; | ||||||
| 
 | 
 | ||||||
|     private static $STUDYITEM_CACHE = []; |     private static $STUDYITEMCACHE = []; | ||||||
|     private $r; // Holds database record.
 |     private $r; // Holds database record.
 | ||||||
|     private $id; |     private $id; | ||||||
| 
 | 
 | ||||||
|  | @ -57,10 +57,10 @@ class studyitem { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function findById($id): self { |     public static function findById($id): self { | ||||||
|         if (!array_key_exists($id, self::$STUDYITEM_CACHE)) { |         if (!array_key_exists($id, self::$STUDYITEMCACHE)) { | ||||||
|             self::$STUDYITEM_CACHE[$id] = new self($id); |             self::$STUDYITEMCACHE[$id] = new self($id); | ||||||
|         } |         } | ||||||
|         return self::$STUDYITEM_CACHE[$id]; |         return self::$STUDYITEMCACHE[$id]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -187,18 +187,18 @@ class studyitem { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         // Add incoming and outgoing connection info.
 |         // Add incoming and outgoing connection info.
 | ||||||
|         $conn_out = studyitemconnection::find_outgoing($this->id); |         $connout = studyitemconnection::find_outgoing($this->id); | ||||||
| 
 | 
 | ||||||
|         if ($mode == "export") { |         if ($mode == "export") { | ||||||
|             foreach ($conn_out as $c) { |             foreach ($connout as $c) { | ||||||
|                 $model["connections"][] = $c->to_id(); |                 $model["connections"][] = $c->to_id(); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             foreach ($conn_out as $c) { |             foreach ($connout as $c) { | ||||||
|                 $model['connections']['out'][$c->to_id()] = $c->model(); |                 $model['connections']['out'][$c->to_id()] = $c->model(); | ||||||
|             } |             } | ||||||
|             $conn_in = studyitemconnection::find_incoming($this->id); |             $connin = studyitemconnection::find_incoming($this->id); | ||||||
|             foreach ($conn_in as $c) { |             foreach ($connin as $c) { | ||||||
|                 $model['connections']['in'][$c->from_id()] = $c->model(); |                 $model['connections']['in'][$c->from_id()] = $c->model(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | @ -268,8 +268,7 @@ class studyitem { | ||||||
| 
 | 
 | ||||||
|         if ($DB->count_records(self::TABLE, ['continuation_id' => $this->id]) > 0) { |         if ($DB->count_records(self::TABLE, ['continuation_id' => $this->id]) > 0) { | ||||||
|             return success::fail('Cannot remove: item is referenced by another item'); |             return success::fail('Cannot remove: item is referenced by another item'); | ||||||
|         } else |         } else { | ||||||
|         { |  | ||||||
|             // delete al related connections to this item.
 |             // delete al related connections to this item.
 | ||||||
|             studyitemconnection::clear($this->id); |             studyitemconnection::clear($this->id); | ||||||
|             // delete all grade inclusion references to this item.
 |             // delete all grade inclusion references to this item.
 | ||||||
|  | @ -381,8 +380,8 @@ class studyitem { | ||||||
| 
 | 
 | ||||||
|         // Add continuation_info if available.
 |         // Add continuation_info if available.
 | ||||||
|         if (self::exists($this->r->continuation_id)) { |         if (self::exists($this->r->continuation_id)) { | ||||||
|             $c_item = self::findById($this->r->continuation_id); |             $citem = self::findById($this->r->continuation_id); | ||||||
|             $model['continuation'] = $c_item->link_model($userid); |             $model['continuation'] = $citem->link_model($userid); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Add course if available.
 |         // Add course if available.
 | ||||||
|  | @ -392,12 +391,12 @@ class studyitem { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Add incoming and outgoing connection info.
 |         // Add incoming and outgoing connection info.
 | ||||||
|         $conn_out = studyitemconnection::find_outgoing($this->id); |         $connout = studyitemconnection::find_outgoing($this->id); | ||||||
|         foreach ($conn_out as $c) { |         foreach ($connout as $c) { | ||||||
|             $model['connections']['out'][$c->to_id()] = $c->model(); |             $model['connections']['out'][$c->to_id()] = $c->model(); | ||||||
|         } |         } | ||||||
|         $conn_in = studyitemconnection::find_incoming($this->id); |         $connin = studyitemconnection::find_incoming($this->id); | ||||||
|         foreach ($conn_in as $c) { |         foreach ($connin as $c) { | ||||||
|             $model['connections']['in'][$c->from_id()] = $c->model(); |             $model['connections']['in'][$c->from_id()] = $c->model(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -424,21 +423,21 @@ class studyitem { | ||||||
|                 // Does not need to use aggregator.
 |                 // Does not need to use aggregator.
 | ||||||
|                 // Either true, or the completion of the reference.
 |                 // Either true, or the completion of the reference.
 | ||||||
|                 if (self::exists($this->r->continuation_id)) { |                 if (self::exists($this->r->continuation_id)) { | ||||||
|                     $c_item = self::findById($this->r->continuation_id); |                     $citem = self::findById($this->r->continuation_id); | ||||||
|                     return $c_item->completion($userid); |                     return $citem->completion($userid); | ||||||
|                 } else { |                 } else { | ||||||
|                     return completion::COMPLETED; |                     return completion::COMPLETED; | ||||||
|                 } |                 } | ||||||
|             } else if (in_array(strtolower($this->r->type), ['junction', 'finish'])) { |             } else if (in_array(strtolower($this->r->type), ['junction', 'finish'])) { | ||||||
|                 // completion of the linked items, according to the rule.
 |                 // completion of the linked items, according to the rule.
 | ||||||
|                 $in_completed = []; |                 $incompleted = []; | ||||||
|                 // Retrieve incoming connections.
 |                 // Retrieve incoming connections.
 | ||||||
|                 $incoming = $DB->get_records(studyitemconnection::TABLE, ['to_id' => $this->r->id]); |                 $incoming = $DB->get_records(studyitemconnection::TABLE, ['to_id' => $this->r->id]); | ||||||
|                 foreach ($incoming as $conn) { |                 foreach ($incoming as $conn) { | ||||||
|                     $item = self::findById($conn->from_id); |                     $item = self::findById($conn->from_id); | ||||||
|                     $in_completed[] = $item->completion($userid); |                     $incompleted[] = $item->completion($userid); | ||||||
|                 } |                 } | ||||||
|                 return $this->aggregator->aggregate_junction($in_completed, $this, $userid); |                 return $this->aggregator->aggregate_junction($incompleted, $this, $userid); | ||||||
|             } else if (strtolower($this->r->type) =='badge') { |             } else if (strtolower($this->r->type) =='badge') { | ||||||
|                 global $DB; |                 global $DB; | ||||||
|                 // badge awarded.
 |                 // badge awarded.
 | ||||||
|  | @ -447,10 +446,10 @@ class studyitem { | ||||||
|                     if ($badge->is_issued($userid)) { |                     if ($badge->is_issued($userid)) { | ||||||
|                         if ($badge->can_expire()) { |                         if ($badge->can_expire()) { | ||||||
|                             // get the issued badges and check if any of them have not expired yet.
 |                             // get the issued badges and check if any of them have not expired yet.
 | ||||||
|                             $badges_issued = $DB->get_records("badge_issued", ["badge_id" => $this->r->badge_id, "user_id" => $userid]); |                             $badgesissued = $DB->get_records("badge_issued", ["badge_id" => $this->r->badge_id, "user_id" => $userid]); | ||||||
|                             $notexpired = false; |                             $notexpired = false; | ||||||
|                             $now = time(); |                             $now = time(); | ||||||
|                             foreach ($badges_issued as $bi) { |                             foreach ($badgesissued as $bi) { | ||||||
|                                 if ($bi->dateexpire == null || $bi->dateexpire > $now) { |                                 if ($bi->dateexpire == null || $bi->dateexpire > $now) { | ||||||
|                                     $notexpired = true; |                                     $notexpired = true; | ||||||
|                                     break; |                                     break; | ||||||
|  | @ -476,16 +475,16 @@ class studyitem { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function duplicate($new_line) { |     public function duplicate($newline) { | ||||||
|         global $DB; |         global $DB; | ||||||
|         // clone the database fields.
 |         // clone the database fields.
 | ||||||
|         $fields = clone $this->r; |         $fields = clone $this->r; | ||||||
|         // set new line id.
 |         // set new line id.
 | ||||||
|         unset($fields->id); |         unset($fields->id); | ||||||
|         $fields->line_id = $new_line->id(); |         $fields->line_id = $newline->id(); | ||||||
|         //create new record with the new data.
 |         //create new record with the new data.
 | ||||||
|         $id = $DB->insert_record(self::TABLE, (array)$fields); |         $id = $DB->insert_record(self::TABLE, (array)$fields); | ||||||
|         $new = self::findById($id, $new_line); |         $new = self::findById($id, $newline); | ||||||
| 
 | 
 | ||||||
|         // copy the grading info if relevant.
 |         // copy the grading info if relevant.
 | ||||||
|         $gradables = gradeinfo::list_studyitem_gradables($this); |         $gradables = gradeinfo::list_studyitem_gradables($this); | ||||||
|  |  | ||||||
|  | @ -65,51 +65,51 @@ class studyitemconnection { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     public static function find_outgoing($item_id) { |     public static function find_outgoing($itemid) { | ||||||
|         global $DB; |         global $DB; | ||||||
|         $list = []; |         $list = []; | ||||||
|         $conn_out = $DB->get_records(self::TABLE, ['from_id' => $item_id]); |         $connout = $DB->get_records(self::TABLE, ['from_id' => $itemid]); | ||||||
|         foreach ($conn_out as $c) { |         foreach ($connout as $c) { | ||||||
|             $list[] = new self($c); |             $list[] = new self($c); | ||||||
|         } |         } | ||||||
|         return $list; |         return $list; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function find_incoming($item_id) { |     public static function find_incoming($itemid) { | ||||||
|         global $DB; |         global $DB; | ||||||
|         $list = []; |         $list = []; | ||||||
|         $conn_in = $DB->get_records(self::TABLE, ['to_id' => $item_id]); |         $connin = $DB->get_records(self::TABLE, ['to_id' => $itemid]); | ||||||
|         foreach ($conn_in as $c) { |         foreach ($connin as $c) { | ||||||
|             $list[] = new self($c); |             $list[] = new self($c); | ||||||
|         } |         } | ||||||
|         return $list; |         return $list; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function connect($from_id, $to_id) { |     public static function connect($fromid, $toid) { | ||||||
|         global $DB; |         global $DB; | ||||||
| 
 | 
 | ||||||
|         //check if link already exists.
 |         //check if link already exists.
 | ||||||
| 
 | 
 | ||||||
|         if (!$DB->record_exists(self::TABLE, ['from_id' => $from_id, 'to_id' => $to_id])) { |         if (!$DB->record_exists(self::TABLE, ['from_id' => $fromid, 'to_id' => $toid])) { | ||||||
|             $id = $DB->insert_record(self::TABLE, [ |             $id = $DB->insert_record(self::TABLE, [ | ||||||
|                 'from_id' => $from_id, |                 'from_id' => $fromid, | ||||||
|                 'to_id' => $to_id, |                 'to_id' => $toid, | ||||||
|             ]); |             ]); | ||||||
| 
 | 
 | ||||||
|             return new self($DB->get_record(self::TABLE, ['id' => $id])); |             return new self($DB->get_record(self::TABLE, ['id' => $id])); | ||||||
| 
 | 
 | ||||||
|         } else { |         } else { | ||||||
|             return new self($DB->get_record(self::TABLE, ['from_id' => $from_id, 'to_id' => $to_id])); |             return new self($DB->get_record(self::TABLE, ['from_id' => $fromid, 'to_id' => $toid])); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function disconnect($from_id, $to_id) { |     public static function disconnect($fromid, $toid) { | ||||||
|         global $DB; |         global $DB; | ||||||
| 
 | 
 | ||||||
|         if ($DB->record_exists(self::TABLE, ['from_id' => $from_id, 'to_id' => $to_id])) { |         if ($DB->record_exists(self::TABLE, ['from_id' => $fromid, 'to_id' => $toid])) { | ||||||
|             $DB->delete_records(self::TABLE, [ |             $DB->delete_records(self::TABLE, [ | ||||||
|                 'from_id' => $from_id, |                 'from_id' => $fromid, | ||||||
|                 'to_id' => $to_id, |                 'to_id' => $toid, | ||||||
|             ]); |             ]); | ||||||
| 
 | 
 | ||||||
|             return success::success('Items Disconnected'); |             return success::success('Items Disconnected'); | ||||||
|  |  | ||||||
|  | @ -43,7 +43,7 @@ class studyline { | ||||||
| 
 | 
 | ||||||
|     public const TABLE = "local_treestudyplan_line"; |     public const TABLE = "local_treestudyplan_line"; | ||||||
| 
 | 
 | ||||||
|     private static $STUDYLINE_CACHE = []; |     private static $STUDYLINECACHE = []; | ||||||
| 
 | 
 | ||||||
|     private $r; // Holds database record.
 |     private $r; // Holds database record.
 | ||||||
|     private $id; |     private $id; | ||||||
|  | @ -63,10 +63,10 @@ class studyline { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function findById($id): self { |     public static function findById($id): self { | ||||||
|         if (!array_key_exists($id, self::$STUDYLINE_CACHE)) { |         if (!array_key_exists($id, self::$STUDYLINECACHE)) { | ||||||
|             self::$STUDYLINE_CACHE[$id] = new self($id); |             self::$STUDYLINECACHE[$id] = new self($id); | ||||||
|         } |         } | ||||||
|         return self::$STUDYLINE_CACHE[$id]; |         return self::$STUDYLINECACHE[$id]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private function __construct($id) { |     private function __construct($id) { | ||||||
|  | @ -132,11 +132,11 @@ class studyline { | ||||||
|         // As a safety data integrity measure, if there are any items in a higher slot than currently allowed, .
 |         // As a safety data integrity measure, if there are any items in a higher slot than currently allowed, .
 | ||||||
|         // make sure there are enought slots to account for them.
 |         // make sure there are enought slots to account for them.
 | ||||||
|         // Alternatively, we could ensure that on reduction of slots, the items that no longer have a slot will be removed.
 |         // Alternatively, we could ensure that on reduction of slots, the items that no longer have a slot will be removed.
 | ||||||
|         $max_slot = $DB->get_field_select(studyitem::TABLE, "MAX(slot)", "line_id = :lineid", ['lineid' => $this->id]); |         $maxslot = $DB->get_field_select(studyitem::TABLE, "MAX(slot)", "line_id = :lineid", ['lineid' => $this->id]); | ||||||
|         $num_slots = max($this->page->periods(), $max_slot +1); |         $numslots = max($this->page->periods(), $maxslot +1); | ||||||
| 
 | 
 | ||||||
|         // Create the required amount of slots.
 |         // Create the required amount of slots.
 | ||||||
|         for($i=0; $i < $num_slots+1; $i++) { |         for($i=0; $i < $numslots+1; $i++) { | ||||||
|             if ($mode == "export") { |             if ($mode == "export") { | ||||||
|                 // Export mode does not separate between filter or competency type, since that is determined automatically.
 |                 // Export mode does not separate between filter or competency type, since that is determined automatically.
 | ||||||
|                 $slots = []; |                 $slots = []; | ||||||
|  | @ -180,8 +180,8 @@ class studyline { | ||||||
|             throw new \InvalidArgumentException("parameter 'page_id' missing"); |             throw new \InvalidArgumentException("parameter 'page_id' missing"); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         $page_id = $fields['page_id']; |         $pageid = $fields['page_id']; | ||||||
|         $sqmax = $DB->get_field_select(self::TABLE, "MAX(sequence)", "page_id = :page_id", ['page_id' => $page_id]); |         $sqmax = $DB->get_field_select(self::TABLE, "MAX(sequence)", "page_id = :page_id", ['page_id' => $pageid]); | ||||||
|         $addable = ['page_id', 'name', 'shortname', 'color']; |         $addable = ['page_id', 'name', 'shortname', 'color']; | ||||||
|         $info = ['sequence' => $sqmax+1]; |         $info = ['sequence' => $sqmax+1]; | ||||||
|         foreach ($addable as $f) { |         foreach ($addable as $f) { | ||||||
|  | @ -220,8 +220,7 @@ class studyline { | ||||||
|         // check if this item has study items in it.
 |         // check if this item has study items in it.
 | ||||||
|         if ($DB->count_records(studyitem::TABLE, ['line_id' => $this->id]) > 0) { |         if ($DB->count_records(studyitem::TABLE, ['line_id' => $this->id]) > 0) { | ||||||
|             return success::fail('cannot delete studyline with items'); |             return success::fail('cannot delete studyline with items'); | ||||||
|         } else |         } else { | ||||||
|         { |  | ||||||
|             $DB->delete_records(self::TABLE, ['id' => $this->id]); |             $DB->delete_records(self::TABLE, ['id' => $this->id]); | ||||||
|             return success::success(); |             return success::success(); | ||||||
|         } |         } | ||||||
|  | @ -285,11 +284,11 @@ class studyline { | ||||||
|         // As a safety data integrity measure, if there are any items in a higher slot than currently allowed, .
 |         // As a safety data integrity measure, if there are any items in a higher slot than currently allowed, .
 | ||||||
|         // make sure there are enought slots to account for them.
 |         // make sure there are enought slots to account for them.
 | ||||||
|         // Alternatively, we could ensure that on reduction of slots, the items that no longer have a slot will be removed.
 |         // Alternatively, we could ensure that on reduction of slots, the items that no longer have a slot will be removed.
 | ||||||
|         $max_slot = $DB->get_field_select(studyitem::TABLE, "MAX(slot)", "line_id = :lineid", ['lineid' => $this->id]); |         $maxslot = $DB->get_field_select(studyitem::TABLE, "MAX(slot)", "line_id = :lineid", ['lineid' => $this->id]); | ||||||
|         $num_slots = max($this->page->periods(), $max_slot +1); |         $numslots = max($this->page->periods(), $maxslot +1); | ||||||
| 
 | 
 | ||||||
|         // Create the required amount of slots.
 |         // Create the required amount of slots.
 | ||||||
|         for($i=0; $i < $num_slots+1; $i++) { |         for($i=0; $i < $numslots+1; $i++) { | ||||||
|             if ($i > 0) { |             if ($i > 0) { | ||||||
|                 $slots = [self::SLOTSET_COMPETENCY => [], self::SLOTSET_FILTER => []]; |                 $slots = [self::SLOTSET_COMPETENCY => [], self::SLOTSET_FILTER => []]; | ||||||
|             } else { |             } else { | ||||||
|  | @ -322,14 +321,14 @@ class studyline { | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function duplicate($new_studyplan, &$translation) { |     public function duplicate($newstudyplan, &$translation) { | ||||||
|         global $DB; |         global $DB; | ||||||
| 
 | 
 | ||||||
|         // clone the database fields.
 |         // clone the database fields.
 | ||||||
|         $fields = clone $this->r; |         $fields = clone $this->r; | ||||||
|         // set new studyplan id.
 |         // set new studyplan id.
 | ||||||
|         unset($fields->id); |         unset($fields->id); | ||||||
|         $fields->studyplan_id = $new_studyplan->id(); |         $fields->studyplan_id = $newstudyplan->id(); | ||||||
|         // create new record with the new data.
 |         // create new record with the new data.
 | ||||||
|         $id = $DB->insert_record(self::TABLE, (array)$fields); |         $id = $DB->insert_record(self::TABLE, (array)$fields); | ||||||
|         $new = self::findById($id); |         $new = self::findById($id); | ||||||
|  | @ -375,8 +374,8 @@ class studyline { | ||||||
|                         if (! isset($connections[$item->id()]) || ! is_array($connections[$item->id()])) { |                         if (! isset($connections[$item->id()]) || ! is_array($connections[$item->id()])) { | ||||||
|                             $connections[$item->id()] = []; |                             $connections[$item->id()] = []; | ||||||
|                         } |                         } | ||||||
|                         foreach ($itemmodel["connections"] as $to_id) { |                         foreach ($itemmodel["connections"] as $toid) { | ||||||
|                             $connections[$item->id()][] = $to_id; |                             $connections[$item->id()][] = $toid; | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  | @ -28,15 +28,15 @@ class studyplan { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     const TABLE = "local_treestudyplan"; |     const TABLE = "local_treestudyplan"; | ||||||
|     private static $STUDYPLAN_CACHE = []; |     private static $STUDYPLANCACHE = []; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     private $r; // Holds database record.
 |     private $r; // Holds database record.
 | ||||||
|     private $id; |     private $id; | ||||||
|     private $aggregator; |     private $aggregator; | ||||||
|     private $context = null; // Hold context object once retrieved.
 |     private $context = null; // Hold context object once retrieved.
 | ||||||
|     private $linked_userids = null; // cache lookup of linked users (saves queries).
 |     private $linkeduserids = null; // cache lookup of linked users (saves queries).
 | ||||||
|     private $page_cache = null; |     private $pagecache = null; | ||||||
| 
 | 
 | ||||||
|     public function aggregator() { |     public function aggregator() { | ||||||
|         return $this->aggregator; |         return $this->aggregator; | ||||||
|  | @ -44,10 +44,10 @@ class studyplan { | ||||||
| 
 | 
 | ||||||
|     // Cache constructors to avoid multiple creation events in one session.
 |     // Cache constructors to avoid multiple creation events in one session.
 | ||||||
|     public static function findById($id): self { |     public static function findById($id): self { | ||||||
|         if (!array_key_exists($id, self::$STUDYPLAN_CACHE)) { |         if (!array_key_exists($id, self::$STUDYPLANCACHE)) { | ||||||
|             self::$STUDYPLAN_CACHE[$id] = new self($id); |             self::$STUDYPLANCACHE[$id] = new self($id); | ||||||
|         } |         } | ||||||
|         return self::$STUDYPLAN_CACHE[$id]; |         return self::$STUDYPLANCACHE[$id]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private function __construct($id) { |     private function __construct($id) { | ||||||
|  | @ -290,8 +290,7 @@ class studyplan { | ||||||
| 
 | 
 | ||||||
|         if ($DB->count_records('local_treestudyplan_page', ['studyplan_id' => $this->id]) > 0) { |         if ($DB->count_records('local_treestudyplan_page', ['studyplan_id' => $this->id]) > 0) { | ||||||
|             return success::fail('cannot delete studyplan that still has pages'); |             return success::fail('cannot delete studyplan that still has pages'); | ||||||
|         } else |         } else { | ||||||
|         { |  | ||||||
|             $DB->delete_records('local_treestudyplan', ['id' => $this->id]); |             $DB->delete_records('local_treestudyplan', ['id' => $this->id]); | ||||||
|             return success::success(); |             return success::success(); | ||||||
|         } |         } | ||||||
|  | @ -341,18 +340,18 @@ class studyplan { | ||||||
|                 INNER JOIN {local_treestudyplan_cohort} j ON j.studyplan_id = s.id |                 INNER JOIN {local_treestudyplan_cohort} j ON j.studyplan_id = s.id | ||||||
|                 INNER JOIN {cohort_members} cm ON j.cohort_id = cm.cohortid |                 INNER JOIN {cohort_members} cm ON j.cohort_id = cm.cohortid | ||||||
|                 WHERE cm.userid = :userid";
 |                 WHERE cm.userid = :userid";
 | ||||||
|         $cohort_plan_ids = $DB->get_fieldset_sql($sql, ['userid' => $userid]); |         $cohortplan_ids = $DB->get_fieldset_sql($sql, ['userid' => $userid]); | ||||||
| 
 | 
 | ||||||
|         $sql = "SELECT s.id FROM {local_treestudyplan} s
 |         $sql = "SELECT s.id FROM {local_treestudyplan} s
 | ||||||
|                 INNER JOIN {local_treestudyplan_user} j ON j.studyplan_id = s.id |                 INNER JOIN {local_treestudyplan_user} j ON j.studyplan_id = s.id | ||||||
|                 WHERE j.user_id = :userid";
 |                 WHERE j.user_id = :userid";
 | ||||||
|         $user_plan_ids = $DB->get_fieldset_sql($sql, ['userid' => $userid]); |         $userplan_ids = $DB->get_fieldset_sql($sql, ['userid' => $userid]); | ||||||
| 
 | 
 | ||||||
|         $plans = []; |         $plans = []; | ||||||
|         foreach ($cohort_plan_ids as $id) { |         foreach ($cohortplan_ids as $id) { | ||||||
|             $plans[$id] = self::findById($id); |             $plans[$id] = self::findById($id); | ||||||
|         } |         } | ||||||
|         foreach ($user_plan_ids as $id) { |         foreach ($userplan_ids as $id) { | ||||||
|             if (!array_key_exists($id, $plans)) { |             if (!array_key_exists($id, $plans)) { | ||||||
|                 $plans[$id] = self::findById($id); |                 $plans[$id] = self::findById($id); | ||||||
|             } |             } | ||||||
|  | @ -477,8 +476,8 @@ class studyplan { | ||||||
|         return $model; |         return $model; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function duplicate_plan($plan_id, $name, $shortname) { |     public static function duplicate_plan($planid, $name, $shortname) { | ||||||
|         $ori = self::findById($plan_id); |         $ori = self::findById($planid); | ||||||
|         $new = $ori->duplicate($name, $shortname); |         $new = $ori->duplicate($name, $shortname); | ||||||
|         return $new->simple_model(); |         return $new->simple_model(); | ||||||
|     } |     } | ||||||
|  | @ -538,7 +537,7 @@ class studyplan { | ||||||
|         return $pages; |         return $pages; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function import_studyplan($content, $format="application/json", $context_id=1) { |     public static function import_studyplan($content, $format="application/json", $contextid=1) { | ||||||
|         if ($format != "application/json") { return false;} |         if ($format != "application/json") { return false;} | ||||||
| 
 | 
 | ||||||
|         $content = json_decode($content, true); |         $content = json_decode($content, true); | ||||||
|  | @ -548,7 +547,7 @@ class studyplan { | ||||||
|             $content["studyplan"]["aggregation_config"] = json_encode($content["studyplan"]["aggregation_config"]); |             $content["studyplan"]["aggregation_config"] = json_encode($content["studyplan"]["aggregation_config"]); | ||||||
| 
 | 
 | ||||||
|             // And make sure the context_id is set to the provided context for import.
 |             // And make sure the context_id is set to the provided context for import.
 | ||||||
|             $content["studyplan"]["context_id"] = $context_id; |             $content["studyplan"]["context_id"] = $contextid; | ||||||
| 
 | 
 | ||||||
|             // Create a new plan, based on the given parameters - this is the import studyplan part.
 |             // Create a new plan, based on the given parameters - this is the import studyplan part.
 | ||||||
|             $plan = self::add($content["studyplan"], true); |             $plan = self::add($content["studyplan"], true); | ||||||
|  |  | ||||||
|  | @ -206,8 +206,7 @@ class studyplanpage { | ||||||
| 
 | 
 | ||||||
|         if ($DB->count_records('local_treestudyplan_line', ['page_id' => $this->id]) > 0) { |         if ($DB->count_records('local_treestudyplan_line', ['page_id' => $this->id]) > 0) { | ||||||
|             return success::fail('cannot delete studyplan page that still has studylines'); |             return success::fail('cannot delete studyplan page that still has studylines'); | ||||||
|         } else |         } else { | ||||||
|         { |  | ||||||
|             $DB->delete_records(self::TABLE, ['id' => $this->id]); |             $DB->delete_records(self::TABLE, ['id' => $this->id]); | ||||||
|             return success::success(); |             return success::success(); | ||||||
|         } |         } | ||||||
|  | @ -259,16 +258,16 @@ class studyplanpage { | ||||||
|         return $list; |         return $list; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function duplicate_page($page_id, $name, $shortname) { |     public static function duplicate_page($pageid, $name, $shortname) { | ||||||
|         $ori = self::findById($page_id); |         $ori = self::findById($pageid); | ||||||
|         $new = $ori->duplicate($name, $shortname); |         $new = $ori->duplicate($name, $shortname); | ||||||
|         return $new->simple_model(); |         return $new->simple_model(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function duplicate($new_studyplan) { |     public function duplicate($newstudyplan) { | ||||||
|         // First duplicate the studyplan structure.
 |         // First duplicate the studyplan structure.
 | ||||||
|         $new = studyplanpage::add([ |         $new = studyplanpage::add([ | ||||||
|             'studyplan_id' => $new_studyplan->id(), |             'studyplan_id' => $newstudyplan->id(), | ||||||
|             'fullname' => $this->r->fullname, |             'fullname' => $this->r->fullname, | ||||||
|             'shortname' => $this->r->shortname, |             'shortname' => $this->r->shortname, | ||||||
|             'description' => $this->r->description, |             'description' => $this->r->description, | ||||||
|  | @ -290,9 +289,9 @@ class studyplanpage { | ||||||
|         // now the itemtranslation array contains all of the old child id's as keys and all of the related new ids as values.
 |         // now the itemtranslation array contains all of the old child id's as keys and all of the related new ids as values.
 | ||||||
|         // (feature of the studyline::duplicate function).
 |         // (feature of the studyline::duplicate function).
 | ||||||
|         // use this to recreate the lines in the new plan.
 |         // use this to recreate the lines in the new plan.
 | ||||||
|         foreach (array_keys($itemtranslation) as $item_id) { |         foreach (array_keys($itemtranslation) as $itemid) { | ||||||
|             // copy based on the outgoing connections of each item, to avoid duplicates.
 |             // copy based on the outgoing connections of each item, to avoid duplicates.
 | ||||||
|             $connections  = studyitemconnection::find_outgoing($item_id); |             $connections  = studyitemconnection::find_outgoing($itemid); | ||||||
|             foreach ($connections as $conn) { |             foreach ($connections as $conn) { | ||||||
|                 studyitemconnection::connect($itemtranslation[$conn->from_id], $itemtranslation[$conn->to_id]); |                 studyitemconnection::connect($itemtranslation[$conn->from_id], $itemtranslation[$conn->to_id]); | ||||||
|             } |             } | ||||||
|  | @ -484,7 +483,7 @@ class studyplanpage { | ||||||
| 
 | 
 | ||||||
|     public function import_studylines_model($model) { |     public function import_studylines_model($model) { | ||||||
|         // First attempt to map each studyline model to an existing or new line.
 |         // First attempt to map each studyline model to an existing or new line.
 | ||||||
|         $line_map = []; |         $linemap = []; | ||||||
|         foreach ($model as $ix => $linemodel) { |         foreach ($model as $ix => $linemodel) { | ||||||
|             $line = $this->find_studyline_by_shortname($linemodel["shortname"]); |             $line = $this->find_studyline_by_shortname($linemodel["shortname"]); | ||||||
|             if (empty($line)) { |             if (empty($line)) { | ||||||
|  | @ -493,14 +492,14 @@ class studyplanpage { | ||||||
|             } else { |             } else { | ||||||
|                 //$line->edit($linemodel); // Update the line with the settings from the imported file.
 |                 //$line->edit($linemodel); // Update the line with the settings from the imported file.
 | ||||||
|             } |             } | ||||||
|             $line_map[$ix] = $line; |             $linemap[$ix] = $line; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // next, let each study line import the study items.
 |         // next, let each study line import the study items.
 | ||||||
|         $itemtranslation = []; |         $itemtranslation = []; | ||||||
|         $connections = []; |         $connections = []; | ||||||
|         foreach ($model as $ix => $linemodel) { |         foreach ($model as $ix => $linemodel) { | ||||||
|             $line_map[$ix]->import_studyitems($linemodel["slots"], $itemtranslation, $connections); |             $linemap[$ix]->import_studyitems($linemodel["slots"], $itemtranslation, $connections); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Finally, create the links between the study items.
 |         // Finally, create the links between the study items.
 | ||||||
|  |  | ||||||
|  | @ -53,16 +53,16 @@ class studyplanservice extends \external_api | ||||||
|         return new \external_multiple_structure( studyplan::simple_structure() ); |         return new \external_multiple_structure( studyplan::simple_structure() ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function list_studyplans($context_id = 0) { |     public static function list_studyplans($contextid = 0) { | ||||||
|         global $CFG, $DB; |         global $CFG, $DB; | ||||||
| 
 | 
 | ||||||
|         // Check if the user has the correct permissions for this context.
 |         // Check if the user has the correct permissions for this context.
 | ||||||
|         $context = webservicehelper::find_context($context_id); |         $context = webservicehelper::find_context($contextid); | ||||||
|         webservicehelper::require_capabilities([self::CAP_EDIT, self::CAP_VIEW], $context); |         webservicehelper::require_capabilities([self::CAP_EDIT, self::CAP_VIEW], $context); | ||||||
| 
 | 
 | ||||||
|         // Now list all the studyplans in the relevant context.
 |         // Now list all the studyplans in the relevant context.
 | ||||||
|         $list = []; |         $list = []; | ||||||
|         $studyplans = studyplan::find_all($context_id); |         $studyplans = studyplan::find_all($contextid); | ||||||
|         foreach ($studyplans as $studyplan) { |         foreach ($studyplans as $studyplan) { | ||||||
|             $list[] = $studyplan->simple_model(); |             $list[] = $studyplan->simple_model(); | ||||||
|         } |         } | ||||||
|  | @ -144,9 +144,9 @@ class studyplanservice extends \external_api | ||||||
|         return studyplan::simple_structure(); |         return studyplan::simple_structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function add_studyplan($name, $shortname, $idnumber, $description, $periods, $startdate, $enddate, $aggregation="bistate", $aggregation_config='', $context_id=0) { |     public static function add_studyplan($name, $shortname, $idnumber, $description, $periods, $startdate, $enddate, $aggregation="bistate", $aggregationconfig='', $contextid=0) { | ||||||
|         // Check if we have the proper rights for the requested context.
 |         // Check if we have the proper rights for the requested context.
 | ||||||
|         $context = webservicehelper::find_context($context_id); |         $context = webservicehelper::find_context($contextid); | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, $context); |         webservicehelper::require_capabilities(self::CAP_EDIT, $context); | ||||||
| 
 | 
 | ||||||
|         $o = studyplan::add([ |         $o = studyplan::add([ | ||||||
|  | @ -158,8 +158,8 @@ class studyplanservice extends \external_api | ||||||
|             'startdate' => $startdate, |             'startdate' => $startdate, | ||||||
|             'enddate' => empty($enddate)?null:$enddate, |             'enddate' => empty($enddate)?null:$enddate, | ||||||
|             'aggregation' => $aggregation, |             'aggregation' => $aggregation, | ||||||
|             'aggregation_config' => $aggregation_config, |             'aggregation_config' => $aggregationconfig, | ||||||
|             'context_id' => $context_id, |             'context_id' => $contextid, | ||||||
|         ]); |         ]); | ||||||
|         return $o->simple_model(); |         return $o->simple_model(); | ||||||
|     } |     } | ||||||
|  | @ -190,9 +190,9 @@ class studyplanservice extends \external_api | ||||||
|         return studyplan::simple_structure(); |         return studyplan::simple_structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function edit_studyplan($id, $name, $shortname, $idnumber, $description, $periods, $startdate, $enddate, $aggregation="bistate", $aggregation_config='', $context_id=0) { |     public static function edit_studyplan($id, $name, $shortname, $idnumber, $description, $periods, $startdate, $enddate, $aggregation="bistate", $aggregationconfig='', $contextid=0) { | ||||||
|         // Validate access in the intended context.
 |         // Validate access in the intended context.
 | ||||||
|         $context = webservicehelper::find_context($context_id); |         $context = webservicehelper::find_context($contextid); | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, $context, false); // do not validate the context in this case, just check the permissions.
 |         webservicehelper::require_capabilities(self::CAP_EDIT, $context, false); // do not validate the context in this case, just check the permissions.
 | ||||||
| 
 | 
 | ||||||
|         $o = studyplan::findById($id); |         $o = studyplan::findById($id); | ||||||
|  | @ -207,8 +207,8 @@ class studyplanservice extends \external_api | ||||||
|             'startdate' => $startdate, |             'startdate' => $startdate, | ||||||
|             'enddate' => $enddate, |             'enddate' => $enddate, | ||||||
|             'aggregation' => $aggregation, |             'aggregation' => $aggregation, | ||||||
|             'aggregation_config' => $aggregation_config, |             'aggregation_config' => $aggregationconfig, | ||||||
|             'context_id' => $context_id, |             'context_id' => $contextid, | ||||||
|         ]); |         ]); | ||||||
|         return $o->simple_model(); |         return $o->simple_model(); | ||||||
|     } |     } | ||||||
|  | @ -257,13 +257,13 @@ class studyplanservice extends \external_api | ||||||
|         return studyline::editor_structure(); |         return studyline::editor_structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function add_studyline($page_id, $name, $shortname, $color, $sequence) { |     public static function add_studyline($pageid, $name, $shortname, $color, $sequence) { | ||||||
|         // validate if the requesting user has the right to edit the plan in it's current context.
 |         // validate if the requesting user has the right to edit the plan in it's current context.
 | ||||||
|         $page = studyplanpage::findById($page_id); |         $page = studyplanpage::findById($pageid); | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, $page->studyplan()->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, $page->studyplan()->context()); | ||||||
| 
 | 
 | ||||||
|         $o = studyline::add([ |         $o = studyline::add([ | ||||||
|             'page_id' => $page_id, |             'page_id' => $pageid, | ||||||
|             'name' => $name, |             'name' => $name, | ||||||
|             'shortname' => $shortname, |             'shortname' => $shortname, | ||||||
|             'color' => $color, |             'color' => $color, | ||||||
|  | @ -415,11 +415,11 @@ class studyplanservice extends \external_api | ||||||
|         return studyitem::editor_structure(); |         return studyitem::editor_structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function add_studyitem($line_id, $type, $details, $slot=-1, $layer=0) { |     public static function add_studyitem($lineid, $type, $details, $slot=-1, $layer=0) { | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, studyline::findById($line_id)->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, studyline::findById($lineid)->context()); | ||||||
| 
 | 
 | ||||||
|         $o = studyitem::add([ |         $o = studyitem::add([ | ||||||
|             'line_id' => $line_id, |             'line_id' => $lineid, | ||||||
|             'type' => $type, |             'type' => $type, | ||||||
|             //'conditions' => $conditions,.
 |             //'conditions' => $conditions,.
 | ||||||
|             'slot' => $slot, |             'slot' => $slot, | ||||||
|  | @ -450,7 +450,7 @@ class studyplanservice extends \external_api | ||||||
|         return studyitem::editor_structure(); |         return studyitem::editor_structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function edit_studyitem($id, $conditions, $continuation_id=false) { |     public static function edit_studyitem($id, $conditions, $continuationid=false) { | ||||||
| 
 | 
 | ||||||
|         $o = studyitem::findById($id); |         $o = studyitem::findById($id); | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, $o->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, $o->context()); | ||||||
|  | @ -458,8 +458,8 @@ class studyplanservice extends \external_api | ||||||
|         $config = [ |         $config = [ | ||||||
|             'conditions' => $conditions, |             'conditions' => $conditions, | ||||||
|         ]; |         ]; | ||||||
|         if ($continuation_id !== false) { |         if ($continuationid !== false) { | ||||||
|             $config['continuation_id'] = $continuation_id; |             $config['continuation_id'] = $continuationid; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         $o->edit($config); |         $o->edit($config); | ||||||
|  | @ -540,12 +540,12 @@ class studyplanservice extends \external_api | ||||||
|         return studyitemconnection::structure(); |         return studyitemconnection::structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function connect_studyitems($from_id, $to_id) { |     public static function connect_studyitems($fromid, $toid) { | ||||||
|         // Validate permissions.
 |         // Validate permissions.
 | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, studyitem::findById($from_id)->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, studyitem::findById($fromid)->context()); | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, studyitem::findById($to_id)->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, studyitem::findById($toid)->context()); | ||||||
| 
 | 
 | ||||||
|         $o = studyitemconnection::connect($from_id, $to_id); |         $o = studyitemconnection::connect($fromid, $toid); | ||||||
|         return $o->model(); |         return $o->model(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -566,11 +566,11 @@ class studyplanservice extends \external_api | ||||||
|         return success::structure(); |         return success::structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function disconnect_studyitems($from_id, $to_id) { |     public static function disconnect_studyitems($fromid, $toid) { | ||||||
|         // Validate permissions.
 |         // Validate permissions.
 | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, studyitem::findById($from_id)->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, studyitem::findById($fromid)->context()); | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, studyitem::findById($to_id)->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, studyitem::findById($toid)->context()); | ||||||
|         return studyitemconnection::disconnect($from_id, $to_id)->model(); |         return studyitemconnection::disconnect($fromid, $toid)->model(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /**************************** |     /**************************** | ||||||
|  | @ -624,19 +624,19 @@ class studyplanservice extends \external_api | ||||||
|         return success::structure(); |         return success::structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function include_grade($grade_id, $item_id, $include, $required=false) { |     public static function include_grade($gradeid, $itemid, $include, $required=false) { | ||||||
|         global $USER; |         global $USER; | ||||||
| 
 | 
 | ||||||
|         // find related course and course context.
 |         // find related course and course context.
 | ||||||
|         $coursecontext = gradeinfo::getCourseContextById($grade_id); |         $coursecontext = gradeinfo::getCourseContextById($gradeid); | ||||||
|         // do sanity checks.
 |         // do sanity checks.
 | ||||||
|         \external_api::validate_context($coursecontext); |         \external_api::validate_context($coursecontext); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         // check correct capabilities.
 |         // check correct capabilities.
 | ||||||
|         if (has_capability('local/treestudyplan:editstudyplan', studyitem::findById($item_id)->context()) || |         if (has_capability('local/treestudyplan:editstudyplan', studyitem::findById($itemid)->context()) || | ||||||
|            is_enrolled($coursecontext, $USER, 'local/treestudyplan:selectowngradables')) { |            is_enrolled($coursecontext, $USER, 'local/treestudyplan:selectowngradables')) { | ||||||
|             return gradeinfo::include_grade($grade_id, $item_id, $include, $required)->model(); |             return gradeinfo::include_grade($gradeid, $itemid, $include, $required)->model(); | ||||||
|         } else { |         } else { | ||||||
|             return success::fail("Access denied")->model(); |             return success::fail("Access denied")->model(); | ||||||
|         } |         } | ||||||
|  | @ -686,16 +686,16 @@ class studyplanservice extends \external_api | ||||||
|         ])); |         ])); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function force_studyplan_scale($studyplan_id, $scale_id) { |     public static function force_studyplan_scale($studyplanid, $scaleid) { | ||||||
|         global $DB; |         global $DB; | ||||||
|         $dbman = $DB->get_manager(); |         $dbman = $DB->get_manager(); | ||||||
| 
 | 
 | ||||||
|         // Validate permissions.
 |         // Validate permissions.
 | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::findById($studyplan_id)->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::findById($studyplanid)->context()); | ||||||
| 
 | 
 | ||||||
|         $list = []; |         $list = []; | ||||||
|         // check if scaleid is valid.
 |         // check if scaleid is valid.
 | ||||||
|         $scale = \grade_scale::fetch(['id' => $scale_id]); |         $scale = \grade_scale::fetch(['id' => $scaleid]); | ||||||
|         $scale->load_items(); |         $scale->load_items(); | ||||||
| 
 | 
 | ||||||
|         if ($scale) { |         if ($scale) { | ||||||
|  | @ -704,13 +704,13 @@ class studyplanservice extends \external_api | ||||||
|             $scalemax = count($scale->scale_items); |             $scalemax = count($scale->scale_items); | ||||||
| 
 | 
 | ||||||
|             // find studyline id's.
 |             // find studyline id's.
 | ||||||
|             $studyline_ids = $DB->get_fieldset_select(studyline::TABLE, "id", "studyplan_id = :plan_id", ['plan_id' => $studyplan_id]); |             $studylineids = $DB->get_fieldset_select(studyline::TABLE, "id", "studyplan_id = :plan_id", ['plan_id' => $studyplanid]); | ||||||
|             foreach ($studyline_ids as $studyline_id) { |             foreach ($studylineids as $studylineid) { | ||||||
|                 // find id's of studyitems of type course.
 |                 // find id's of studyitems of type course.
 | ||||||
|                 $records = $DB->get_records(studyitem::TABLE, ['line_id' => $studyline_id]); |                 $records = $DB->get_records(studyitem::TABLE, ['line_id' => $studylineid]); | ||||||
| 
 | 
 | ||||||
|                 foreach ($records as $item_r) { |                 foreach ($records as $itemr) { | ||||||
|                     $studyitem = new studyitem($item_r->id); |                     $studyitem = new studyitem($itemr->id); | ||||||
|                     if ($studyitem->isValid() && $studyitem->type() == studyitem::COURSE) { |                     if ($studyitem->isValid() && $studyitem->type() == studyitem::COURSE) { | ||||||
|                         $courseinfo = $studyitem->getcourseinfo(); |                         $courseinfo = $studyitem->getcourseinfo(); | ||||||
|                         $gradables = gradeinfo::list_studyitem_gradables($studyitem); |                         $gradables = gradeinfo::list_studyitem_gradables($studyitem); | ||||||
|  | @ -742,9 +742,9 @@ class studyplanservice extends \external_api | ||||||
|                                 $fieldname = "grade"; |                                 $fieldname = "grade"; | ||||||
|                                 if ($result && $gi->itemtype == "mod" && $dbman->table_exists($tablename)) { |                                 if ($result && $gi->itemtype == "mod" && $dbman->table_exists($tablename)) { | ||||||
|                                     if ($dbman->field_exists($tablename, $fieldname)) { |                                     if ($dbman->field_exists($tablename, $fieldname)) { | ||||||
|                                         $grade_value = intval(0-($scale->id)); |                                         $gradevalue = intval(0-($scale->id)); | ||||||
|                                         try { |                                         try { | ||||||
|                                             $DB->set_field($tablename, $fieldname, $grade_value, ["id" => $gi->iteminstance]); |                                             $DB->set_field($tablename, $fieldname, $gradevalue, ["id" => $gi->iteminstance]); | ||||||
|                                         } |                                         } | ||||||
|                                         catch(\dml_exception $x) { |                                         catch(\dml_exception $x) { | ||||||
|                                             $updated = "fail"; |                                             $updated = "fail"; | ||||||
|  | @ -826,20 +826,20 @@ class studyplanservice extends \external_api | ||||||
|         return success::structure(); |         return success::structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function disable_autoenddate($studyplan_id) { |     public static function disable_autoenddate($studyplanid) { | ||||||
|         global $DB; |         global $DB; | ||||||
| 
 | 
 | ||||||
|         // Validate permissions.
 |         // Validate permissions.
 | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::findById($studyplan_id)->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::findById($studyplanid)->context()); | ||||||
| 
 | 
 | ||||||
|         // find studyline id's.
 |         // find studyline id's.
 | ||||||
|         $studyline_ids = $DB->get_fieldset_select(studyline::TABLE, "id", "studyplan_id = :plan_id", ['plan_id' => $studyplan_id]); |         $studylineids = $DB->get_fieldset_select(studyline::TABLE, "id", "studyplan_id = :plan_id", ['plan_id' => $studyplanid]); | ||||||
|         foreach ($studyline_ids as $studyline_id) { |         foreach ($studylineids as $studylineid) { | ||||||
|             // find id's of studyitems of type course.
 |             // find id's of studyitems of type course.
 | ||||||
|             $records = $DB->get_records(studyitem::TABLE, ['line_id' => $studyline_id]); |             $records = $DB->get_records(studyitem::TABLE, ['line_id' => $studylineid]); | ||||||
| 
 | 
 | ||||||
|             foreach ($records as $item_r) { |             foreach ($records as $itemr) { | ||||||
|                 $studyitem = new studyitem($item_r->id); |                 $studyitem = new studyitem($itemr->id); | ||||||
|                 if ($studyitem->isValid() && $studyitem->type() == studyitem::COURSE) { |                 if ($studyitem->isValid() && $studyitem->type() == studyitem::COURSE) { | ||||||
|                     $record = $DB->get_record("course_format_options", ["courseid" => $studyitem->courseid(), "name" => "automaticenddate"]); |                     $record = $DB->get_record("course_format_options", ["courseid" => $studyitem->courseid(), "name" => "automaticenddate"]); | ||||||
|                     if ($record && $record->value) { |                     if ($record && $record->value) { | ||||||
|  | @ -870,11 +870,11 @@ class studyplanservice extends \external_api | ||||||
|         return studyplan::simple_structure(); |         return studyplan::simple_structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function duplicate_plan($studyplan_id, $name, $shortname) { |     public static function duplicate_plan($studyplanid, $name, $shortname) { | ||||||
|         // Validate permissions.
 |         // Validate permissions.
 | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::findById($studyplan_id)->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::findById($studyplanid)->context()); | ||||||
| 
 | 
 | ||||||
|         return studyplan::duplicate_plan($studyplan_id, $name, $shortname); |         return studyplan::duplicate_plan($studyplanid, $name, $shortname); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /**************************** |     /**************************** | ||||||
|  | @ -894,12 +894,12 @@ class studyplanservice extends \external_api | ||||||
|         return studyplan::export_structure(); |         return studyplan::export_structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function export_plan($studyplan_id, $format="json") { |     public static function export_plan($studyplanid, $format="json") { | ||||||
|         try { |         try { | ||||||
|             // Validate permissions.
 |             // Validate permissions.
 | ||||||
|             webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::findById($studyplan_id)->context()); |             webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::findById($studyplanid)->context()); | ||||||
| 
 | 
 | ||||||
|             $plan = studyplan::findById($studyplan_id); |             $plan = studyplan::findById($studyplanid); | ||||||
|             if ($format == "csv") { |             if ($format == "csv") { | ||||||
|                 // FIXME: Make sure this webservice function gets called for the page instead of the studyplan.
 |                 // FIXME: Make sure this webservice function gets called for the page instead of the studyplan.
 | ||||||
|                 return $plan->pages()[0]->export_page_csv(); |                 return $plan->pages()[0]->export_page_csv(); | ||||||
|  | @ -922,12 +922,12 @@ class studyplanservice extends \external_api | ||||||
|         return studyplan::export_structure(); |         return studyplan::export_structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function export_studylines($studyplan_id) { |     public static function export_studylines($studyplanid) { | ||||||
|         $systemcontext = webservicehelper::system_context(); |         $systemcontext = webservicehelper::system_context(); | ||||||
| 
 | 
 | ||||||
|         try { |         try { | ||||||
|             webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::findById($studyplan_id)->context()); |             webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::findById($studyplanid)->context()); | ||||||
|             $plan = studyplan::findById($studyplan_id); |             $plan = studyplan::findById($studyplanid); | ||||||
|             // FIXME: Make sure this gets called for the page instead of the studyplan.
 |             // FIXME: Make sure this gets called for the page instead of the studyplan.
 | ||||||
|             return $plan->pages()[0]->export_studylines(); |             return $plan->pages()[0]->export_studylines(); | ||||||
|         } |         } | ||||||
|  | @ -953,14 +953,14 @@ class studyplanservice extends \external_api | ||||||
|         return success::structure(); |         return success::structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function import_plan($content, $format="application/json", $context_id=1) { |     public static function import_plan($content, $format="application/json", $contextid=1) { | ||||||
| 
 | 
 | ||||||
|         try { |         try { | ||||||
|             // Validate import context.
 |             // Validate import context.
 | ||||||
|             $context = webservicehelper::find_context($context_id); |             $context = webservicehelper::find_context($contextid); | ||||||
|             webservicehelper::require_capabilities(self::CAP_EDIT, $context); |             webservicehelper::require_capabilities(self::CAP_EDIT, $context); | ||||||
| 
 | 
 | ||||||
|             $result = studyplan::import_studyplan($content, $format, $context_id); |             $result = studyplan::import_studyplan($content, $format, $contextid); | ||||||
|             return (new success($result, "During study plan import"))->model(); |             return (new success($result, "During study plan import"))->model(); | ||||||
|         } |         } | ||||||
|         catch(\webservice_access_exception $x) { |         catch(\webservice_access_exception $x) { | ||||||
|  | @ -980,10 +980,10 @@ class studyplanservice extends \external_api | ||||||
|         return success::structure(); |         return success::structure(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function import_studylines($studyplan_id, $content, $format="application/json") { |     public static function import_studylines($studyplanid, $content, $format="application/json") { | ||||||
| 
 | 
 | ||||||
|         try { |         try { | ||||||
|             $plan = studyplan::findById($studyplan_id); |             $plan = studyplan::findById($studyplanid); | ||||||
|             // Validate import context.
 |             // Validate import context.
 | ||||||
|             webservicehelper::require_capabilities(self::CAP_EDIT, $plan->context()); |             webservicehelper::require_capabilities(self::CAP_EDIT, $plan->context()); | ||||||
| 
 | 
 | ||||||
|  | @ -1130,15 +1130,15 @@ class studyplanservice extends \external_api | ||||||
|          return courseinfo::editor_structure(); |          return courseinfo::editor_structure(); | ||||||
|      } |      } | ||||||
| 
 | 
 | ||||||
|      public static function course_period_timing($period_id, $course_id, $span=1) { |      public static function course_period_timing($periodid, $courseid, $span=1) { | ||||||
|         global $DB; |         global $DB; | ||||||
|         $period = period::findById($period_id); |         $period = period::findById($periodid); | ||||||
|         $periodnr = $period->period(); |         $periodnr = $period->period(); | ||||||
|         $page = $period->page(); |         $page = $period->page(); | ||||||
|         // Check for studyplan edit permissions.
 |         // Check for studyplan edit permissions.
 | ||||||
|         webservicehelper::require_capabilities(self::CAP_EDIT, $page->studyplan()->context()); |         webservicehelper::require_capabilities(self::CAP_EDIT, $page->studyplan()->context()); | ||||||
|         $course = \get_course($course_id); |         $course = \get_course($courseid); | ||||||
|         $coursecontext = \context_course::instance($course_id); |         $coursecontext = \context_course::instance($courseid); | ||||||
| 
 | 
 | ||||||
|         if (webservicehelper::has_capabilities("moodle/course:update", $coursecontext)) { |         if (webservicehelper::has_capabilities("moodle/course:update", $coursecontext)) { | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -41,8 +41,8 @@ class refreshteacherlist extends \core\task\scheduled_task  { | ||||||
|      */ |      */ | ||||||
|     public function execute() { |     public function execute() { | ||||||
|         \mtrace("Ververs lijst met leraren"); |         \mtrace("Ververs lijst met leraren"); | ||||||
|         $teacher_ids = teachingfinder::list_teacher_ids(); |         $teacherids = teachingfinder::list_teacher_ids(); | ||||||
|         foreach ($teacher_ids as $tid) { |         foreach ($teacherids as $tid) { | ||||||
|             $utime = teachingfinder::get_update_time($tid); |             $utime = teachingfinder::get_update_time($tid); | ||||||
|             if (time() - $utime > self::CACHE_TIME) { |             if (time() - $utime > self::CACHE_TIME) { | ||||||
|                 \mtrace("Teacher {$tid} is due for a refresh of the list"); |                 \mtrace("Teacher {$tid} is due for a refresh of the list"); | ||||||
|  |  | ||||||
|  | @ -57,19 +57,19 @@ class teachingfinder { | ||||||
| 
 | 
 | ||||||
|         $sql = "SELECT p.id FROM {local_treestudyplan_page} p
 |         $sql = "SELECT p.id FROM {local_treestudyplan_page} p
 | ||||||
|             WHERE startdate <= NOW() and enddate >= NOW()";
 |             WHERE startdate <= NOW() and enddate >= NOW()";
 | ||||||
|         $page_ids = $DB->get_fieldset_sql($sql, []); |         $pageids = $DB->get_fieldset_sql($sql, []); | ||||||
| 
 | 
 | ||||||
|         // then parse them to see if the user has the grading permission in any of them .
 |         // then parse them to see if the user has the grading permission in any of them .
 | ||||||
|         // (Which would make them a teacher for all intents and purposes).
 |         // (Which would make them a teacher for all intents and purposes).
 | ||||||
| 
 | 
 | ||||||
|         foreach ($page_ids as $page_id) { |         foreach ($pageids as $pageid) { | ||||||
|             $sql = "SELECT i.course_id FROM {local_treestudyplan_item} i
 |             $sql = "SELECT i.course_id FROM {local_treestudyplan_item} i
 | ||||||
|                     INNER JOIN {local_treestudyplan_line} l ON i.line_id = l.id |                     INNER JOIN {local_treestudyplan_line} l ON i.line_id = l.id | ||||||
|                     WHERE l.page_id = :page_id AND i.course_id IS NOT NULL";
 |                     WHERE l.page_id = :page_id AND i.course_id IS NOT NULL";
 | ||||||
|             $course_ids = $DB->get_fieldset_sql($sql, ["page_id" => $page_id]); |             $courseids = $DB->get_fieldset_sql($sql, ["page_id" => $pageid]); | ||||||
| 
 | 
 | ||||||
|             $linked = false; |             $linked = false; | ||||||
|             foreach ($course_ids as $cid) { |             foreach ($courseids as $cid) { | ||||||
|                 $coursecontext =  \context_course::instance($cid); |                 $coursecontext =  \context_course::instance($cid); | ||||||
|                 if (is_enrolled($coursecontext, $userid, 'mod/assign:grade')) { |                 if (is_enrolled($coursecontext, $userid, 'mod/assign:grade')) { | ||||||
|                     $linked = true; |                     $linked = true; | ||||||
|  | @ -78,7 +78,7 @@ class teachingfinder { | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if ($linked) { |             if ($linked) { | ||||||
|                 $list[] = $page_id; |                 $list[] = $pageid; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
|  | @ -87,10 +87,10 @@ class teachingfinder { | ||||||
|         $DB->delete_records(self::TABLE, ["teacher_id"=>$userid]); |         $DB->delete_records(self::TABLE, ["teacher_id"=>$userid]); | ||||||
|         // And add new records for the found studyplans.
 |         // And add new records for the found studyplans.
 | ||||||
|         $now = time(); |         $now = time(); | ||||||
|         foreach ($list as $page_id) { |         foreach ($list as $pageid) { | ||||||
|             // Retrieve the studyplan id from the page.
 |             // Retrieve the studyplan id from the page.
 | ||||||
|             //TODO: Change this when page management is implemented to return the page instead of the plan.
 |             //TODO: Change this when page management is implemented to return the page instead of the plan.
 | ||||||
|             $planid = $DB->get_field("local_treestudyplan_page", "studyplan_id", ["id" => $page_id]); |             $planid = $DB->get_field("local_treestudyplan_page", "studyplan_id", ["id" => $pageid]); | ||||||
|             $DB->insert_record(self::TABLE, ["teacher_id"=>$userid, "studyplan_id"=>$planid, "update_time"=>$now]); |             $DB->insert_record(self::TABLE, ["teacher_id"=>$userid, "studyplan_id"=>$planid, "update_time"=>$now]); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -102,10 +102,10 @@ class teachingfinder { | ||||||
|         return $DB->get_fieldset_sql("SELECT DISTINCT teacher_id FROM {".self::TABLE."}"); |         return $DB->get_fieldset_sql("SELECT DISTINCT teacher_id FROM {".self::TABLE."}"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static function get_update_time($teacher_id): int { |     public static function get_update_time($teacherid): int { | ||||||
|         global $DB; |         global $DB; | ||||||
|         $r = $DB->get_field_sql("SELECT MIN(update_time)FROM {".self::TABLE."} WHERE teacher_id=:teacher_id", |         $r = $DB->get_field_sql("SELECT MIN(update_time)FROM {".self::TABLE."} WHERE teacher_id=:teacher_id", | ||||||
|                                 ["teacher_id" => $teacher_id]); |                                 ["teacher_id" => $teacherid]); | ||||||
|         return (int)($r->update_time); |         return (int)($r->update_time); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -143,8 +143,8 @@ foreach ($plans as $plan) { | ||||||
|                                         if ($gi->itemmodule == "assign") { |                                         if ($gi->itemmodule == "assign") { | ||||||
|                                             // If it is an assignment, submit though that interface .
 |                                             // If it is an assignment, submit though that interface .
 | ||||||
|                                             list($c, $cminfo) = get_course_and_cm_from_instance($gi->iteminstance, $gi->itemmodule); |                                             list($c, $cminfo) = get_course_and_cm_from_instance($gi->iteminstance, $gi->itemmodule); | ||||||
|                                             $cm_ctx = \context_module::instance($cminfo->id); |                                             $cmctx = \context_module::instance($cminfo->id); | ||||||
|                                             $a = new \assign($cm_ctx, $cminfo, $c); |                                             $a = new \assign($cmctx, $cminfo, $c); | ||||||
| 
 | 
 | ||||||
|                                             $ug = $a->get_user_grade($u->id, true); |                                             $ug = $a->get_user_grade($u->id, true); | ||||||
|                                             $ug->grade = grade_floatval($gg->grade); |                                             $ug->grade = grade_floatval($gg->grade); | ||||||
|  | @ -174,8 +174,7 @@ foreach ($plans as $plan) { | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                     } else |                     } else { | ||||||
|                     { |  | ||||||
|                         cli_writeln("      Skipping since it has not started yet"); |                         cli_writeln("      Skipping since it has not started yet"); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								doc.php
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								doc.php
									
									
									
									
									
								
							|  | @ -41,9 +41,9 @@ if (!file_exists($file)) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| $mime = mime_content_type($file); | $mime = mime_content_type($file); | ||||||
| $text_types = ["text/html", "text/plain"]; | $texttypes = ["text/html", "text/plain"]; | ||||||
| 
 | 
 | ||||||
| if ( in_array($mime, $text_types)) { | if ( in_array($mime, $texttypes)) { | ||||||
| 	print $OUTPUT->header(); | 	print $OUTPUT->header(); | ||||||
| 	print file_get_contents($file); | 	print file_get_contents($file); | ||||||
| 	print $OUTPUT->footer(); | 	print $OUTPUT->footer(); | ||||||
|  |  | ||||||
|  | @ -40,8 +40,7 @@ $PAGE->set_context($systemcontext); | ||||||
| if ($update > 0) { | if ($update > 0) { | ||||||
| 	$PAGE->set_title(get_string('invite_desc_edit', 'local_treestudyplan')); | 	$PAGE->set_title(get_string('invite_desc_edit', 'local_treestudyplan')); | ||||||
| 	$PAGE->set_heading(get_string('invite_desc_edit', 'local_treestudyplan')); | 	$PAGE->set_heading(get_string('invite_desc_edit', 'local_treestudyplan')); | ||||||
| } else | } else { | ||||||
| { |  | ||||||
| 	$PAGE->set_title(get_string('invite_desc_new', 'local_treestudyplan')); | 	$PAGE->set_title(get_string('invite_desc_new', 'local_treestudyplan')); | ||||||
| 	$PAGE->set_heading(get_string('invite_desc_new', 'local_treestudyplan')); | 	$PAGE->set_heading(get_string('invite_desc_new', 'local_treestudyplan')); | ||||||
| } | } | ||||||
|  | @ -144,8 +143,7 @@ if ($mform->is_cancelled()) { | ||||||
| 
 | 
 | ||||||
| 	exit; | 	exit; | ||||||
| 	 | 	 | ||||||
| } else | } else { | ||||||
| { |  | ||||||
| 	$data = null; | 	$data = null; | ||||||
| 	if ($unitid > 0) | 	if ($unitid > 0) | ||||||
| 	{ | 	{ | ||||||
|  |  | ||||||
|  | @ -47,12 +47,11 @@ if ($categoryid > 0) { | ||||||
| 	{ | 	{ | ||||||
| 		$studyplancontext = $systemcontext; | 		$studyplancontext = $systemcontext; | ||||||
| 	} | 	} | ||||||
| } else | } else { | ||||||
| { |  | ||||||
| 	// If no context is selected, find the first available one.
 | 	// If no context is selected, find the first available one.
 | ||||||
| 	$available_contexts = courseservice::list_accessible_categories_with_usage("edit"); | 	$availablecontexts = courseservice::list_accessible_categories_with_usage("edit"); | ||||||
| 	$contextid=1; // fallback to system context.
 | 	$contextid=1; // fallback to system context.
 | ||||||
| 	foreach ($available_contexts as $ctx) { | 	foreach ($availablecontexts as $ctx) { | ||||||
| 		if ($ctx->count > 0) { | 		if ($ctx->count > 0) { | ||||||
| 			$contextid = $ctx->ctxid; | 			$contextid = $ctx->ctxid; | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
|  | @ -25,8 +25,7 @@ if (isset($_SERVER['SCRIPT_FILENAME'])) { | ||||||
| 	$root = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME']))); | 	$root = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME']))); | ||||||
| 	error_log("Using {$root}/config.php"); | 	error_log("Using {$root}/config.php"); | ||||||
| 	require_once($root."/config.php"); | 	require_once($root."/config.php"); | ||||||
| } else | } else { | ||||||
| { |  | ||||||
| 	// If not, assume the cwd is not symlinked and proceed as we are used to.
 | 	// If not, assume the cwd is not symlinked and proceed as we are used to.
 | ||||||
| 	require_once("../../config.php"); | 	require_once("../../config.php"); | ||||||
| } | } | ||||||
|  | @ -36,7 +35,7 @@ require_once($CFG->dirroot.'/grade/querylib.php'); | ||||||
| 
 | 
 | ||||||
| use local_treestudyplan; | use local_treestudyplan; | ||||||
| 
 | 
 | ||||||
| $INVITED_URL = "/local/treestudyplan/invited.php"; | $INVITEDURL = "/local/treestudyplan/invited.php"; | ||||||
| 
 | 
 | ||||||
| //admin_externalpage_setup('major');.
 | //admin_externalpage_setup('major');.
 | ||||||
| $systemcontext = context_system::instance(); | $systemcontext = context_system::instance(); | ||||||
|  | @ -80,7 +79,7 @@ print "<tbody>"; | ||||||
| if (count($invites) > 0) { | if (count($invites) > 0) { | ||||||
| 	foreach ($invites as $invite) | 	foreach ($invites as $invite) | ||||||
| 	{ | 	{ | ||||||
| 		$testlink  = $INVITED_URL."?key={$invite->invitekey}"; | 		$testlink  = $INVITEDURL."?key={$invite->invitekey}"; | ||||||
| 		print "<tr data-id='{$invite->id}'>"; | 		print "<tr data-id='{$invite->id}'>"; | ||||||
| 		print "<td data-field='name'>{$invite->name}</td>"; | 		print "<td data-field='name'>{$invite->name}</td>"; | ||||||
| 		print "<td data-field='email'>{$invite->email}</td>"; | 		print "<td data-field='email'>{$invite->email}</td>"; | ||||||
|  | @ -104,8 +103,7 @@ if (count($invites) > 0) { | ||||||
| 
 | 
 | ||||||
| 		print "</td>"; | 		print "</td>"; | ||||||
| 	} | 	} | ||||||
| } else | } else { | ||||||
| { |  | ||||||
| 	print "<tr><td colspan='6'>".get_string('invite_table_empty', 'local_treestudyplan')."</td></tr>"; | 	print "<tr><td colspan='6'>".get_string('invite_table_empty', 'local_treestudyplan')."</td></tr>"; | ||||||
| } | } | ||||||
| print "</tbody></table>"; | print "</tbody></table>"; | ||||||
|  |  | ||||||
|  | @ -54,8 +54,7 @@ if (empty($invite)) { | ||||||
| 	print $OUTPUT->footer(); | 	print $OUTPUT->footer(); | ||||||
| 
 | 
 | ||||||
| 	exit; | 	exit; | ||||||
| } else | } else { | ||||||
| { |  | ||||||
| 	// Load javascripts and specific css.
 | 	// Load javascripts and specific css.
 | ||||||
| 	$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue/bootstrap-vue.css')); | 	$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue/bootstrap-vue.css')); | ||||||
| 	$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css')); | 	$PAGE->requires->css(new moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css')); | ||||||
|  |  | ||||||
							
								
								
									
										19
									
								
								lib.php
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								lib.php
									
									
									
									
									
								
							|  | @ -50,7 +50,7 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) { | ||||||
| 	// (Since the Output API does not easily support inline style tags, adding one through Javascript is easier,.
 | 	// (Since the Output API does not easily support inline style tags, adding one through Javascript is easier,.
 | ||||||
| 	//  and not much more complex than loading a separate stylesheet for each link we want to hide).
 | 	//  and not much more complex than loading a separate stylesheet for each link we want to hide).
 | ||||||
| 	// we will add all the hrefs that should be hidden to this variable below.
 | 	// we will add all the hrefs that should be hidden to this variable below.
 | ||||||
| 	$hide_primary_hrefs = []; | 	$hideprimary_hrefs = []; | ||||||
| 
 | 
 | ||||||
| 	if ($USER->id > 1) // Don't show if user is not logged in (id == 0) or is guest user (id == 1).
 | 	if ($USER->id > 1) // Don't show if user is not logged in (id == 0) or is guest user (id == 1).
 | ||||||
| 	{ | 	{ | ||||||
|  | @ -87,7 +87,7 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) { | ||||||
| 			$navigation->add_node($node, 'mycourses'); | 			$navigation->add_node($node, 'mycourses'); | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			$hide_primary_hrefs[] = "/local/treestudyplan/myreport.php"; | 			$hideprimary_hrefs[] = "/local/treestudyplan/myreport.php"; | ||||||
| 		} | 		} | ||||||
| 		if (	has_capability('local/treestudyplan:viewuserreports', context_system::instance()) | 		if (	has_capability('local/treestudyplan:viewuserreports', context_system::instance()) | ||||||
| 			|| webservicehelper::has_capability_in_any_category('local/treestudyplan:viewuserreports')) | 			|| webservicehelper::has_capability_in_any_category('local/treestudyplan:viewuserreports')) | ||||||
|  | @ -105,7 +105,7 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) { | ||||||
| 			$navigation->add_node($node, 'mycourses'); | 			$navigation->add_node($node, 'mycourses'); | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			$hide_primary_hrefs[] = "/local/treestudyplan/view-plan.php"; | 			$hideprimary_hrefs[] = "/local/treestudyplan/view-plan.php"; | ||||||
| 		} | 		} | ||||||
| 		if (	has_capability('local/treestudyplan:editstudyplan', context_system::instance()) | 		if (	has_capability('local/treestudyplan:editstudyplan', context_system::instance()) | ||||||
| 		  	|| webservicehelper::has_capability_in_any_category('local/treestudyplan:editstudyplan') | 		  	|| webservicehelper::has_capability_in_any_category('local/treestudyplan:editstudyplan') | ||||||
|  | @ -124,13 +124,13 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) { | ||||||
| 			$navigation->add_node($node, 'mycourses'); | 			$navigation->add_node($node, 'mycourses'); | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			$hide_primary_hrefs[] = "/local/treestudyplan/edit-plan.php"; | 			$hideprimary_hrefs[] = "/local/treestudyplan/edit-plan.php"; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
| 		$hide_primary_hrefs[] = "/local/treestudyplan/myreport.php"; | 		$hideprimary_hrefs[] = "/local/treestudyplan/myreport.php"; | ||||||
| 		$hide_primary_hrefs[] = "/local/treestudyplan/edit-plan.php"; | 		$hideprimary_hrefs[] = "/local/treestudyplan/edit-plan.php"; | ||||||
| 		$hide_primary_hrefs[] = "/local/treestudyplan/view-plan.php"; | 		$hideprimary_hrefs[] = "/local/treestudyplan/view-plan.php"; | ||||||
| 	} | 	} | ||||||
| 	// create invitenode node.
 | 	// create invitenode node.
 | ||||||
| 	$invitenode = navigation_node::create( | 	$invitenode = navigation_node::create( | ||||||
|  | @ -146,7 +146,7 @@ function local_treestudyplan_extend_navigation(global_navigation $navigation) { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	// Now using some javascript magic, we'll hide the links that are not accessible.
 | 	// Now using some javascript magic, we'll hide the links that are not accessible.
 | ||||||
| 	$PAGE->requires->js_call_amd('local_treestudyplan/primary-nav-tools', 'hide_primary', [$hide_primary_hrefs]); | 	$PAGE->requires->js_call_amd('local_treestudyplan/primary-nav-tools', 'hide_primary', [$hideprimary_hrefs]); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -292,8 +292,7 @@ function local_treestudyplan_get_cohort_path($cohort) { | ||||||
|         $ctxpath[] = $cohort->name; |         $ctxpath[] = $cohort->name; | ||||||
| 
 | 
 | ||||||
|         return implode(" / ", $ctxpath); |         return implode(" / ", $ctxpath); | ||||||
|     } else |     } else { | ||||||
|     { |  | ||||||
|         return $cohort->name; |         return $cohort->name; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								settings.php
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								settings.php
									
									
									
									
									
								
							|  | @ -146,46 +146,46 @@ if ($hassiteconfig) { | ||||||
| 	 * | 	 * | ||||||
| 	 *************************************/ | 	 *************************************/ | ||||||
| 	 | 	 | ||||||
| 	$page_csync = new admin_settingpage('local_treestudyplan_settings_cohortsync', | 	$pagecsync = new admin_settingpage('local_treestudyplan_settings_cohortsync', | ||||||
| 		get_string('settingspage_csync', 'local_treestudyplan', null, true)); | 		get_string('settingspage_csync', 'local_treestudyplan', null, true)); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	// Description heading.
 | 	// Description heading.
 | ||||||
| 	$page_csync->add(new admin_setting_heading('local_treestudyplan/csync_heading', | 	$pagecsync->add(new admin_setting_heading('local_treestudyplan/csync_heading', | ||||||
| 		get_string('setting_csync_heading', 'local_treestudyplan'), | 		get_string('setting_csync_heading', 'local_treestudyplan'), | ||||||
| 		get_string('settingdesc_csync_heading', 'local_treestudyplan') | 		get_string('settingdesc_csync_heading', 'local_treestudyplan') | ||||||
| 	)); | 	)); | ||||||
| 
 | 
 | ||||||
| 	// Enable/disable cohort sync.
 | 	// Enable/disable cohort sync.
 | ||||||
| 	$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_enable', | 	$pagecsync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_enable', | ||||||
| 		get_string('setting_csync_enable_field', 'local_treestudyplan'), | 		get_string('setting_csync_enable_field', 'local_treestudyplan'), | ||||||
| 		get_string('settingdesc_csync_enable_field', 'local_treestudyplan'), | 		get_string('settingdesc_csync_enable_field', 'local_treestudyplan'), | ||||||
| 		false | 		false | ||||||
| 	)); | 	)); | ||||||
| 
 | 
 | ||||||
| 	// Enable/disable autoremove.
 | 	// Enable/disable autoremove.
 | ||||||
| 	$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_autoremove', | 	$pagecsync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_autoremove', | ||||||
| 		get_string('setting_csync_autoremove_field', 'local_treestudyplan'), | 		get_string('setting_csync_autoremove_field', 'local_treestudyplan'), | ||||||
| 		get_string('settingdesc_csync_autoremove_field', 'local_treestudyplan'), | 		get_string('settingdesc_csync_autoremove_field', 'local_treestudyplan'), | ||||||
| 		true | 		true | ||||||
| 	)); | 	)); | ||||||
| 
 | 
 | ||||||
| 	// Enable/disable remembering previously added cohort syncs so they're not automatically deleted.
 | 	// Enable/disable remembering previously added cohort syncs so they're not automatically deleted.
 | ||||||
| 	$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_remember_manual_csync', | 	$pagecsync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_remember_manual_csync', | ||||||
| 		get_string('setting_csync_remember_manual_csync_field', 'local_treestudyplan'), | 		get_string('setting_csync_remember_manual_csync_field', 'local_treestudyplan'), | ||||||
| 		get_string('settingdesc_csync_remember_manual_csync_field', 'local_treestudyplan'), | 		get_string('settingdesc_csync_remember_manual_csync_field', 'local_treestudyplan'), | ||||||
| 		true | 		true | ||||||
| 	)); | 	)); | ||||||
| 
 | 
 | ||||||
| 	// Enable/disable group creation.
 | 	// Enable/disable group creation.
 | ||||||
| 	$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_creategroup', | 	$pagecsync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_creategroup', | ||||||
| 		get_string('setting_csync_creategroup_field', 'local_treestudyplan'), | 		get_string('setting_csync_creategroup_field', 'local_treestudyplan'), | ||||||
| 		get_string('settingdesc_csync_creategroup_field', 'local_treestudyplan'), | 		get_string('settingdesc_csync_creategroup_field', 'local_treestudyplan'), | ||||||
| 		true | 		true | ||||||
| 	)); | 	)); | ||||||
| 
 | 
 | ||||||
| 	// Sync users too yes/no?.
 | 	// Sync users too yes/no?.
 | ||||||
| 	$page_csync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_users', | 	$pagecsync->add(new admin_setting_configcheckbox('local_treestudyplan/csync_users', | ||||||
| 		get_string('setting_csync_users_field', 'local_treestudyplan'), | 		get_string('setting_csync_users_field', 'local_treestudyplan'), | ||||||
| 		get_string('settingdesc_csync_users_field', 'local_treestudyplan'), | 		get_string('settingdesc_csync_users_field', 'local_treestudyplan'), | ||||||
| 		true | 		true | ||||||
|  | @ -196,14 +196,14 @@ if ($hassiteconfig) { | ||||||
| 		$options = get_default_enrol_roles(context_system::instance()); | 		$options = get_default_enrol_roles(context_system::instance()); | ||||||
| 		$student = get_archetype_roles('student'); | 		$student = get_archetype_roles('student'); | ||||||
| 		$student = reset($student); | 		$student = reset($student); | ||||||
| 		$page_csync->add(new admin_setting_configselect('local_treestudyplan/csync_roleid', | 		$pagecsync->add(new admin_setting_configselect('local_treestudyplan/csync_roleid', | ||||||
| 		get_string('setting_csync_role_field', 'local_treestudyplan'), | 		get_string('setting_csync_role_field', 'local_treestudyplan'), | ||||||
| 		get_string('settingdesc_csync_role_field', 'local_treestudyplan'), | 		get_string('settingdesc_csync_role_field', 'local_treestudyplan'), | ||||||
| 		$student->id ?? null, $options)); | 		$student->id ?? null, $options)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Add settings page2 to the admin settings category.
 | 	// Add settings page2 to the admin settings category.
 | ||||||
| 	$ADMIN->add('local_treestudyplan', $page_csync); | 	$ADMIN->add('local_treestudyplan', $pagecsync); | ||||||
| 
 | 
 | ||||||
| 	/************************************** | 	/************************************** | ||||||
| 	 * | 	 * | ||||||
|  |  | ||||||
|  | @ -47,12 +47,11 @@ if ($categoryid > 0) { | ||||||
| 	{ | 	{ | ||||||
| 		$studyplancontext = $systemcontext; | 		$studyplancontext = $systemcontext; | ||||||
| 	} | 	} | ||||||
| } else | } else { | ||||||
| { |  | ||||||
| 	// If no context is selected, find the first available one.
 | 	// If no context is selected, find the first available one.
 | ||||||
| 	$available_contexts = courseservice::list_accessible_categories_with_usage("view"); | 	$availablecontexts = courseservice::list_accessible_categories_with_usage("view"); | ||||||
| 	$contextid=1; // fallback to system context.
 | 	$contextid=1; // fallback to system context.
 | ||||||
| 	foreach ($available_contexts as $ctx) { | 	foreach ($availablecontexts as $ctx) { | ||||||
| 		if ($ctx->count > 0) { | 		if ($ctx->count > 0) { | ||||||
| 			$contextid = $ctx->ctxid; | 			$contextid = $ctx->ctxid; | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 PMKuipers
						PMKuipers