mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 14:27:22 +01:00
990650f94c
This was implemented by Matt Petro of the University of Wisconsin - Madison Engineering School and Math Department. Many thanks. Reviewed by and committed by Tim Hunt. This adds a new Overrides tab to the UI, with sub-tabs Group overrides and User overrides. Each of those lists all the overrides that currently exist, and lets you manage them and create more. When a quiz is being attempted, the override that applies to the current user is combined with the current quiz settings loaded from the quiz table (normally called $quiz). If there are both user and group overrides, then just the specific user override is used (more specific). If the user is in several groups, then the overrides are combined to give the most permissive set of options. There is one new database table quiz_overrides, to store the overrides.
125 lines
4.3 KiB
PHP
125 lines
4.3 KiB
PHP
<?php
|
|
/**
|
|
* This page deals with starting a new attempt at a quiz.
|
|
*
|
|
* Normally, it will end up redirecting to attempt.php - unless a password form is displayed.
|
|
*
|
|
* This code used to be at the top of attempt.php, if you are looking for CVS history.
|
|
*
|
|
* @author Tim Hunt.
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
|
* @package quiz
|
|
*/
|
|
|
|
require_once(dirname(__FILE__) . '/../../config.php');
|
|
require_once($CFG->dirroot . '/mod/quiz/locallib.php');
|
|
|
|
/// Get submitted parameters.
|
|
$id = required_param('cmid', PARAM_INT); // Course Module ID
|
|
$forcenew = optional_param('forcenew', false, PARAM_BOOL); // Used to force a new preview
|
|
|
|
if (!$cm = get_coursemodule_from_id('quiz', $id)) {
|
|
print_error('invalidcoursemodule');
|
|
}
|
|
if (!$course = $DB->get_record('course', array('id' => $cm->course))) {
|
|
print_error("coursemisconf");
|
|
}
|
|
if (!$quiz = $DB->get_record('quiz', array('id' => $cm->instance))) {
|
|
print_error('invalidcoursemodule');
|
|
}
|
|
|
|
$quizobj = quiz::create($quiz->id, $USER->id);
|
|
|
|
/// 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);
|
|
|
|
if ($lastattempt && !$lastattempt->timefinish) {
|
|
/// Continuation of an attempt - check password then redirect.
|
|
$accessmanager->do_password_check($quizobj->is_preview_user());
|
|
redirect($quizobj->attempt_url($lastattempt->id));
|
|
}
|
|
|
|
/// Get number for the next or unfinished attempt
|
|
if ($lastattempt && !$lastattempt->preview && !$quizobj->is_preview_user()) {
|
|
$lastattemptid = $lastattempt->id;
|
|
$attemptnumber = $lastattempt->attempt + 1;
|
|
} else {
|
|
$lastattempt = false;
|
|
$lastattemptid = false;
|
|
$attemptnumber = 1;
|
|
}
|
|
|
|
/// Check access.
|
|
$messages = $accessmanager->prevent_access() +
|
|
$accessmanager->prevent_new_attempt($attemptnumber - 1, $lastattempt);
|
|
if (!$quizobj->is_preview_user() && $messages) {
|
|
print_error('attempterror', 'quiz', $quizobj->view_url(),
|
|
$accessmanager->print_messages($messages, true));
|
|
}
|
|
$accessmanager->do_password_check($quizobj->is_preview_user());
|
|
|
|
/// Delete any previous preview attempts belonging to this user.
|
|
quiz_delete_previews($quiz, $USER->id);
|
|
|
|
/// Create the new attempt and initialize the question sessions
|
|
$attempt = quiz_create_attempt($quiz, $attemptnumber, $lastattempt, time(), $quizobj->is_preview_user());
|
|
|
|
/// Save the attempt in the database.
|
|
$attempt->id = $DB->insert_record('quiz_attempts', $attempt);
|
|
|
|
/// Log the new attempt.
|
|
if ($attempt->preview) {
|
|
add_to_log($course->id, 'quiz', 'preview', 'view.php?id=' . $quizobj->get_cmid(),
|
|
$quizobj->get_quizid(), $quizobj->get_cmid());
|
|
} else {
|
|
add_to_log($course->id, 'quiz', 'attempt', 'review.php?attempt=' . $attempt->id,
|
|
$quizobj->get_quizid(), $quizobj->get_cmid());
|
|
}
|
|
|
|
/// Fully load all the questions in this quiz.
|
|
$quizobj->preload_questions();
|
|
$quizobj->load_questions();
|
|
|
|
/// Create initial states for all questions in this quiz.
|
|
if (!$states = get_question_states($quizobj->get_questions(), $quizobj->get_quiz(), $attempt, $lastattemptid)) {
|
|
print_error('cannotrestore', 'quiz');
|
|
}
|
|
|
|
/// Save all the newly created states.
|
|
foreach ($quizobj->get_questions() as $i => $question) {
|
|
save_question_session($question, $states[$i]);
|
|
}
|
|
|
|
/// Redirect to the attempt page.
|
|
redirect($quizobj->attempt_url($attempt->id));
|