diff --git a/mod/quiz/attemptlib.php b/mod/quiz/attemptlib.php index ed1e9c59a6a..a4a703ad48f 100644 --- a/mod/quiz/attemptlib.php +++ b/mod/quiz/attemptlib.php @@ -1789,6 +1789,7 @@ class quiz_attempt { $transaction = $DB->start_delegated_transaction(); + // Choose the replacement question. $questiondata = $DB->get_record('question', array('id' => $this->slots[$slot]->questionid)); if ($questiondata->qtype != 'random') { @@ -1803,7 +1804,11 @@ class quiz_attempt { } } + // Add the question to the usage. It is important we do this before we choose a variant. $newquestion = question_bank::load_question($newqusetionid); + $newslot = $this->quba->add_question_in_place_of_other($slot, $newquestion); + + // Choose the variant. if ($newquestion->get_num_variants() == 1) { $variant = 1; } else { @@ -1813,8 +1818,8 @@ class quiz_attempt { $newquestion->get_variants_selection_seed()); } - $newslot = $this->quba->add_question_in_place_of_other($slot, $newquestion); - $this->quba->start_question($slot); + // Start the question. + $this->quba->start_question($slot, $variant); $this->quba->set_max_mark($newslot, 0); $this->quba->set_question_attempt_metadata($newslot, 'originalslot', $slot); question_engine::save_questions_usage_by_activity($this->quba); diff --git a/question/classes/engine/variants/least_used_strategy.php b/question/classes/engine/variants/least_used_strategy.php index 0772659ca11..346174c62ae 100644 --- a/question/classes/engine/variants/least_used_strategy.php +++ b/question/classes/engine/variants/least_used_strategy.php @@ -90,6 +90,15 @@ class least_used_strategy implements \question_variant_selection_strategy { return $this->selectedvariant[$seed]; } + // Catch a possible programming error, and make the problem clear. + if (!isset($this->variantsusecounts[$seed])) { + debugging('Variant requested for unknown seed ' . $seed . '. ' . + 'You must add all questions to the usage before creating the least_used_strategy. ' . + 'Continuing, but the variant choses may not actually be least used.', + DEBUG_DEVELOPER); + $this->variantsusecounts[$seed] = array(); + } + if ($maxvariants > 2 * count($this->variantsusecounts[$seed])) { // Many many more variants exist than have been used so far. // It will be quicker to just pick until we miss a collision.