public function attempt() { if (!env('student')) { redirect('m=login'); } $quizId = val($_REQUEST, 'id', -1); $attemptId = val($_REQUEST, 'attemptId', -1); $page = val($_REQUEST, 'page', 1); $complete = val($_REQUEST, 'complete'); $pro = val($_REQUEST, 'pro'); if (!empty($pro)) { env('modepro', true); } $now = date('Y-m-d H:i:s'); if (val(env('event'), 'instanceId') != $quizId) { throw new Exception('Cannot fetch event', 404); } $quiz = entry_sql('SELECT * FROM quiz WHERE quizId=:quizId', array('quizId' => $quizId)); if (empty($quiz)) { throw new Exception('Cannot find quiz "' . $id . '"', 404); } if ($attemptId == 0) { // create new attempt $attemptId = material::i('quiz')->startAttempt($quiz); redirect('c=quiz&m=attempt&id=' . $quizId . '&attemptId=' . $attemptId); } $attempt = entry_sql('SELECT * FROM quiz_attempt WHERE quizAttemptId=:quizAttemptId AND quizId=:quizId AND studentId=:studentId', array('quizAttemptId' => $attemptId, 'quizId' => $quizId, 'studentId' => studentId())); if (empty($attempt)) { throw new Exception('Attempt "' . $attemptId . '" not found', 404); } if ($attempt['status'] != STATUS_INPROC) { throw new Exception('Attempt is not available anymore', 403); } if (!empty($quiz['timeLimit']) && date('Y-m-d H:i:s', strtotime($attempt['timeStart']) + $quiz['timeLimit']) < $now) { // if time expired material::i('quiz')->finishAttempt($attemptId); redirect('c=quiz&id=' . $quiz['quizId'] . '&eventId=' . val(env('event'), 'eventId')); } $questions = entries_sql('SELECT * FROM question_session WHERE quizAttemptId=:quizAttemptId ORDER BY num', array('quizAttemptId' => $attemptId)); $perpage = 1; $numl = $page * $perpage; $numf = $numl - $perpage; $qresponses = val($_REQUEST, 'question', array()); foreach ($questions as &$qsess) { $qobj = question::i($qsess['questionId']); $qresponse = val($qresponses, $qsess['questionId']); if (!empty($qresponse)) { $qgrade = $qobj->get_grade($qresponse); $qsess['grade'] = $qobj->get_grade($qresponse); $qsess['response'] = json_encode($qresponse); $qsess['status'] = STATUS_ANSWER; entry_change('question_session', $qsess, array('questionSessionId' => $qsess['questionSessionId'])); entry_change('quiz_attempt', array('timeChange' => date('Y-m-d H:i:s')), array('quizAttemptId' => $attemptId)); } if ($qsess['num'] > $numf && $qsess['num'] <= $numl) { // render only questions of the page $qsess['qhtml'] = $qobj->render(json_decode($qsess['response'])); } $qsess['page'] = ceil($qsess['num'] / $perpage); } env('breadcrumbs', array_merge($this->_up_breadcrumbs(env('event')), array(lng('quiz:attempt')))); if (!empty($complete)) { material::i('quiz')->finishAttempt($attemptId); trigger_exe('material.graded', array('quiz', $quizId, studentId())); redirect('c=quiz&id=' . $quiz['quizId'] . '&eventId=' . val(env('event'), 'eventId')); } tpl('quiz/attempt', array('page' => $page, 'quiz' => $quiz, 'attempt' => $attempt, 'questions' => $questions)); }