/** * Initializes quiz javascript and strings for javascript when on the * quiz view page, or the "quizstart" action * * @param \mod_activequiz\activequiz_attempt $attempt * @param \mod_activequiz\activequiz_session $session * @throws moodle_exception throws exception when invalid question on the attempt is found */ public function init_quiz_js($attempt, $session) { global $USER, $CFG; // include classList javascript to add the class List HTML5 for compatibility // below IE 10 $this->page->requires->js('/mod/activequiz/js/classList.js'); $this->page->requires->js('/mod/activequiz/js/core.js'); // add window.onload script manually to handle removing the loading mask echo html_writer::start_tag('script', array('type' => 'text/javascript')); echo <<<EOD (function preLoad(){ window.addEventListener('load', function(){activequiz.quiz_page_loaded();}, false); }()); EOD; echo html_writer::end_tag('script'); if ($this->rtq->is_instructor()) { $this->page->requires->js('/mod/activequiz/js/instructor.js'); } else { $this->page->requires->js('/mod/activequiz/js/student.js'); } // next set up a class to pass to js for js info $jsinfo = new stdClass(); $jsinfo->sesskey = sesskey(); $jsinfo->siteroot = $CFG->wwwroot; $jsinfo->rtqid = $this->rtq->getRTQ()->id; $jsinfo->sessionid = $session->get_session()->id; $jsinfo->attemptid = $attempt->id; $jsinfo->slots = $attempt->getSlots(); $jsinfo->isinstructor = $this->rtq->is_instructor() ? 'true' : 'false'; // manually create the questions stdClass as we can't support JsonSerializable yet $questions = array(); foreach ($attempt->get_questions() as $q) { /** @var \mod_activequiz\activequiz_question $q */ $question = new stdClass(); $question->id = $q->getId(); $question->questiontime = $q->getQuestionTime(); $question->tries = $q->getTries(); $question->question = $q->getQuestion(); $question->slot = $attempt->get_question_slot($q); // if the slot is false, throw exception for invalid question on quiz attempt if ($question->slot === false) { $a = new stdClass(); $a->questionname = $q->getQuestion()->name; throw new moodle_exception('invalidquestionattempt', 'mod_activequiz', '', $a, 'invalid slot when building questions array on quiz renderer'); } $questions[$question->slot] = $question; } $jsinfo->questions = $questions; // resuming quiz feature // this will check if the session has started already and print out $jsinfo->resumequiz = 'false'; if ($session->get_session()->status != 'notrunning') { $sessionstatus = $session->get_session()->status; $currentquestion = $session->get_session()->currentquestion; $nextstarttime = $session->get_session()->nextstarttime; if ($sessionstatus == 'running' && !empty($currentquestion)) { // we're in a currently running question $jsinfo->resumequiz = 'true'; $jsinfo->resumequizstatus = $sessionstatus; $jsinfo->resumequizcurrentquestion = $currentquestion; $nextQuestion = $this->rtq->get_questionmanager()->get_question_with_slot($session->get_session()->currentqnum, $attempt); if ($nextstarttime > time()) { // we're wating for question $jsinfo->resumequizaction = 'waitforquestion'; $jsinfo->resumequizdelay = $session->get_session()->nextstarttime - time(); $jsinfo->resumequizquestiontime = $nextQuestion->getQuestionTime(); } else { $jsinfo->resumequizaction = 'startquestion'; // how much time has elapsed since start time // first check if the question has a time limit if ($nextQuestion->getNoTime()) { $jsinfo->resumequizquestiontime = 0; } else { // otherwise figure out how much time is left $timeelapsed = time() - $nextstarttime; $timeLeft = $nextQuestion->getQuestionTime() - $timeelapsed; $jsinfo->resumequizquestiontime = $timeLeft; } } } else { if ($sessionstatus == 'reviewing' || $sessionstatus == 'endquestion') { // if we're reviewing, resume with quiz info of reviewing and just let // set interval capture next question start time $jsinfo->resumequiz = 'true'; $jsinfo->resumequizaction = 'reviewing'; $jsinfo->resumequizstatus = $sessionstatus; $jsinfo->resumequizcurrentquestion = $currentquestion; if ($attempt->lastquestion) { $jsinfo->lastquestion = 'true'; } else { $jsinfo->lastquestion = 'false'; } } } } // print jsinfo to javascript echo html_writer::start_tag('script', array('type' => 'text/javascript')); echo "rtqinitinfo = " . json_encode($jsinfo); echo html_writer::end_tag('script'); // add strings for js $this->page->requires->strings_for_js(array('waitforquestion', 'gatheringresults', 'feedbackintro', 'nofeedback', 'closingsession', 'sessionclosed', 'trycount', 'timertext', 'waitforrevewingend', 'show_correct_answer', 'hide_correct_answer', 'hidestudentresponses', 'showstudentresponses', 'hidenotresponded', 'shownotresponded'), 'activequiz'); $this->page->requires->strings_for_js(array('seconds'), 'moodle'); // finally allow question modifiers to add their own css/js $this->rtq->call_question_modifiers('add_js', null); }