From 58cbaa785bb9d1e9ef6fe109c02932b6489ab02e Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Fri, 23 Aug 2024 13:59:38 +0100 Subject: [PATCH] Fixed bug emailing all students (#531) --- classes/task/email_certificate_task.php | 17 ++--- tests/email_certificate_task_test.php | 82 +++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 7 deletions(-) diff --git a/classes/task/email_certificate_task.php b/classes/task/email_certificate_task.php index e1518ea6..09e6c0ee 100644 --- a/classes/task/email_certificate_task.php +++ b/classes/task/email_certificate_task.php @@ -124,6 +124,7 @@ public function execute() { if (!$fastmoduleinfo->visible) { continue; } + // Do not process an empty certificate. $sql = "SELECT ce.* FROM {customcert_elements} ce @@ -150,7 +151,7 @@ public function execute() { $certificatename = format_string($customcert->name, true, ['context' => $context]); // Used to create the email subject. - $info = new \stdClass; + $info = new \stdClass(); $info->coursename = $courseshortname; // Added for BC, so users who have edited the string don't lose this value. $info->courseshortname = $courseshortname; $info->coursefullname = $coursefullname; @@ -177,14 +178,10 @@ public function execute() { $userswithissue = get_users_by_capability($context, 'mod/customcert:receiveissue'); // Get users with mod/customcert:view capability. $userswithview = get_users_by_capability($context, 'mod/customcert:view'); - // Users with both mod/customcert:view and mod/customcert:receiveissue cabapilities. + // Users with both mod/customcert:view and mod/customcert:receiveissue capabilities. $userswithissueview = array_intersect_key($userswithissue, $userswithview); - $infomodule = new \core_availability\info_module($fastmoduleinfo); - // Filter who can't access due to availability restriction, from the full list. - $userscanissue = $infomodule->filter_user_list($userswithissueview); - - foreach ($userscanissue as $enroluser) { + foreach ($userswithissueview as $enroluser) { // Check if the user has already been issued. if (in_array($enroluser->id, array_keys((array)$issuedusers))) { continue; @@ -195,6 +192,12 @@ public function execute() { continue; } + // Now check if the certificate is not visible to the current user. + $cm = get_fast_modinfo($customcert->courseid, $enroluser->id)->instances['customcert'][$customcert->id]; + if (!$cm->uservisible) { + continue; + } + // Check that they have passed the required time. if (!empty($customcert->requiredtime)) { if (\mod_customcert\certificate::get_course_time($customcert->courseid, diff --git a/tests/email_certificate_task_test.php b/tests/email_certificate_task_test.php index 93910d8b..1950c9c7 100644 --- a/tests/email_certificate_task_test.php +++ b/tests/email_certificate_task_test.php @@ -25,6 +25,7 @@ namespace mod_customcert; +use completion_info; use stdClass; use context_course; use advanced_testcase; @@ -436,4 +437,85 @@ public function test_email_certificates_students_havent_met_required_time() { // Confirm no emails were sent. $this->assertCount(0, $emails); } + + /** + * Tests the email certificate task when the student has not met the completion criteria. + * + * @covers \mod_customcert\task\email_certificate_task + */ + public function test_email_certificates_students_havent_met_required_criteria(): void { + global $CFG, $DB; + + $CFG->enablecompletion = true; + + // Create a course. + $course = $this->getDataGenerator()->create_course(); + + // Create a user. + $user1 = $this->getDataGenerator()->create_user(); + + // Enrol them in the course. + $this->getDataGenerator()->enrol_user($user1->id, $course->id); + + // Create a quiz. + $quiz = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]); + + $quizmodule = $DB->get_record('course_modules', ['id' => $quiz->cmid]); + + // Set completion criteria for the quiz. + $quizmodule->completion = COMPLETION_TRACKING_AUTOMATIC; + $quizmodule->completionview = 1; // Require view to complete. + $quizmodule->completionexpected = 0; + $DB->update_record('course_modules', $quizmodule); + + // Set restrict access to the customcert activity based on the completion of the quiz. + $customcert = $this->getDataGenerator()->create_module('customcert', [ + 'course' => $course->id, + 'emailstudents' => 1, + 'availability' => json_encode( + [ + 'op' => '&', + 'c' => [ + [ + 'type' => 'completion', + 'cm' => $quiz->cmid, + 'e' => COMPLETION_COMPLETE, // Ensure the quiz is marked as complete. + ], + ], + 'showc' => [ + false + ], + ] + ) + ]); + + // Create template object. + $template = new stdClass(); + $template->id = $customcert->templateid; + $template->name = 'A template'; + $template->contextid = context_course::instance($course->id)->id; + $template = new template($template); + + // Add a page to this template. + $pageid = $template->add_page(); + + // Add an element to the page. + $element = new stdClass(); + $element->pageid = $pageid; + $element->name = 'Image'; + $DB->insert_record('customcert_elements', $element); + + // Run the task. + $sink = $this->redirectEmails(); + $task = new email_certificate_task(); + $task->execute(); + $emails = $sink->get_messages(); + + // Confirm there are no issues as the user can not view the certificate. + $issues = $DB->get_records('customcert_issues'); + $this->assertCount(0, $issues); + + // Confirm no emails were sent. + $this->assertCount(0, $emails); + } }