/** * 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); }
$questionids = $attemptobj->get_question_ids(); foreach ($attemptobj->get_question_iterator() as $number => $question) { if ($question->length == 0) { continue; } $flag = ''; if ($attemptobj->is_question_flagged($question->id)) { $flag = ' <img src="' . $CFG->pixpath . '/i/flagged.png" alt="' . get_string('flagged', 'question') . '" class="questionflag" />'; } $row = array('<a href="' . $attemptobj->attempt_url($question->id) . '">' . $number . $flag . '</a>', get_string($attemptobj->get_question_status($question->id), 'quiz')); if ($scorescolumn) { $row[] = $attemptobj->get_question_score($question->id); } $table->data[] = $row; } /// Print the summary table. print_table($table); /// countdown timer echo $attemptobj->get_timer_html(); /// Finish attempt button. echo "<div class=\"submitbtns mdl-align\">\n"; $options = array('attempt' => $attemptobj->get_attemptid(), 'finishattempt' => 1, 'timeup' => 0, 'questionids' => '', 'sesskey' => sesskey()); print_single_button($attemptobj->processattempt_url(), $options, get_string('finishattempt', 'quiz'), 'post', '', false, '', false, get_string('confirmclose', 'quiz'), 'responseform'); echo "</div>\n"; /// Finish the page $accessmanager->show_attempt_timer_if_needed($attemptobj->get_attempt(), time()); if ($accessmanager->securewindow_required($attemptobj->is_preview_user())) { print_footer('empty'); } else { print_footer($attemptobj->get_course()); }
} /// Unset any variables we know are not responses unset($responses->id); unset($responses->q); unset($responses->oldpage); unset($responses->newpage); unset($responses->review); unset($responses->questionids); unset($responses->finishattempt); // same as $finishattempt unset($responses->forcenewattempt); /// Extract the responses. $actions will be an array indexed by the questions ids. $actions = question_extract_responses($attemptobj->get_questions($submittedquestionids), $responses, $event); /// Process each question in turn $success = true; $attempt = $attemptobj->get_attempt(); foreach ($submittedquestionids as $id) { if (!isset($actions[$id])) { $actions[$id]->responses = array('' => ''); $actions[$id]->event = QUESTION_EVENTOPEN; } $actions[$id]->timestamp = $timenow; /// If a particular question was submitted, update the nexturl to go back to that question. if ($actions[$id]->event == QUESTION_EVENTSUBMIT) { $nexturl = $attemptobj->attempt_url($id); } $state = $attemptobj->get_question_state($id); if (question_process_responses($attemptobj->get_question($id), $state, $actions[$id], $attemptobj->get_quiz(), $attempt)) { save_question_session($attemptobj->get_question($id), $state); } else { $success = false;