From d3bbcb6e63a712869c12d0ed4e59d4da3cf63022 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 21 Nov 2024 16:10:05 +0000 Subject: [PATCH 01/26] CTP-4088 Marker view --- block_my_feedback.php | 213 ++++++++++++++++++++++++++++++++-- lang/en/block_my_feedback.php | 8 +- templates/content.mustache | 54 ++++++--- 3 files changed, 245 insertions(+), 30 deletions(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index d1112da..1e7e722 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -14,9 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . + use core\context\user; use core_course\external\course_summary_exporter; +use local_assess_type\assess_type; // TODO - add in requires... use mod_quiz\question\display_options; +require_once($CFG->dirroot . '/mod/assign/locallib.php'); /** * Block definition class for the block_my_feedback plugin. @@ -40,6 +43,9 @@ public function init() { $this->title = get_string('pluginname', 'block_my_feedback'); } else { $this->title = get_string('feedbackfor', 'block_my_feedback').' '.$USER->firstname; + if (self::is_teacher()) { + $this->title = get_string('markingfor', 'block_my_feedback').' '.$USER->firstname; + } } } @@ -59,15 +65,180 @@ public function get_content(): stdClass { $this->content->footer = ''; $template = new stdClass(); - $template->feedback = $this->fetch_feedback($USER); - // Hide the block when no content. - if (!$template->feedback) { - return $this->content; + if (self::is_teacher()) { + // Teacher content. + $template->marking = $this->fetch_marking($USER); + } else { + // Student content. + $template->feedback = $this->fetch_feedback($USER); + $template->showfeedbacktrackerlink = true; + } + + if (isset($template->feedback) || isset($template->marking)) { + $this->content->text = $OUTPUT->render_from_template('block_my_feedback/content', $template); + } + + return $this->content; + } + + + /** + * Return marking for a user. + * + * @param stdClass $user + */ + public function fetch_marking(stdClass $user): ?array { + global $DB, $OUTPUT; + // User courses. + $courses = enrol_get_all_users_courses($user->id, false, ['enddate']); + // Marking. + $marking = []; + + foreach ($courses as $course) { + // Skip hidden courses. + if (!$course->visible) { + continue; + } + // Skip none current course. + if (!self::is_course_current($course)) { + continue; + } + // Skip if no summative assessments. + if (!$summatives = assess_type::get_assess_type_records_by_courseid($course->id, "1")) { + continue; + } + + $modinfo = get_fast_modinfo($course->id); + + foreach ($summatives as $summative) { + + // Check this is a course mod. + if (isset($summative->cmid)) { + $cmid = $summative->cmid; + $mod = $modinfo->get_cm($cmid); + + // Skip hidden mods. + if (!$mod->visible) { + continue; + } + + // Template. + $assess = new stdClass; + $assess->cmid = $cmid; + $assess->modname = $mod->modname; + // Get due date and require marking. + $assess = self::get_mod_data($mod, $assess); + + // Check mod has require marking (only set when there is a due date). + if (isset($assess->requiremarking)) { + // TODO - what is expensive here that we can do after sort and limit? + $assess->name = $mod->name; + $assess->coursename = $course->fullname; + $assess->url = new moodle_url('/mod/'. $mod->modname. '/view.php', ['id' => $cmid]); + $assess->icon = course_summary_exporter::get_course_image($course); + $marking[] = $assess; + } + } + } + } + + // Sort and return data. + if ($marking) { + usort($marking, function ($a, $b) { + return $a->unixtimestamp <=> $b->unixtimestamp; + }); + + return array_slice($marking, 0, 5); + } + return null; + } + + /** + * Return mod data - due date & require marking. + * + * TODO - turnitin, quiz. + * + * @param stdClass $mod + * @param stdClass $course + */ + public function get_mod_data($mod, $assess) { + // Mods have different feilds for due date, and require marking. + switch ($mod->modname) { + case 'assign': + + // Check mod due date is relevant. + $duedate = self::duedate_in_range($mod->customdata['duedate']); + if (!$duedate) { + return false; + } + + // Add dates. + $assess->unixtimestamp = $duedate; + $assess->duedate = date('jS F y', $duedate); + + // Require marking. + $context = context_module::instance($mod->id); + $assignment = new assign($context, $mod, $mod->course); + $assess->requiremarking = $assignment->count_submissions_need_grading(); + if (!$assess->requiremarking) { + return false; + } + $assess->markingurl = new moodle_url('/mod/'. $mod->modname. '/view.php', ['id' => $assess->cmid, 'action' => 'grader']); + // Return template data. + return $assess; + + // TODO - quiz + case 'quiz': + // return 'timeclose'; + return false; + // TODO - turnitin + default: + return false; + } + } + + /** + * Return if course has started (startdate) and has not ended (enddate). + * + * @param stdClass $course + */ + public function is_course_current(stdClass $course): bool { + // Start date. + if ($course->startdate > time()){ + return false; // Before the start date. + } + + // End date. + if (isset($course->enddate)) { + if ($course->enddate == 0) { + return true; // Enddate is set to 0 when no end date, show course. + } + if (time() > $course->enddate){ + return false; // After the end date. + } } + return true; // All good, show course. + } - $this->content->text = $OUTPUT->render_from_template('block_my_feedback/content', $template); - return $this->content; + /** + * Return if a due date in the date range. + * + * @param int $duedate + */ + public function duedate_in_range(int $duedate): ?int { + // Only show dates within a month. + $past = strtotime('-1 month'); + $future = strtotime('+1 month'); + // If due date is too far in the future. + if ($duedate > $future) { + return false; + } + // If due date is too far in the past. + if ($duedate < $past) { + return false; + } + return $duedate; } /** @@ -80,14 +251,14 @@ public function get_content(): stdClass { * @throws dml_exception * @throws moodle_exception */ - public function fetch_feedback($user): array { + public function fetch_feedback($user): ?array { global $DB; $submissions = $this->get_submissions($user); // No feedback. if (!$submissions) { - return []; + return null; } // Template data for mustache. @@ -138,7 +309,11 @@ public function fetch_feedback($user): array { $template->feedback[] = $feedback; } - return $template->feedback; + + if ($template->feedback) { + return $template->feedback; + } + return null; } /** @@ -228,6 +403,26 @@ public function show_quiz_submission(stdClass $submission): bool { return false; } + /** + * Return if user has archetype editingteacher. + * + */ + public static function is_teacher(): bool { + global $DB, $USER; + + // Get id's from role where archetype is editingteacher. + $roles = $DB->get_fieldset('role', 'id', ['archetype' => 'editingteacher']); + + // Check if user has editingteacher role on any courses. + list($roles, $params) = $DB->get_in_or_equal($roles, SQL_PARAMS_NAMED); + $params['userid'] = $USER->id; + $sql = "SELECT id + FROM {role_assignments} + WHERE userid = :userid + AND roleid $roles"; + return $DB->record_exists_sql($sql, $params); + } + /** * Defines in which pages this block can be added. * diff --git a/lang/en/block_my_feedback.php b/lang/en/block_my_feedback.php index 5e7c500..ce5111a 100644 --- a/lang/en/block_my_feedback.php +++ b/lang/en/block_my_feedback.php @@ -24,9 +24,13 @@ $string['feedbackfor'] = 'Feedback for'; $string['feedbackreport'] = "Feedback tracker"; - $string['feedbackreportdescription'] = "Assessments, feedback, and marks from your courses in UCL Moodle."; + $string['feedbackreportdescription'] = "Assessments, feedback, and marks for all your courses in UCL Moodle."; + $string['markingfor'] = 'Marking for'; $string['my_feedback:addinstance'] = 'Add my feedback block'; $string['my_feedback:myaddinstance'] = 'Add my feedback block'; - $string['norecentfeedback'] = "Recent feedback you've received will show here."; $string['pluginname'] = 'My feedback'; $string['privacy:metadata'] = 'My Feedback does not store any personal data.'; + + // Template strings. + $string['t:requiremarking'] = "require marking"; + $string['t:due'] = "Due"; diff --git a/templates/content.mustache b/templates/content.mustache index 5a34765..d0a3b74 100644 --- a/templates/content.mustache +++ b/templates/content.mustache @@ -35,40 +35,56 @@ } }} -{{#feedback}} -
-
+{{! TODO - Lots of duplication here, can we use the same template for marking and feedback? }} +{{#marking}} +
-
+
-
- {{coursename}} - {{activityname}} +
+
+ {{{coursename}}} +
+ {{{name}}} +
+ {{#str}} t:due, block_my_feedback {{/str}} {{duedate}}
-
+
-
- {{#tutorname}}{{.}} · {{/tutorname}} {{date}} -
+
+ {{requiremarking}} {{#str}} t:requiremarking, block_my_feedback {{/str}} +
+
+{{/marking}} -
-
-{{/feedback}} +{{#feedback}} +
+
-{{^feedback}} -

{{#str}} norecentfeedback, block_my_feedback {{/str}}

+
+
+ {{coursename}} +
+ {{activityname}} +
+
+ +
+ {{#tutorname}}{{.}} · {{/tutorname}} {{date}} +
+
{{/feedback}} +{{#showfeedbacktrackerlink}}
- New -
{{#str}} feedbackreport, block_my_feedback {{/str}}
{{#str}} feedbackreportdescription, block_my_feedback {{/str}}
-
\ No newline at end of file +
+{{/showfeedbacktrackerlink}} \ No newline at end of file From 41ff507fb489cb2e44bac88d6565388b2fca72c2 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 21 Nov 2024 16:18:03 +0000 Subject: [PATCH 02/26] CI fixes --- block_my_feedback.php | 12 ++++++------ lang/en/block_my_feedback.php | 5 ++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index 1e7e722..acc4081 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -14,11 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . - use core\context\user; use core_course\external\course_summary_exporter; use local_assess_type\assess_type; // TODO - add in requires... use mod_quiz\question\display_options; + require_once($CFG->dirroot . '/mod/assign/locallib.php'); /** @@ -160,7 +160,7 @@ public function fetch_marking(stdClass $user): ?array { * TODO - turnitin, quiz. * * @param stdClass $mod - * @param stdClass $course + * @param stdClass $assess */ public function get_mod_data($mod, $assess) { // Mods have different feilds for due date, and require marking. @@ -188,11 +188,11 @@ public function get_mod_data($mod, $assess) { // Return template data. return $assess; - // TODO - quiz + // TODO - quiz. case 'quiz': // return 'timeclose'; return false; - // TODO - turnitin + // TODO - turnitin. default: return false; } @@ -205,7 +205,7 @@ public function get_mod_data($mod, $assess) { */ public function is_course_current(stdClass $course): bool { // Start date. - if ($course->startdate > time()){ + if ($course->startdate > time()) { return false; // Before the start date. } @@ -214,7 +214,7 @@ public function is_course_current(stdClass $course): bool { if ($course->enddate == 0) { return true; // Enddate is set to 0 when no end date, show course. } - if (time() > $course->enddate){ + if (time() > $course->enddate) { return false; // After the end date. } } diff --git a/lang/en/block_my_feedback.php b/lang/en/block_my_feedback.php index ce5111a..157c152 100644 --- a/lang/en/block_my_feedback.php +++ b/lang/en/block_my_feedback.php @@ -30,7 +30,6 @@ $string['my_feedback:myaddinstance'] = 'Add my feedback block'; $string['pluginname'] = 'My feedback'; $string['privacy:metadata'] = 'My Feedback does not store any personal data.'; - - // Template strings. - $string['t:requiremarking'] = "require marking"; $string['t:due'] = "Due"; + $string['t:requiremarking'] = "require marking"; + From 515985962065c3289eb9ad06dbb683c1d9711426 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 21 Nov 2024 16:25:11 +0000 Subject: [PATCH 03/26] CI fixes --- block_my_feedback.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index acc4081..981966d 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -19,6 +19,8 @@ use local_assess_type\assess_type; // TODO - add in requires... use mod_quiz\question\display_options; +defined('MOODLE_INTERNAL') || die(); + require_once($CFG->dirroot . '/mod/assign/locallib.php'); /** @@ -79,7 +81,7 @@ public function get_content(): stdClass { $this->content->text = $OUTPUT->render_from_template('block_my_feedback/content', $template); } - return $this->content; + return $this->content; } @@ -184,13 +186,14 @@ public function get_mod_data($mod, $assess) { if (!$assess->requiremarking) { return false; } - $assess->markingurl = new moodle_url('/mod/'. $mod->modname. '/view.php', ['id' => $assess->cmid, 'action' => 'grader']); + $assess->markingurl = new moodle_url('/mod/'. $mod->modname. '/view.php', + ['id' => $assess->cmid, 'action' => 'grader'] + ); // Return template data. return $assess; - // TODO - quiz. + // TODO - quiz - 'timeclose' ?. case 'quiz': - // return 'timeclose'; return false; // TODO - turnitin. default: From efa754c9c7d2738401351d35fbcf86105acdf937 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 21 Nov 2024 16:36:25 +0000 Subject: [PATCH 04/26] CI update --- block_my_feedback.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index 981966d..7b3742b 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -21,7 +21,7 @@ defined('MOODLE_INTERNAL') || die(); -require_once($CFG->dirroot . '/mod/assign/locallib.php'); +require_once(__DIR__ .'/mod/assign/locallib.php'); /** * Block definition class for the block_my_feedback plugin. From fd52f6d40341f451f704415957f199a29df67cf9 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 21 Nov 2024 16:39:08 +0000 Subject: [PATCH 05/26] CI test --- block_my_feedback.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index 7b3742b..26e9add 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -21,8 +21,6 @@ defined('MOODLE_INTERNAL') || die(); -require_once(__DIR__ .'/mod/assign/locallib.php'); - /** * Block definition class for the block_my_feedback plugin. * @@ -165,6 +163,7 @@ public function fetch_marking(stdClass $user): ?array { * @param stdClass $assess */ public function get_mod_data($mod, $assess) { + global $CFG; // Mods have different feilds for due date, and require marking. switch ($mod->modname) { case 'assign': @@ -180,6 +179,7 @@ public function get_mod_data($mod, $assess) { $assess->duedate = date('jS F y', $duedate); // Require marking. + require_once($CFG->dirroot.'/mod/assign/locallib.php'); $context = context_module::instance($mod->id); $assignment = new assign($context, $mod, $mod->course); $assess->requiremarking = $assignment->count_submissions_need_grading(); From b2acb068adb97d034967355ba6cf4c533bd6b18d Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 21 Nov 2024 16:42:34 +0000 Subject: [PATCH 06/26] yup --- block_my_feedback.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index 26e9add..d6dead2 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -19,8 +19,6 @@ use local_assess_type\assess_type; // TODO - add in requires... use mod_quiz\question\display_options; -defined('MOODLE_INTERNAL') || die(); - /** * Block definition class for the block_my_feedback plugin. * From e8b0ba5db7e3aa4014cd565a68320896f4b684dc Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Fri, 22 Nov 2024 15:13:02 +0000 Subject: [PATCH 07/26] CR update --- block_my_feedback.php | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index d6dead2..f7a0e35 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -36,14 +36,12 @@ class block_my_feedback extends block_base { public function init() { global $USER; - // If $USER->firstname is not set yet do not try to use it. if (!isset($USER->firstname)) { $this->title = get_string('pluginname', 'block_my_feedback'); + } else if (self::is_teacher()) { + $this->title = get_string('markingfor', 'block_my_feedback').' '.$USER->firstname; } else { $this->title = get_string('feedbackfor', 'block_my_feedback').' '.$USER->firstname; - if (self::is_teacher()) { - $this->title = get_string('markingfor', 'block_my_feedback').' '.$USER->firstname; - } } } @@ -87,7 +85,6 @@ public function get_content(): stdClass { * @param stdClass $user */ public function fetch_marking(stdClass $user): ?array { - global $DB, $OUTPUT; // User courses. $courses = enrol_get_all_users_courses($user->id, false, ['enddate']); // Marking. @@ -103,7 +100,7 @@ public function fetch_marking(stdClass $user): ?array { continue; } // Skip if no summative assessments. - if (!$summatives = assess_type::get_assess_type_records_by_courseid($course->id, "1")) { + if (!$summatives = assess_type::get_assess_type_records_by_courseid($course->id, 1)) { continue; } @@ -311,10 +308,7 @@ public function fetch_feedback($user): ?array { $template->feedback[] = $feedback; } - if ($template->feedback) { - return $template->feedback; - } - return null; + return $template->feedback ?: null; } /** From 2bbfedb9156b9ee3ddb55c9908ffba3b4e75013b Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Mon, 25 Nov 2024 16:38:14 +0000 Subject: [PATCH 08/26] Add needs marking link --- block_my_feedback.php | 3 --- lang/en/block_my_feedback.php | 2 +- templates/content.mustache | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index f7a0e35..a47653b 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -245,9 +245,6 @@ public function duedate_in_range(int $duedate): ?int { * Return users 5 most recent feedbacks. * @param stdClass $user * @return array feedback items. - * @throws coding_exception - * @throws dml_exception - * @throws moodle_exception */ public function fetch_feedback($user): ?array { global $DB; diff --git a/lang/en/block_my_feedback.php b/lang/en/block_my_feedback.php index 157c152..81b9069 100644 --- a/lang/en/block_my_feedback.php +++ b/lang/en/block_my_feedback.php @@ -31,5 +31,5 @@ $string['pluginname'] = 'My feedback'; $string['privacy:metadata'] = 'My Feedback does not store any personal data.'; $string['t:due'] = "Due"; - $string['t:requiremarking'] = "require marking"; + $string['t:needmarking'] = "need marking"; diff --git a/templates/content.mustache b/templates/content.mustache index d0a3b74..ac131a8 100644 --- a/templates/content.mustache +++ b/templates/content.mustache @@ -53,7 +53,7 @@
- {{requiremarking}} {{#str}} t:requiremarking, block_my_feedback {{/str}} + {{requiremarking}} {{#str}} t:needmarking, block_my_feedback {{/str}}

{{/marking}} From 26b5a1a0012e055ca5e909f24ba1c657e1820bfd Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Mon, 25 Nov 2024 17:15:01 +0000 Subject: [PATCH 09/26] Update past due date --- block_my_feedback.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index a47653b..1452a67 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -226,7 +226,7 @@ public function is_course_current(stdClass $course): bool { */ public function duedate_in_range(int $duedate): ?int { // Only show dates within a month. - $past = strtotime('-1 month'); + $past = strtotime('-2 month'); $future = strtotime('+1 month'); // If due date is too far in the future. if ($duedate > $future) { From da6e014543501ecedb657dc6314b14ce38c7d8a6 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Tue, 26 Nov 2024 14:12:54 +0000 Subject: [PATCH 10/26] Allow for late summer assessments --- block_my_feedback.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index 1452a67..ef47e06 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -212,7 +212,8 @@ public function is_course_current(stdClass $course): bool { if ($course->enddate == 0) { return true; // Enddate is set to 0 when no end date, show course. } - if (time() > $course->enddate) { + $future = strtotime('+3 month'); // Allow for Late summer assessments. + if ($future > $course->enddate) { return false; // After the end date. } } From 95e0d9b5df551e4a20fc493b4462dfd7a5118ea5 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 28 Nov 2024 10:31:56 +0000 Subject: [PATCH 11/26] Refactor template Reduce duplicate code and reuse the same template for feedback and marking. --- block_my_feedback.php | 66 +++++++++++++++++++------------------- templates/content.mustache | 57 +++++++++++++------------------- 2 files changed, 55 insertions(+), 68 deletions(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index ef47e06..55ec92f 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -64,20 +64,38 @@ public function get_content(): stdClass { if (self::is_teacher()) { // Teacher content. - $template->marking = $this->fetch_marking($USER); + $template->mods = $this->fetch_marking($USER); } else { // Student content. - $template->feedback = $this->fetch_feedback($USER); + $template->mods = $this->fetch_feedback($USER); $template->showfeedbacktrackerlink = true; } - if (isset($template->feedback) || isset($template->marking)) { + if (isset($template->mods)) { $this->content->text = $OUTPUT->render_from_template('block_my_feedback/content', $template); } return $this->content; } + /** + * Return if user has archetype editingteacher. + * + */ + public static function is_teacher(): bool { + global $DB, $USER; + // Get id's from role where archetype is editingteacher. + $roles = $DB->get_fieldset('role', 'id', ['archetype' => 'editingteacher']); + + // Check if user has editingteacher role on any courses. + list($roles, $params) = $DB->get_in_or_equal($roles, SQL_PARAMS_NAMED); + $params['userid'] = $USER->id; + $sql = "SELECT id + FROM {role_assignments} + WHERE userid = :userid + AND roleid $roles"; + return $DB->record_exists_sql($sql, $params); + } /** * Return marking for a user. @@ -106,6 +124,7 @@ public function fetch_marking(stdClass $user): ?array { $modinfo = get_fast_modinfo($course->id); + // Loop through assessments for this course. foreach ($summatives as $summative) { // Check this is a course mod. @@ -212,8 +231,9 @@ public function is_course_current(stdClass $course): bool { if ($course->enddate == 0) { return true; // Enddate is set to 0 when no end date, show course. } - $future = strtotime('+3 month'); // Allow for Late summer assessments. - if ($future > $course->enddate) { + // Show course 3 months after end date to allow for UCL late summer assessments. + $cutoffdate = strtotime('+3 month'); + if ($course->enddate > $cutoffdate) { return false; // After the end date. } } @@ -226,15 +246,15 @@ public function is_course_current(stdClass $course): bool { * @param int $duedate */ public function duedate_in_range(int $duedate): ?int { - // Only show dates within a month. - $past = strtotime('-2 month'); - $future = strtotime('+1 month'); - // If due date is too far in the future. - if ($duedate > $future) { + // Only show dates within UCL limits for marking. + $startdate = strtotime('-2 month'); + $cutoffdate = strtotime('+1 month'); + // If due date is beyond cutoff. + if ($duedate > $cutoffdate) { return false; } // If due date is too far in the past. - if ($duedate < $past) { + if ($duedate < $startdate) { return false; } return $duedate; @@ -276,8 +296,8 @@ public function fetch_feedback($user): ?array { $feedback = new stdClass(); $feedback->id = $f->gradeid; $feedback->date = date('jS F', $f->lastmodified); - $feedback->activityname = $f->name; - $feedback->link = new moodle_url('/mod/'.$f->modname.'/view.php', ['id' => $f->cmid]); + $feedback->name = $f->name; + $feedback->url = new moodle_url('/mod/'.$f->modname.'/view.php', ['id' => $f->cmid]); // Course. $course = $DB->get_record('course', ['id' => $f->course]); @@ -396,26 +416,6 @@ public function show_quiz_submission(stdClass $submission): bool { return false; } - /** - * Return if user has archetype editingteacher. - * - */ - public static function is_teacher(): bool { - global $DB, $USER; - - // Get id's from role where archetype is editingteacher. - $roles = $DB->get_fieldset('role', 'id', ['archetype' => 'editingteacher']); - - // Check if user has editingteacher role on any courses. - list($roles, $params) = $DB->get_in_or_equal($roles, SQL_PARAMS_NAMED); - $params['userid'] = $USER->id; - $sql = "SELECT id - FROM {role_assignments} - WHERE userid = :userid - AND roleid $roles"; - return $DB->record_exists_sql($sql, $params); - } - /** * Defines in which pages this block can be added. * diff --git a/templates/content.mustache b/templates/content.mustache index ac131a8..d0155d2 100644 --- a/templates/content.mustache +++ b/templates/content.mustache @@ -15,68 +15,55 @@ @template blocks_my_feedback/content Example context (json): { - "allfeedbackurl": "cgf/intervalurl/", - "nofeedback": 0, - "feedback": [ + "showfeedbacktrackerlink": "true", + "mods": [ { "icon": "moodleurl/icon.png", "coursename": "A course", + "name": "A mod", + "url": "/foo/", + "duedate": "10th Jan 2023", "tutorname": "Bob Smith", "date": "24th March 2023" + "requiremarking": "3", }, - { - "icon": "moodleurl/icon.png", - "coursename": "A course", - "tutorname": "Rob Smith", - "date": "24th April 2023" - } ] } }} -{{! TODO - Lots of duplication here, can we use the same template for marking and feedback? }} -{{#marking}} +{{! Mods for feedback and marking. }} +{{#mods}}
- {{{coursename}}} + {{coursename}}
- {{{name}}} + {{name}} + {{#duedate}}
{{#str}} t:due, block_my_feedback {{/str}} {{duedate}}
+ {{/duedate}}
- -
-{{/marking}} - - -{{#feedback}} -
- -
- -
-
- {{coursename}} -
- {{activityname}} -
-
+
+ {{! Student. }} + {{#date}} + {{#tutorname}}{{.}} · {{/tutorname}} {{date}} + {{/date}} -
- {{#tutorname}}{{.}} · {{/tutorname}} {{date}} + {{! Admin. }} + {{#requiremarking}} + {{requiremarking}} {{#str}} t:needmarking, block_my_feedback {{/str}} + {{/requiremarking}}

-{{/feedback}} +{{/mods}} {{#showfeedbacktrackerlink}}
From adad5288b734791309c849849861a50cb5eaf7fc Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 28 Nov 2024 10:37:01 +0000 Subject: [PATCH 12/26] CI error --- templates/content.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/content.mustache b/templates/content.mustache index d0155d2..60c3e5d 100644 --- a/templates/content.mustache +++ b/templates/content.mustache @@ -26,7 +26,7 @@ "tutorname": "Bob Smith", "date": "24th March 2023" "requiremarking": "3", - }, + } ] } From 20742a4a334b4781781bc91ef04b47869fdde420 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 28 Nov 2024 10:41:44 +0000 Subject: [PATCH 13/26] CI error --- templates/content.mustache | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/templates/content.mustache b/templates/content.mustache index 60c3e5d..455c3e3 100644 --- a/templates/content.mustache +++ b/templates/content.mustache @@ -24,11 +24,10 @@ "url": "/foo/", "duedate": "10th Jan 2023", "tutorname": "Bob Smith", - "date": "24th March 2023" + "date": "24th March 2023", "requiremarking": "3", } ] - } }} From cc69633b4218ab3ec6f9431b0e959524cdbb2bd1 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 28 Nov 2024 12:04:55 +0000 Subject: [PATCH 14/26] CI error --- templates/content.mustache | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/content.mustache b/templates/content.mustache index 455c3e3..cdd2b5d 100644 --- a/templates/content.mustache +++ b/templates/content.mustache @@ -21,11 +21,11 @@ "icon": "moodleurl/icon.png", "coursename": "A course", "name": "A mod", - "url": "/foo/", + "url": "foo.php", "duedate": "10th Jan 2023", "tutorname": "Bob Smith", "date": "24th March 2023", - "requiremarking": "3", + "requiremarking": "3" } ] } From a5fd0827f7b0ff1dafb626dcd354e6a605c98ce7 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 28 Nov 2024 12:46:53 +0000 Subject: [PATCH 15/26] Version bump, dependencies and readme --- README.md | 15 +++++++++++++++ block_my_feedback.php | 2 +- version.php | 7 +++++-- 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..3b15e7a --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# moodle-block_my_feedback + +This block shows students recent feedback across moodle courses. + +It currently supports assignment, quiz, and turnitin. + +It outputs some UCL specific elements which you can remove from mustahce template. + +# Version 2.0 + +For users who's role archetype is editingteacher the block shows a marker view, with summative assessments that require marking. + +The marker view uses https://github.com/ucl-isd/moodle-local_assess_type to get which assessments have been set as summative. + + diff --git a/block_my_feedback.php b/block_my_feedback.php index 55ec92f..96c0ca9 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -16,7 +16,7 @@ use core\context\user; use core_course\external\course_summary_exporter; -use local_assess_type\assess_type; // TODO - add in requires... +use local_assess_type\assess_type; // UCL plugin. use mod_quiz\question\display_options; /** diff --git a/version.php b/version.php index 90886e3..3e8e860 100644 --- a/version.php +++ b/version.php @@ -24,9 +24,12 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2023031400; // The current plugin version (Date: YYYYMMDDXX). -$plugin->release = '1.0'; +$plugin->version = 2024112800; // The current plugin version (Date: YYYYMMDDXX). +$plugin->release = '2.0'; $plugin->maturity = MATURITY_ALPHA; $plugin->requires = 2023042400; // Requires at least Moodle version 4.2. $plugin->component = 'block_my_feedback'; // Full name of the plugin (used for diagnostics). +$plugin->dependencies = [ + 'local_assess_type' => 2024091300, +]; From a3cc72d648ad34976c36700b4dcb742e037a1ca3 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Mon, 2 Dec 2024 09:27:57 +0000 Subject: [PATCH 16/26] CR updates --- .github/workflows/moodle-ci.yml | 4 +++- block_my_feedback.php | 39 +++++++++++++++++---------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml index 9288e8d..4445b06 100644 --- a/.github/workflows/moodle-ci.yml +++ b/.github/workflows/moodle-ci.yml @@ -72,7 +72,9 @@ jobs: echo "NVM_DIR=$HOME/.nvm" >> $GITHUB_ENV - name: Install moodle-plugin-ci - run: moodle-plugin-ci install --plugin ./plugin --db-host=127.0.0.1 + run: | + moodle-plugin-ci add-plugin -b main --clone https://github.com/ucl-isd/moodle-local_assess_type.git + moodle-plugin-ci install --plugin ./plugin --db-host=127.0.0.1 env: DB: ${{ matrix.database }} MOODLE_BRANCH: ${{ matrix.moodle-branch }} diff --git a/block_my_feedback.php b/block_my_feedback.php index 96c0ca9..b3a1f83 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -38,7 +38,7 @@ public function init() { if (!isset($USER->firstname)) { $this->title = get_string('pluginname', 'block_my_feedback'); - } else if (self::is_teacher()) { + } else if ($this->is_teacher()) { $this->title = get_string('markingfor', 'block_my_feedback').' '.$USER->firstname; } else { $this->title = get_string('feedbackfor', 'block_my_feedback').' '.$USER->firstname; @@ -62,7 +62,7 @@ public function get_content(): stdClass { $template = new stdClass(); - if (self::is_teacher()) { + if ($this->is_teacher()) { // Teacher content. $template->mods = $this->fetch_marking($USER); } else { @@ -114,11 +114,11 @@ public function fetch_marking(stdClass $user): ?array { continue; } // Skip none current course. - if (!self::is_course_current($course)) { + if (!$this->is_course_current($course)) { continue; } // Skip if no summative assessments. - if (!$summatives = assess_type::get_assess_type_records_by_courseid($course->id, 1)) { + if (!$summatives = assess_type::get_assess_type_records_by_courseid($course->id, assess_type::ASSESS_TYPE_SUMMATIVE)) { continue; } @@ -128,7 +128,7 @@ public function fetch_marking(stdClass $user): ?array { foreach ($summatives as $summative) { // Check this is a course mod. - if (isset($summative->cmid)) { + if ($summative->cmid != 0) { $cmid = $summative->cmid; $mod = $modinfo->get_cm($cmid); @@ -142,7 +142,7 @@ public function fetch_marking(stdClass $user): ?array { $assess->cmid = $cmid; $assess->modname = $mod->modname; // Get due date and require marking. - $assess = self::get_mod_data($mod, $assess); + $assess = $this->get_mod_data($mod, $assess); // Check mod has require marking (only set when there is a due date). if (isset($assess->requiremarking)) { @@ -173,19 +173,19 @@ public function fetch_marking(stdClass $user): ?array { * * TODO - turnitin, quiz. * - * @param stdClass $mod + * @param cm_info $mod * @param stdClass $assess */ - public function get_mod_data($mod, $assess) { + public function get_mod_data($mod, $assess): ?stdClass { global $CFG; - // Mods have different feilds for due date, and require marking. + // Mods have different fields for due date, and require marking. switch ($mod->modname) { case 'assign': // Check mod due date is relevant. - $duedate = self::duedate_in_range($mod->customdata['duedate']); + $duedate = $this->duedate_in_range($mod->customdata['duedate']); if (!$duedate) { - return false; + return null; } // Add dates. @@ -198,20 +198,21 @@ public function get_mod_data($mod, $assess) { $assignment = new assign($context, $mod, $mod->course); $assess->requiremarking = $assignment->count_submissions_need_grading(); if (!$assess->requiremarking) { - return false; + return null; } $assess->markingurl = new moodle_url('/mod/'. $mod->modname. '/view.php', ['id' => $assess->cmid, 'action' => 'grader'] ); + // Return template data. return $assess; // TODO - quiz - 'timeclose' ?. case 'quiz': - return false; + return null; // TODO - turnitin. default: - return false; + return null; } } @@ -231,10 +232,10 @@ public function is_course_current(stdClass $course): bool { if ($course->enddate == 0) { return true; // Enddate is set to 0 when no end date, show course. } - // Show course 3 months after end date to allow for UCL late summer assessments. - $cutoffdate = strtotime('+3 month'); - if ($course->enddate > $cutoffdate) { - return false; // After the end date. + // Return false if enddate has passed. + // Note - UCL add 3 mouths for late summer assessments, where course can end before assessments are due. + if (time() > strtotime('+3 month', $course->enddate)) { + return false; } } return true; // All good, show course. @@ -247,7 +248,7 @@ public function is_course_current(stdClass $course): bool { */ public function duedate_in_range(int $duedate): ?int { // Only show dates within UCL limits for marking. - $startdate = strtotime('-2 month'); + $startdate = strtotime('-2 month'); // Longer time to try retain overdue marking at the top. $cutoffdate = strtotime('+1 month'); // If due date is beyond cutoff. if ($duedate > $cutoffdate) { From 31227d9d03488ea6636cc4df623306fa868d1707 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Mon, 2 Dec 2024 09:58:01 +0000 Subject: [PATCH 17/26] Comment update --- block_my_feedback.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index b3a1f83..d125f81 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -232,8 +232,8 @@ public function is_course_current(stdClass $course): bool { if ($course->enddate == 0) { return true; // Enddate is set to 0 when no end date, show course. } - // Return false if enddate has passed. - // Note - UCL add 3 mouths for late summer assessments, where course can end before assessments are due. + // Past course enddate. + // Note - UCL add 3 mouths for late summer assessments, so course can end before assessments are due. if (time() > strtotime('+3 month', $course->enddate)) { return false; } @@ -250,11 +250,11 @@ public function duedate_in_range(int $duedate): ?int { // Only show dates within UCL limits for marking. $startdate = strtotime('-2 month'); // Longer time to try retain overdue marking at the top. $cutoffdate = strtotime('+1 month'); - // If due date is beyond cutoff. + // If duedate is beyond cutoff. if ($duedate > $cutoffdate) { return false; } - // If due date is too far in the past. + // If duedate is too far in the past. if ($duedate < $startdate) { return false; } From ab287512adafccff7f60cee16c7f70db20788702 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 5 Dec 2024 20:02:44 +0000 Subject: [PATCH 18/26] template update --- templates/content.mustache | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/templates/content.mustache b/templates/content.mustache index cdd2b5d..577c0e0 100644 --- a/templates/content.mustache +++ b/templates/content.mustache @@ -43,24 +43,21 @@
{{name}} {{#duedate}} -
- {{#str}} t:due, block_my_feedback {{/str}} {{duedate}} +
+ {{#str}} t:due, block_my_feedback {{/str}} {{duedate}} + {{#requiremarking}} + · {{requiremarking}} {{#str}} t:needmarking, block_my_feedback {{/str}} + {{/requiremarking}}
{{/duedate}}
+{{#date}}
- {{! Student. }} - {{#date}} - {{#tutorname}}{{.}} · {{/tutorname}} {{date}} - {{/date}} - - {{! Admin. }} - {{#requiremarking}} - {{requiremarking}} {{#str}} t:needmarking, block_my_feedback {{/str}} - {{/requiremarking}} + {{#tutorname}}{{.}} · {{/tutorname}} {{date}}
+{{/date}}
{{/mods}} From 6f22ed296331d76ddbe02e8a2681c454b7de079b Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 5 Dec 2024 20:17:03 +0000 Subject: [PATCH 19/26] update static / self functions --- block_my_feedback.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index d125f81..b3197d9 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -38,7 +38,7 @@ public function init() { if (!isset($USER->firstname)) { $this->title = get_string('pluginname', 'block_my_feedback'); - } else if ($this->is_teacher()) { + } else if (self::is_teacher()) { $this->title = get_string('markingfor', 'block_my_feedback').' '.$USER->firstname; } else { $this->title = get_string('feedbackfor', 'block_my_feedback').' '.$USER->firstname; @@ -62,7 +62,7 @@ public function get_content(): stdClass { $template = new stdClass(); - if ($this->is_teacher()) { + if (self::is_teacher()) { // Teacher content. $template->mods = $this->fetch_marking($USER); } else { @@ -183,7 +183,7 @@ public function get_mod_data($mod, $assess): ?stdClass { case 'assign': // Check mod due date is relevant. - $duedate = $this->duedate_in_range($mod->customdata['duedate']); + $duedate = self::duedate_in_range($mod->customdata['duedate']); if (!$duedate) { return null; } @@ -221,7 +221,7 @@ public function get_mod_data($mod, $assess): ?stdClass { * * @param stdClass $course */ - public function is_course_current(stdClass $course): bool { + public static function is_course_current(stdClass $course): bool { // Start date. if ($course->startdate > time()) { return false; // Before the start date. @@ -246,7 +246,7 @@ public function is_course_current(stdClass $course): bool { * * @param int $duedate */ - public function duedate_in_range(int $duedate): ?int { + public static function duedate_in_range(int $duedate): ?int { // Only show dates within UCL limits for marking. $startdate = strtotime('-2 month'); // Longer time to try retain overdue marking at the top. $cutoffdate = strtotime('+1 month'); From a4b1038512d8a284bfd50c204bb082347874d971 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 5 Dec 2024 20:31:21 +0000 Subject: [PATCH 20/26] more static / self --- block_my_feedback.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index b3197d9..c821ae8 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -114,7 +114,7 @@ public function fetch_marking(stdClass $user): ?array { continue; } // Skip none current course. - if (!$this->is_course_current($course)) { + if (!self::is_course_current($course)) { continue; } // Skip if no summative assessments. From 67da8207cddf8da3dae4bfa4f8396c82d0dab043 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Thu, 5 Dec 2024 20:35:22 +0000 Subject: [PATCH 21/26] fix spelling in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b15e7a..f9be639 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This block shows students recent feedback across moodle courses. It currently supports assignment, quiz, and turnitin. -It outputs some UCL specific elements which you can remove from mustahce template. +It outputs some UCL specific elements which you can remove from mustache template. # Version 2.0 From b8a5865b9238da4e70c77bca8becbe33543e0177 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Fri, 6 Dec 2024 03:38:42 +0000 Subject: [PATCH 22/26] line clamp names --- templates/content.mustache | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/templates/content.mustache b/templates/content.mustache index 577c0e0..1fa94f6 100644 --- a/templates/content.mustache +++ b/templates/content.mustache @@ -41,7 +41,8 @@
{{coursename}}
- {{name}} + {{name}} + {{#duedate}}
{{#str}} t:due, block_my_feedback {{/str}} {{duedate}} @@ -50,14 +51,14 @@ {{/requiremarking}}
{{/duedate}} -
- -{{#date}} -
- {{#tutorname}}{{.}} · {{/tutorname}} {{date}} + {{#date}} +
+ {{#tutorname}}{{.}} · {{/tutorname}} {{date}} +
+ {{/date}} +
-{{/date}}
{{/mods}} From 551fec063b9d664f7bc4af85a8adaa79b296417e Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Fri, 6 Dec 2024 11:56:44 +0000 Subject: [PATCH 23/26] cr - change this to self where appropriate --- block_my_feedback.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index c821ae8..053e905 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -64,7 +64,7 @@ public function get_content(): stdClass { if (self::is_teacher()) { // Teacher content. - $template->mods = $this->fetch_marking($USER); + $template->mods = self::fetch_marking($USER); } else { // Student content. $template->mods = $this->fetch_feedback($USER); @@ -102,7 +102,7 @@ public static function is_teacher(): bool { * * @param stdClass $user */ - public function fetch_marking(stdClass $user): ?array { + public static function fetch_marking(stdClass $user): ?array { // User courses. $courses = enrol_get_all_users_courses($user->id, false, ['enddate']); // Marking. @@ -142,7 +142,7 @@ public function fetch_marking(stdClass $user): ?array { $assess->cmid = $cmid; $assess->modname = $mod->modname; // Get due date and require marking. - $assess = $this->get_mod_data($mod, $assess); + $assess = self::get_mod_data($mod, $assess); // Check mod has require marking (only set when there is a due date). if (isset($assess->requiremarking)) { @@ -176,7 +176,7 @@ public function fetch_marking(stdClass $user): ?array { * @param cm_info $mod * @param stdClass $assess */ - public function get_mod_data($mod, $assess): ?stdClass { + public static function get_mod_data($mod, $assess): ?stdClass { global $CFG; // Mods have different fields for due date, and require marking. switch ($mod->modname) { From 0f4a30cccfe50d085453292467d42d984b0ba72a Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Tue, 10 Dec 2024 12:07:49 +0000 Subject: [PATCH 24/26] Improve dates --- block_my_feedback.php | 4 ++-- templates/content.mustache | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/block_my_feedback.php b/block_my_feedback.php index 053e905..f01c02e 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -190,7 +190,7 @@ public static function get_mod_data($mod, $assess): ?stdClass { // Add dates. $assess->unixtimestamp = $duedate; - $assess->duedate = date('jS F y', $duedate); + $assess->duedate = date('jS M', $duedate); // Require marking. require_once($CFG->dirroot.'/mod/assign/locallib.php'); @@ -296,7 +296,7 @@ public function fetch_feedback($user): ?array { $feedback = new stdClass(); $feedback->id = $f->gradeid; - $feedback->date = date('jS F', $f->lastmodified); + $feedback->releaseddate = date('jS M', $f->lastmodified); $feedback->name = $f->name; $feedback->url = new moodle_url('/mod/'.$f->modname.'/view.php', ['id' => $f->cmid]); diff --git a/templates/content.mustache b/templates/content.mustache index 1fa94f6..18ed753 100644 --- a/templates/content.mustache +++ b/templates/content.mustache @@ -52,11 +52,11 @@ {{/duedate}} - {{#date}} + {{#releaseddate}}
- {{#tutorname}}{{.}} · {{/tutorname}} {{date}} + {{#tutorname}}{{.}} · {{/tutorname}} {{releaseddate}}
- {{/date}} + {{/releaseddate}}
From 1f5a1889dd2070877c6cbd13370ea2dd7521aece Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Fri, 13 Dec 2024 12:12:18 +0000 Subject: [PATCH 25/26] Check cmid exists in course --- block_my_feedback.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/block_my_feedback.php b/block_my_feedback.php index f01c02e..6e660eb 100644 --- a/block_my_feedback.php +++ b/block_my_feedback.php @@ -123,15 +123,28 @@ public static function fetch_marking(stdClass $user): ?array { } $modinfo = get_fast_modinfo($course->id); + $mods = $modinfo->get_cms(); + // Mod ids array to check cmid exists. + $cmids = []; + foreach ($mods as $mod) { + $cmids[] = $mod->id; + } // Loop through assessments for this course. foreach ($summatives as $summative) { // Check this is a course mod. if ($summative->cmid != 0) { + // Skip mods where cmid is not in the course. + if (!in_array($summative->cmid, $cmids)) { + continue; + } + + // Begin to build mod data for template. $cmid = $summative->cmid; $mod = $modinfo->get_cm($cmid); + // Skip hidden mods. if (!$mod->visible) { continue; From f4c0e27487b18785dd3296ea2d1f59f36adb5182 Mon Sep 17 00:00:00 2001 From: Stuart Lamour Date: Fri, 13 Dec 2024 16:10:06 +0000 Subject: [PATCH 26/26] Update lang string --- lang/en/block_my_feedback.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/en/block_my_feedback.php b/lang/en/block_my_feedback.php index 81b9069..b0903c9 100644 --- a/lang/en/block_my_feedback.php +++ b/lang/en/block_my_feedback.php @@ -31,5 +31,5 @@ $string['pluginname'] = 'My feedback'; $string['privacy:metadata'] = 'My Feedback does not store any personal data.'; $string['t:due'] = "Due"; - $string['t:needmarking'] = "need marking"; + $string['t:needmarking'] = "to mark";