From ac48e43a896d1a6315c38e3aac5a3c5f0d327cb8 Mon Sep 17 00:00:00 2001 From: tjhunt Date: Tue, 26 Jun 2007 16:34:05 +0000 Subject: [PATCH] MDL-648 - Email notification and confirmation when quizzes are submitted. Thanks to Graham Miller for implementing this to my design. --- lang/en_utf8/quiz.php | 21 ++++++ mod/quiz/attempt.php | 5 ++ mod/quiz/db/access.php | 16 +++++ mod/quiz/locallib.php | 160 +++++++++++++++++++++++++++++++++++++++++ mod/quiz/version.php | 4 +- 5 files changed, 204 insertions(+), 2 deletions(-) diff --git a/lang/en_utf8/quiz.php b/lang/en_utf8/quiz.php index bfb37665f8..1de91fe568 100644 --- a/lang/en_utf8/quiz.php +++ b/lang/en_utf8/quiz.php @@ -163,6 +163,25 @@ $string['editqcats'] = 'Edit questions categories'; $string['editquestions'] = 'Edit questions'; $string['editquiz'] = 'Edit Quiz'; $string['editquizquestions'] = 'Edit Quiz Questions'; +$string['emailconfirmbody'] = 'Dear $a->username, + +Thank you for submitting your answers to +\'$a->quizname\' +in course \'$a->coursename\' +at $a->submissiontime. + +This email confirms that we have safely received your answers. + +You can access this quiz at $a->quizurl.'; +$string['emailconfirmsubject'] = 'Quiz submission confirmation: $a->quizname'; +$string['emailnotifybody'] = 'Dear $a->username, + +$a->studentname has completed the quiz +\'$a->quizname\' ($a->quizurl) +in course \'$a->coursename\' + +You can review this attempt at $a->quizreviewurl.'; +$string['emailnotifysubject'] = '$a->studentname has completed quiz $a->quizname'; $string['errorinquestion'] = 'Error in question'; $string['errormissingquestion'] = 'Error: The system is missing the question with id $a'; $string['errornotnumbers'] = 'Error - answers must be numeric'; @@ -380,6 +399,8 @@ $string['questiontype'] = 'Question type $a'; $string['questiontypesetupoptions'] = 'Setup options for question types:'; $string['quiz:attempt'] = 'Attempt quizzes'; $string['quiz:deleteattempts'] = 'Delete quiz attempts'; +$string['quiz:emailconfirmsubmission'] = 'Get email confirmation when submitting'; +$string['quiz:emailnotifysubmission'] = 'Get email notification of submissions'; $string['quiz:grade'] = 'Grade quizzes manually'; $string['quiz:ignoretimelimits'] = 'Ignores time limit on quizzes'; $string['quiz:manage'] = 'Manage quizzes'; diff --git a/mod/quiz/attempt.php b/mod/quiz/attempt.php index c298c4f5bc..694f57bb0b 100644 --- a/mod/quiz/attempt.php +++ b/mod/quiz/attempt.php @@ -363,6 +363,11 @@ } } +/// Send emails to those who have the capability set + if ($finishattempt && !$attempt->preview) { + quiz_send_notification_emails($course, $quiz, $attempt, $context, $cm); + } + /// Check access to quiz page // check the quiz times diff --git a/mod/quiz/db/access.php b/mod/quiz/db/access.php index 720e0e6e86..251ec22e1c 100644 --- a/mod/quiz/db/access.php +++ b/mod/quiz/db/access.php @@ -90,6 +90,22 @@ $mod_quiz_capabilities = array( ), 'mod/quiz:ignoretimelimits' => array( + 'captype' => 'read', + 'contextlevel' => CONTEXT_MODULE, + 'legacy' => array() + ), + + // Receive email confirmation of own quiz submission + 'mod/quiz:emailconfirmsubmission' => array( + + 'captype' => 'read', + 'contextlevel' => CONTEXT_MODULE, + 'legacy' => array() + ), + + // Receive email notification of other peoples quiz submissions + 'mod/quiz:emailnotifysubmission' => array( + 'captype' => 'read', 'contextlevel' => CONTEXT_MODULE, 'legacy' => array() diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index ff565c1b1d..fb6231e776 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -765,4 +765,164 @@ function quiz_get_combined_reviewoptions($quiz, $attempts, $context=null) { } return array($someoptions, $alloptions); } + +/// FUNCTIONS FOR SENDING NOTIFICATION EMAILS /////////////////////////////// + +/** + * Sends confirmation email to the student taking the course + * + * @param stdClass $a associative array of replaceable fields for the templates + * + * @return bool|string result of email_to_user() + */ +function quiz_send_confirmation($a) { + + global $USER; + + // recipient is self + $a->useridnumber = $USER->idnumber; + $a->username = fullname($USER); + $a->userusername = $USER->username; + + // fetch the subject and body from strings + $subject = get_string('emailconfirmsubject', 'quiz', $a); + $body = get_string('emailconfirmbody', 'quiz', $a); + + // send email and analyse result + return email_to_user($USER, get_admin(), $subject, $body); +} + +/** + * Sends notification email to the interested parties that assign the role capability + * + * @param object $recipient user object of the intended recipient + * @param stdClass $a associative array of replaceable fields for the templates + * + * @return bool|string result of email_to_user() + */ +function quiz_send_notification($recipient, $a) { + + global $USER; + + // recipient info for template + $a->username = fullname($recipient); + $a->userusername = $recipient->username; + $a->userusername = $recipient->username; + + // fetch the subject and body from strings + $subject = get_string('emailnotifysubject', 'quiz', $a); + $body = get_string('emailnotifybody', 'quiz', $a); + + // send email and analyse result + return email_to_user($recipient, $USER, $subject, $body); +} + +/** + * Takes a bunch of information to format into an email and send + * to the specified recipient. + * + * @param object $course the course + * @param object $quiz the quiz + * @param object $attempt this attempt just finished + * @param object $context the quiz context + * @param object $cm the coursemodule for this quiz + * + * @return int number of emails sent + */ +function quiz_send_notification_emails($course, $quiz, $attempt, $context, $cm) { + global $CFG, $USER; + // we will count goods and bads for error logging + $emailresult = array('good' => 0, 'block' => 0, 'fail' => 0); + + // do nothing if required objects not present + if (empty($course) or empty($quiz) or empty($attempt) or empty($context)) { + debugging('quiz_send_notification_emails: Email(s) not sent due to program error.', + DEBUG_DEVELOPER); + return $emailresult['fail']; + } + + // check for confirmation required + $sendconfirm = false; + $notifyexcludeusers = ''; + if (has_capability('mod/quiz:emailconfirmsubmission', $context, NULL, false)) { + // exclude from notify emails later + $notifyexcludeusers = $USER->id; + // send the email + $sendconfirm = true; + } + + // check for notifications required + $notifyfields = 'u.id, u.username, u.firstname, u.lastname, u.email, u.emailstop, u.lang, u.timezone, u.mailformat, u.maildisplay'; + $userstonotify = get_users_by_capability($context, 'mod/quiz:emailnotifysubmission', + $notifyfields, '', '', '', groups_m_get_groups_for_user($cm, $USER->id), + $notifyexcludeusers, false, false, true); + + // if something to send, then build $a + if (! empty($userstonotify) or $sendconfirm) { + $a = new stdClass; + // course info + $a->coursename = $course->fullname; + $a->courseshortname = $course->shortname; + // quiz info + $a->quizname = $quiz->name; + $a->quizreportlink = '' . format_string($quiz->name) . ' report'; + $a->quizreporturl = $CFG->wwwroot . '/mod/quiz/report.php?q=' . $quiz->id; + $a->quizreviewlink = '' . format_string($quiz->name) . ' review'; + $a->quizreviewurl = $CFG->wwwroot . '/mod/quiz/review.php?attempt=' . $attempt->id; + $a->quizlink = '' . format_string($quiz->name) . ''; + $a->quizurl = $CFG->wwwroot . '/mod/quiz/view.php?q=' . $quiz->id; + // attempt info + $a->attemptsubmissiontime = userdate($attempt->timefinish); + $a->attempttimetaken = $attempt->timefinish - $attempt->timestart; + // student who sat the quiz info + $a->studentidnumber = $USER->idnumber; + $a->studentname = fullname($USER); + $a->studentusername = $USER->username; + } + + // send confirmation if required + if ($sendconfirm) { + // send the email and update stats + switch (quiz_send_confirmation($a)) { + case true: + $emailresult['good']++; + break; + case false: + $emailresult['fail']++; + break; + case 'emailstop': + $emailresult['block']++; + break; + } + } + + // send notifications if required + if (!empty($userstonotify)) { + // loop through recipients and send an email to each and update stats + foreach ($userstonotify as $recipient) { + switch (quiz_send_notification($recipient, $a)) { + case true: + $emailresult['good']++; + break; + case false: + $emailresult['fail']++; + break; + case 'emailstop': + $emailresult['block']++; + break; + } + } + } + + // log errors sending emails if any + if (! empty($emailresult['fail'])) { + debugging('quiz_send_notification_emails:: '.$emailresult['fail'].' email(s) failed to be sent.', DEBUG_DEVELOPER); + } + if (! empty($emailresult['block'])) { + debugging('quiz_send_notification_emails:: '.$emailresult['block'].' email(s) were blocked by the user.', DEBUG_DEVELOPER); + } + + // return the number of successfully sent emails + return $emailresult['good']; +} ?> diff --git a/mod/quiz/version.php b/mod/quiz/version.php index 8a945eb022..40b6d1f6b3 100644 --- a/mod/quiz/version.php +++ b/mod/quiz/version.php @@ -5,8 +5,8 @@ // This fragment is called by moodle_needs_upgrading() and /admin/index.php //////////////////////////////////////////////////////////////////////////////// -$module->version = 2007061100; // The (date) version of this module -$module->requires = 2007060502; // Requires this Moodle version +$module->version = 2007062600; // The (date) version of this module +$module->requires = 2007062401; // Requires this Moodle version $module->cron = 0; // How often should cron check this module (seconds)? ?> -- 2.39.5