From a8de866712a15f32dac6fb28dd45d9816a918fb9 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Fri, 17 Oct 2014 14:34:20 +0100 Subject: [PATCH] MDL-47740 question engine: let qs update variant later if appropriate Variant has two purposes. First to determine which version of the question the student will see. Hence it is used to set up the state of the quetsion when the question is started. Then the internal state of the question is saved in the first step. Once that has been done, the variant number is purely informative, and just used to break down the statistics. In some cases (the one I have in mind is qtype_opaque) then there is a complex randomisation process, which may lead to several inital variant numbers acutally giving the same version of the question. In this case it is nice if the question can update the stored variant number, to make the statistics more meaningful. --- question/engine/datalib.php | 1 + question/engine/questionattempt.php | 3 ++ question/engine/questionattemptstep.php | 49 +++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/question/engine/datalib.php b/question/engine/datalib.php index 61910e8e01b..6bec522be8e 100644 --- a/question/engine/datalib.php +++ b/question/engine/datalib.php @@ -867,6 +867,7 @@ ORDER BY public function update_question_attempt(question_attempt $qa) { $record = new stdClass(); $record->id = $qa->get_database_id(); + $record->variant = $qa->get_variant(); $record->maxmark = $qa->get_max_mark(); $record->minfraction = $qa->get_min_fraction(); $record->maxfraction = $qa->get_max_fraction(); diff --git a/question/engine/questionattempt.php b/question/engine/questionattempt.php index 3d1c55b96d5..8a59289d595 100644 --- a/question/engine/questionattempt.php +++ b/question/engine/questionattempt.php @@ -1178,6 +1178,9 @@ class question_attempt { if ($pendingstep->response_summary_changed()) { $this->responsesummary = $pendingstep->get_new_response_summary(); } + if ($pendingstep->variant_number_changed()) { + $this->variant = $pendingstep->get_new_variant_number(); + } } } diff --git a/question/engine/questionattemptstep.php b/question/engine/questionattemptstep.php index e18f9970ff9..101a37f5098 100644 --- a/question/engine/questionattemptstep.php +++ b/question/engine/questionattemptstep.php @@ -432,15 +432,23 @@ class question_attempt_step { /** - * A subclass with a bit of additional funcitonality, for pending steps. + * A subclass of {@link question_attempt_step} used when processing a new submission. + * + * When we are processing some new submitted data, which may or may not lead to + * a new step being added to the {@link question_usage_by_activity} we create an + * instance of this class. which is then passed to the question behaviour and question + * type for processing. At the end of processing we then may, or may not, keep it. * * @copyright 2010 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class question_attempt_pending_step extends question_attempt_step { - /** @var string . */ + /** @var string the new response summary, if there is one. */ protected $newresponsesummary = null; + /** @var int the new variant number, if there is one. */ + protected $newvariant = null; + /** * If as a result of processing this step, the response summary for the * question attempt should changed, you should call this method to set the @@ -451,15 +459,48 @@ class question_attempt_pending_step extends question_attempt_step { $this->newresponsesummary = $responsesummary; } - /** @return string the new response summary, if any. */ + /** + * Get the new response summary, if there is one. + * @return string the new response summary, or null if it has not changed. + */ public function get_new_response_summary() { return $this->newresponsesummary; } - /** @return string whether this step changes the response summary. */ + /** + * Whether this processing this step has changed the response summary. + * @return bool true if there is a new response summary. + */ public function response_summary_changed() { return !is_null($this->newresponsesummary); } + + /** + * If as a result of processing this step, you identify that this variant of the + * question is acutally identical to the another one, you may change the + * variant number recorded, in order to give better statistics. For an example + * see qbehaviour_opaque. + * @param int $variant the new variant number. + */ + public function set_new_variant_number($variant) { + $this->newvariant = $variant; + } + + /** + * Get the new variant number, if there is one. + * @return int the new variant number, or null if it has not changed. + */ + public function get_new_variant_number() { + return $this->newvariant; + } + + /** + * Whether this processing this step has changed the variant number. + * @return bool true if there is a new variant number. + */ + public function variant_number_changed() { + return !is_null($this->newvariant); + } }