/** * Send the notification message when a quiz attempt becomes overdue. * * @param quiz_attempt $attemptobj all the data about the quiz attempt. */ function quiz_send_overdue_message($attemptobj) { global $CFG, $DB; $submitter = $DB->get_record('user', array('id' => $attemptobj->get_userid()), '*', MUST_EXIST); if (!$attemptobj->has_capability('mod/quiz:emailwarnoverdue', $submitter->id, false)) { return; // Message not required. } if (!$attemptobj->has_response_to_at_least_one_graded_question()) { return; // Message not required. } // Prepare lots of useful information that admins might want to include in // the email message. $quizname = format_string($attemptobj->get_quiz_name()); $deadlines = array(); if ($attemptobj->get_quiz()->timelimit) { $deadlines[] = $attemptobj->get_attempt()->timestart + $attemptobj->get_quiz()->timelimit; } if ($attemptobj->get_quiz()->timeclose) { $deadlines[] = $attemptobj->get_quiz()->timeclose; } $duedate = min($deadlines); $graceend = $duedate + $attemptobj->get_quiz()->graceperiod; $a = new stdClass(); // Course info. $a->coursename = format_string($attemptobj->get_course()->fullname); $a->courseshortname = format_string($attemptobj->get_course()->shortname); // Quiz info. $a->quizname = $quizname; $a->quizurl = $attemptobj->view_url(); $a->quizlink = '<a href="' . $a->quizurl . '">' . $quizname . '</a>'; // Attempt info. $a->attemptduedate = userdate($duedate); $a->attemptgraceend = userdate($graceend); $a->attemptsummaryurl = $attemptobj->summary_url()->out(false); $a->attemptsummarylink = '<a href="' . $a->attemptsummaryurl . '">' . $quizname . ' review</a>'; // Student's info. $a->studentidnumber = $submitter->idnumber; $a->studentname = fullname($submitter); $a->studentusername = $submitter->username; // Prepare the message. $eventdata = new stdClass(); $eventdata->component = 'mod_quiz'; $eventdata->name = 'attempt_overdue'; $eventdata->notification = 1; $eventdata->userfrom = core_user::get_noreply_user(); $eventdata->userto = $submitter; $eventdata->subject = get_string('emailoverduesubject', 'quiz', $a); $eventdata->fullmessage = get_string('emailoverduebody', 'quiz', $a); $eventdata->fullmessageformat = FORMAT_PLAIN; $eventdata->fullmessagehtml = ''; $eventdata->smallmessage = get_string('emailoverduesmall', 'quiz', $a); $eventdata->contexturl = $a->quizurl; $eventdata->contexturlname = $a->quizname; // Send the message. return message_send($eventdata); }
require_once $CFG->dirroot . '/mod/quiz/locallib.php'; /// Remember the current time as the time any responses were submitted /// (so as to make sure students don't get penalized for slow processing on this page) $timenow = time(); /// Get submitted parameters. $attemptid = required_param('attempt', PARAM_INT); $nextpage = optional_param('nextpage', 0, PARAM_INT); $submittedquestionids = required_param('questionids', PARAM_SEQUENCE); $finishattempt = optional_param('finishattempt', 0, PARAM_BOOL); $timeup = optional_param('timeup', 0, PARAM_BOOL); // True if form was submitted by timer. $attemptobj = new quiz_attempt($attemptid); /// Set $nexturl now. It will be updated if a particular question was sumbitted in /// adaptive mode. if ($nextpage == -1) { $nexturl = $attemptobj->summary_url(); } else { $nexturl = $attemptobj->attempt_url(0, $nextpage); } /// We treat automatically closed attempts just like normally closed attempts if ($timeup) { $finishattempt = 1; } /// Check login. require_login($attemptobj->get_courseid(), false, $attemptobj->get_cm()); confirm_sesskey(); /// Check that this attempt belongs to this user. if ($attemptobj->get_userid() != $USER->id) { quiz_error($attemptobj->get_quiz(), 'notyourattempt'); } /// Check capabilites.