diff --git a/mod/quiz/accessmanager.php b/mod/quiz/accessmanager.php index 5217178a6c0..2d2cd3cadcf 100644 --- a/mod/quiz/accessmanager.php +++ b/mod/quiz/accessmanager.php @@ -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); diff --git a/mod/quiz/attemptlib.php b/mod/quiz/attemptlib.php index 98f4dafa3c2..af99b63a671 100644 --- a/mod/quiz/attemptlib.php +++ b/mod/quiz/attemptlib.php @@ -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); diff --git a/mod/quiz/startattempt.php b/mod/quiz/startattempt.php index 4f85d373ca3..1323220df4a 100644 --- a/mod/quiz/startattempt.php +++ b/mod/quiz/startattempt.php @@ -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); diff --git a/mod/quiz/view.php b/mod/quiz/view.php index 642e8bf5d84..c38b8d5097c 100644 --- a/mod/quiz/view.php +++ b/mod/quiz/view.php @@ -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);