--- quiz.php Thu Mar 15 12:29:36 2007 +++ quiz.php Tue Jun 26 14:00:44 2007 @@ -1,4 +1,4 @@ -username,\nYou have just completed the assessment $a->quizname\n in course $a->coursename\nReview: $a->quizreviewurl\n'; +$string['emailconfirmsubject'] = 'Assessment submission confirmation'; +$string['emailnotifybody'] = 'Hello $a->username,\nThe student $a->studentname has completed the assessment $a->quizname\n in course $a->coursename\nReview: $a->quizreviewurl\n'; +$string['emailnotifysubject'] = '$a->studentname has completed assessment - $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'; @@ -373,6 +377,8 @@ $string['questiontypesetupoptions'] = 'Setup options for question types:'; $string['quiz:attempt'] = 'Attempt quizzes'; $string['quiz:deleteattempts'] = 'Delete quiz attempts'; +$string['quiz:emailconfirmsubmission'] = 'Receive own assessment submission notification'; +$string['quiz:emailnotifysubmission'] = 'Receive student assessment submission notifications'; $string['quiz:grade'] = 'Grade quizzes manually'; $string['quiz:ignoretimelimits'] = 'Ignores time limit on quizs'; $string['quiz:manage'] = 'Manage quizzes'; --- db/access.php Sat Feb 17 12:24:46 2007 +++ db/access.php Tue Jun 26 14:28:11 2007 @@ -93,6 +93,22 @@ '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() ) ); --- attempt.php Sat Mar 31 03:21:46 2007 +++ attempt.php Tue Jun 26 12:49:04 2007 @@ -61,7 +61,7 @@ $coursecontext = get_context_instance(CONTEXT_COURSE, $cm->course); // course context $context = get_context_instance(CONTEXT_MODULE, $cm->id); - + // if no questions have been set up yet redirect to edit.php if (!$quiz->questions and has_capability('mod/quiz:manage', $context)) { redirect('edit.php?quizid=' . $quiz->id); @@ -402,6 +402,11 @@ if (($attempt->attempt > 1 || $attempt->timefinish > 0) and !$attempt->preview) { quiz_save_best_grade($quiz); } + } + +/// Send emails to those who have the capability set + if ($finishattempt) { + quiz_send_notification_emails($course, $quiz, $attempt, $context); } /// Check access to quiz page --- locallib.php Wed Jan 17 12:02:24 2007 +++ locallib.php Tue Jun 26 13:28:16 2007 @@ -732,4 +732,158 @@ } return array($someoptions, $alloptions); } + +/** + * 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 + * + * @return int number of emails sent + */ +function quiz_send_notification_emails($course, $quiz, $attempt, $context) { + global $CFG, $USER; + // we will count goods and bads for error logging + $emailresult['good'] = $emailresult['block'] = $emailresult['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)) { + // 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, $sort='', + $limitfrom='', $limitnum='', $groups='', $notifyexcludeusers, $doanything=false, $view=false); + + // 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']; +} ?> --- version.php Wed Feb 14 17:44:38 2007 +++ version.php Tue Jun 26 13:10:51 2007 @@ -5,7 +5,7 @@ // This fragment is called by moodle_needs_upgrading() and /admin/index.php //////////////////////////////////////////////////////////////////////////////// -$module->version = 2007020200; // The (date) version of this module +$module->version = 2007062600; // The (date) version of this module $module->requires = 2007020200; // Requires this Moodle version $module->cron = 0; // How often should cron check this module (seconds)?