} if (!($quiz = $DB->get_record('quiz', array('id' => $cm->instance)))) { print_error('invalidcoursemodule'); } $quizobj = new quiz($quiz, $cm, $course); /// Check login and sesskey. require_login($quizobj->get_courseid(), false, $quizobj->get_cm()); if (!confirm_sesskey()) { throw new moodle_exception('confirmsesskeybad', 'error', $quizobj->view_url()); } /// if no questions have been set up yet redirect to edit.php if (!$quizobj->get_question_ids() && $quizobj->has_capability('mod/quiz:manage')) { redirect($quizobj->edit_url()); } /// Create an object to manage all the other (non-roles) access rules. $accessmanager = $quizobj->get_access_manager(time()); if ($quizobj->is_preview_user() && $forcenew) { $accessmanager->clear_password_access(); } /// Check capabilites. if (!$quizobj->is_preview_user()) { $quizobj->require_capability('mod/quiz:attempt'); } /// Check to see if a new preview was requested. if ($quizobj->is_preview_user() && $forcenew) { /// To force the creation of a new preview, we set a finish time on the /// current attempt (if any). It will then automatically be deleted below $DB->set_field('quiz_attempts', 'timefinish', time(), array('quiz' => $quiz->id, 'userid' => $USER->id)); } /// Look for an existing attempt. $lastattempt = quiz_get_latest_attempt_by_user($quiz->id, $USER->id);
/** * Creates an object to represent a new attempt at a quiz * * Creates an attempt object to represent an attempt at the quiz by the current * user starting at the current time. The ->id field is not set. The object is * NOT written to the database. * * @param object $quizobj the quiz object to create an attempt for. * @param int $attemptnumber the sequence number for the attempt. * @param object $lastattempt the previous attempt by this user, if any. Only needed * if $attemptnumber > 1 and $quiz->attemptonlast is true. * @param int $timenow the time the attempt was started at. * @param bool $ispreview whether this new attempt is a preview. * * @return object the newly created attempt object. */ function quiz_create_attempt(quiz $quizobj, $attemptnumber, $lastattempt, $timenow, $ispreview = false) { global $USER; $quiz = $quizobj->get_quiz(); if ($quiz->sumgrades < 0.000005 && $quiz->grade > 0.000005) { throw new moodle_exception('cannotstartgradesmismatch', 'quiz', new moodle_url('/mod/quiz/view.php', array('q' => $quiz->id)), array('grade' => quiz_format_grade($quiz, $quiz->grade))); } if ($attemptnumber == 1 || !$quiz->attemptonlast) { // We are not building on last attempt so create a new attempt. $attempt = new stdClass(); $attempt->quiz = $quiz->id; $attempt->userid = $USER->id; $attempt->preview = 0; $attempt->layout = quiz_clean_layout($quiz->questions, true); if ($quiz->shufflequestions) { $attempt->layout = quiz_repaginate($attempt->layout, $quiz->questionsperpage, true); } } else { // Build on last attempt. if (empty($lastattempt)) { print_error('cannotfindprevattempt', 'quiz'); } $attempt = $lastattempt; } $attempt->attempt = $attemptnumber; $attempt->timestart = $timenow; $attempt->timefinish = 0; $attempt->timemodified = $timenow; $attempt->state = quiz_attempt::IN_PROGRESS; // If this is a preview, mark it as such. if ($ispreview) { $attempt->preview = 1; } $timeclose = $quizobj->get_access_manager($timenow)->get_end_time($attempt); if ($timeclose === false || $ispreview) { $attempt->timecheckstate = null; } else { $attempt->timecheckstate = $timeclose; } return $attempt; }