mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 06:18:28 +01:00
MDL-29627 quiz load access settings when a quiz is being attempted.
This commit is contained in:
parent
c18ba64c3e
commit
dd70d561ef
@ -124,23 +124,16 @@ class quiz_access_manager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Load any settings required by the access rules. We try to do this with
|
||||
* a single DB query.
|
||||
*
|
||||
* Note that the standard plugins do not use this mechanism, becuase all their
|
||||
* settings are stored in the quiz table.
|
||||
*
|
||||
* Build the SQL for loading all the access settings in one go.
|
||||
* @param int $quizid the quiz id.
|
||||
* @return array setting value name => value. The value names should all
|
||||
* start with the name of the corresponding plugin to avoid collisions.
|
||||
* @param string $basefields initial part of the select list.
|
||||
* @return array with two elements, the sql and the placeholder values.
|
||||
*/
|
||||
public static function load_settings($quizid) {
|
||||
global $DB;
|
||||
$rules = get_plugin_list_with_class('quizaccess', '', 'rule.php');
|
||||
|
||||
$allfields = '';
|
||||
protected static function get_load_sql($quizid, $rules, $basefields) {
|
||||
$allfields = $basefields;
|
||||
$alljoins = '{quiz} quiz';
|
||||
$allparams = array('quizid' => $quizid);
|
||||
|
||||
foreach ($rules as $rule) {
|
||||
list($fields, $joins, $params) = $rule::get_settings_sql($quizid);
|
||||
if ($fields) {
|
||||
@ -156,10 +149,27 @@ class quiz_access_manager {
|
||||
$allparams += $params;
|
||||
}
|
||||
}
|
||||
$data = (array) $DB->get_record_sql("
|
||||
SELECT $allfields
|
||||
FROM $alljoins
|
||||
WHERE quiz.id = :quizid", $allparams);
|
||||
|
||||
return array("SELECT $allfields FROM $alljoins WHERE quiz.id = :quizid", $allparams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load any settings required by the access rules. We try to do this with
|
||||
* a single DB query.
|
||||
*
|
||||
* Note that the standard plugins do not use this mechanism, becuase all their
|
||||
* settings are stored in the quiz table.
|
||||
*
|
||||
* @param int $quizid the quiz id.
|
||||
* @return array setting value name => value. The value names should all
|
||||
* start with the name of the corresponding plugin to avoid collisions.
|
||||
*/
|
||||
public static function load_settings($quizid) {
|
||||
global $DB;
|
||||
|
||||
$rules = get_plugin_list_with_class('quizaccess', '', 'rule.php');
|
||||
list($sql, $params) = self::get_load_sql($quizid, $rules, '');
|
||||
$data = (array) $DB->get_record_sql($sql, $params);
|
||||
|
||||
foreach ($rules as $rule) {
|
||||
$data += $rule::get_extra_settings($quizid);
|
||||
@ -168,6 +178,32 @@ class quiz_access_manager {
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the quiz settings and any settings required by the access rules.
|
||||
* We try to do this with a single DB query.
|
||||
*
|
||||
* Note that the standard plugins do not use this mechanism, becuase all their
|
||||
* settings are stored in the quiz table.
|
||||
*
|
||||
* @param int $quizid the quiz id.
|
||||
* @return object mdl_quiz row with extra fields.
|
||||
*/
|
||||
public static function load_quiz_and_settings($quizid) {
|
||||
global $DB;
|
||||
|
||||
$rules = get_plugin_list_with_class('quizaccess', '', 'rule.php');
|
||||
list($sql, $params) = self::get_load_sql($quizid, $rules, 'quiz.*');
|
||||
$quiz = $DB->get_record_sql($sql, $params, MUST_EXIST);
|
||||
|
||||
foreach ($rules as $rule) {
|
||||
foreach ($rule::get_extra_settings($quizid) as $name => $value) {
|
||||
$quiz->$name = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $quiz;
|
||||
}
|
||||
|
||||
protected function accumulate_messages(&$messages, $new) {
|
||||
if (is_array($new)) {
|
||||
$messages = array_merge($messages, $new);
|
||||
|
@ -103,7 +103,7 @@ class quiz {
|
||||
public static function create($quizid, $userid) {
|
||||
global $DB;
|
||||
|
||||
$quiz = $DB->get_record('quiz', array('id' => $quizid), '*', MUST_EXIST);
|
||||
$quiz = quiz_access_manager::load_quiz_and_settings($quizid);
|
||||
$course = $DB->get_record('course', array('id' => $quiz->course), '*', MUST_EXIST);
|
||||
$cm = get_coursemodule_from_instance('quiz', $quiz->id, $course->id, false, MUST_EXIST);
|
||||
|
||||
@ -383,7 +383,7 @@ class quiz_attempt {
|
||||
global $DB;
|
||||
|
||||
$attempt = $DB->get_record('quiz_attempts', $conditions, '*', MUST_EXIST);
|
||||
$quiz = $DB->get_record('quiz', array('id' => $attempt->quiz), '*', MUST_EXIST);
|
||||
$quiz = quiz_access_manager::load_quiz_and_settings($attempt->quiz);
|
||||
$course = $DB->get_record('course', array('id' => $quiz->course), '*', MUST_EXIST);
|
||||
$cm = get_coursemodule_from_instance('quiz', $quiz->id, $course->id, false, MUST_EXIST);
|
||||
|
||||
|
@ -41,11 +41,8 @@ if (!$cm = get_coursemodule_from_id('quiz', $id)) {
|
||||
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);
|
||||
$quizobj = quiz::create($cm->instance, $USER->id);
|
||||
// This script should only ever be posted to, so set page URL to the view page.
|
||||
$PAGE->set_url($quizobj->view_url());
|
||||
|
||||
@ -75,11 +72,11 @@ 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));
|
||||
array('quiz' => $quizobj->get_quizid(), 'userid' => $USER->id));
|
||||
}
|
||||
|
||||
// Look for an existing attempt.
|
||||
$attempts = quiz_get_user_attempts($quiz->id, $USER->id, 'all');
|
||||
$attempts = quiz_get_user_attempts($quizobj->get_quizid(), $USER->id, 'all');
|
||||
$lastattempt = end($attempts);
|
||||
|
||||
// If an in-progress attempt exists, check password then redirect to it.
|
||||
@ -107,16 +104,16 @@ if (!$quizobj->is_preview_user() && $messages) {
|
||||
$accessmanager->do_password_check($quizobj->is_preview_user());
|
||||
|
||||
// Delete any previous preview attempts belonging to this user.
|
||||
quiz_delete_previews($quiz, $USER->id);
|
||||
quiz_delete_previews($quizobj->get_quiz(), $USER->id);
|
||||
|
||||
$quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context());
|
||||
$quba->set_preferred_behaviour($quiz->preferredbehaviour);
|
||||
$quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour);
|
||||
|
||||
// Create the new attempt and initialize the question sessions
|
||||
$attempt = quiz_create_attempt($quiz, $attemptnumber, $lastattempt, time(),
|
||||
$attempt = quiz_create_attempt($quizobj->get_quiz(), $attemptnumber, $lastattempt, time(),
|
||||
$quizobj->is_preview_user());
|
||||
|
||||
if (!($quiz->attemptonlast && $lastattempt)) {
|
||||
if (!($quizobj->get_quiz()->attemptonlast && $lastattempt)) {
|
||||
// Starting a normal, new, quiz attempt.
|
||||
|
||||
// Fully load all the questions in this quiz.
|
||||
@ -128,14 +125,14 @@ if (!($quiz->attemptonlast && $lastattempt)) {
|
||||
$questionsinuse = array_keys($quizobj->get_questions());
|
||||
foreach ($quizobj->get_questions() as $i => $questiondata) {
|
||||
if ($questiondata->qtype != 'random') {
|
||||
if (!$quiz->shuffleanswers) {
|
||||
if (!$quizobj->get_quiz()->shuffleanswers) {
|
||||
$questiondata->options->shuffleanswers = false;
|
||||
}
|
||||
$question = question_bank::make_question($questiondata);
|
||||
|
||||
} else {
|
||||
$question = question_bank::get_qtype('random')->choose_other_question(
|
||||
$questiondata, $questionsinuse, $quiz->shuffleanswers);
|
||||
$questiondata, $questionsinuse, $quizobj->get_quiz()->shuffleanswers);
|
||||
if (is_null($question)) {
|
||||
throw new moodle_exception('notenoughrandomquestions', 'quiz',
|
||||
$quizobj->view_url(), $questiondata);
|
||||
|
@ -40,9 +40,6 @@ if ($id) {
|
||||
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');
|
||||
}
|
||||
} else {
|
||||
if (!$quiz = $DB->get_record('quiz', array('id' => $q))) {
|
||||
print_error('invalidquizid', 'quiz');
|
||||
@ -67,8 +64,10 @@ $canpreview = has_capability('mod/quiz:preview', $context);
|
||||
|
||||
// Create an object to manage all the other (non-roles) access rules.
|
||||
$timenow = time();
|
||||
$accessmanager = new quiz_access_manager(quiz::create($quiz->id, $USER->id), $timenow,
|
||||
$quizobj = quiz::create($cm->instance, $USER->id);
|
||||
$accessmanager = new quiz_access_manager($quizobj, $timenow,
|
||||
has_capability('mod/quiz:ignoretimelimits', $context, null, false));
|
||||
$quiz = $quizobj->get_quiz();
|
||||
|
||||
// Log this request.
|
||||
add_to_log($course->id, 'quiz', 'view', 'view.php?id=' . $cm->id, $quiz->id, $cm->id);
|
||||
@ -84,9 +83,6 @@ if ($edit != -1 && $PAGE->user_allowed_editing()) {
|
||||
$USER->editing = $edit;
|
||||
}
|
||||
|
||||
// Update the quiz with overrides for the current user
|
||||
$quiz = quiz_update_effective_access($quiz, $USER->id);
|
||||
|
||||
// Get this user's attempts.
|
||||
$attempts = quiz_get_user_attempts($quiz->id, $USER->id, 'finished', true);
|
||||
$lastfinishedattempt = end($attempts);
|
||||
|
Loading…
x
Reference in New Issue
Block a user