From 3905042aacfa9749882e2636ab0f4f46442979e7 Mon Sep 17 00:00:00 2001 From: Pol Torrent i Soler Date: Tue, 12 Mar 2024 16:43:07 +0100 Subject: [PATCH 1/5] fix: handle multiple attempt regrade for multianswer --- question.php | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/question.php b/question.php index d514a90..87fbdf3 100644 --- a/question.php +++ b/question.php @@ -19,7 +19,7 @@ require_once($CFG->dirroot . '/question/type/wq/step.php'); class qtype_shortanswerwiris_question extends qtype_wq_question - implements question_automatically_gradable, question_response_answer_comparer { +implements question_automatically_gradable, question_response_answer_comparer { /** * A link to last question attempt step and also a helper class for some * grading issues. @@ -84,9 +84,16 @@ public function grade_response(array $response) { // Multiply Moodle fraction by quizzes grade (due to custom function // grading or compound grade distribution). $grade = $this->step->get_var('_matching_answer_grade'); + + if (empty($grade)) { + $responsehash = md5($response['answer']); + $grade = $this->step->get_var('_' . substr($responsehash, 0, 6) . '_matching_answer_grade'); + } + if (!empty($grade)) { $fraction = $fraction * $grade; } + $state = question_state::graded_state_for_fraction($fraction); return array($fraction, $state); } else if ($this->step->is_error()) { @@ -109,8 +116,11 @@ public function get_matching_answer_fail_test(array $response) { $conditiona = isset($CFG->wq_fail_shortanswer_grade) && $CFG->wq_fail_shortanswer_grade; if ($conditiona && $CFG->wq_fail_shortanswer_grade != 'false') { $fail = explode("@", $CFG->wq_fail_shortanswer_grade); - $attemptid = $DB->get_record('question_attempt_steps', - array('id' => $this->step->step_id), 'questionattemptid')->questionattemptid; + $attemptid = $DB->get_record( + 'question_attempt_steps', + array('id' => $this->step->step_id), + 'questionattemptid' + )->questionattemptid; $attemptid = $DB->get_record('question_attempts', array('id' => $attemptid), 'questionusageid')->questionusageid; $activity = $DB->get_field('question_usages', 'component', array('id' => $attemptid)); if ($activity == 'mod_quiz') { @@ -133,8 +143,11 @@ public function get_matching_answer_fail_test(array $response) { } // Used to simulate a grade failure when doing tests! if ($error) { - throw new moodle_exception(get_string('failedtogradetest', 'qtype_shortanswerwiris', - ($this->step->get_attempts() + 1)), 'qtype_wq'); + throw new moodle_exception(get_string( + 'failedtogradetest', + 'qtype_shortanswerwiris', + ($this->step->get_attempts() + 1) + ), 'qtype_wq'); } // END TEST. } @@ -145,10 +158,18 @@ public function get_matching_answer(array $response) { if (!isset($response['answer']) || $response['answer'] === null) { return null; } + // Optimization in order to avoid a service call. $responsehash = md5($response['answer']); - if ($this->step->get_var('_response_hash') == $responsehash) { + $cachedresponses = $this->step->get_var('_response_hash') ?? ''; + + if (str_contains($cachedresponses, $responsehash)) { $matchinganswer = $this->step->get_var('_matching_answer'); + + if (empty($matchinganswer)) { + $matchinganswer = $this->step->get_var('_' . substr($responsehash, 0, 6) . '_matching_answer'); + } + if (!empty($matchinganswer)) { return $this->base->answers[$matchinganswer]; } else if (!is_null($matchinganswer)) { @@ -162,6 +183,11 @@ public function get_matching_answer(array $response) { return null; } + if ($this->parent) { + // Questions with parent should be graded together in multianswerwiris qtype! + throw new moodle_exception('Questions with parent should be graded together'); + } + // Test code: // Does nothing on production, may throw exception on test environment. $this->get_matching_answer_fail_test($response); @@ -192,7 +218,7 @@ public function get_matching_answer(array $response) { $max = 0.0; $maxwqgrade = 0.0; $matchinganswerposition = -1; - + for ($i = 0; $i < count($correctanswers); $i++) { $wqgrade = $qi->getAnswerGrade($i, 0, $this->wirisquestion); $grade = $wqgrade * $correctanswers[$i]->fraction; @@ -210,7 +236,7 @@ public function get_matching_answer(array $response) { // Backup matching answer. $matchinganswerid = 0; $answer = null; - + // Reset variable. $this->step->set_var('_matching_answer_grade', null); if ($matchinganswerposition != -1) { @@ -219,8 +245,9 @@ public function get_matching_answer(array $response) { if ($max < 1.0) { $this->step->set_var('_matching_answer_grade', $maxwqgrade, true); } - $this->step->set_var('_matching_answer_wq_position', $matchinganswerposition, true); + $this->step->set_var('_matching_answer_wq', $matchinganswerposition, true); } + $this->step->set_var('_matching_answer', $matchinganswerid, true); $this->step->set_var('_response_hash', $responsehash, true); $this->step->set_var('_qi', $qi->serialize(), true); From 8b02a7ea03b347ce6d345bea51ca8998a9d7469d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 15:44:27 +0000 Subject: [PATCH 2/5] chore(deps): bump tj-actions/branch-names in /.github/workflows Bumps [tj-actions/branch-names](https://github.com/tj-actions/branch-names) from 5.2 to 7.0.7. - [Release notes](https://github.com/tj-actions/branch-names/releases) - [Changelog](https://github.com/tj-actions/branch-names/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/branch-names/compare/v5.2...v7.0.7) --- updated-dependencies: - dependency-name: tj-actions/branch-names dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0224ca..9e9b6bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,7 +42,7 @@ jobs: steps: - name: Get branch name id: branch-name - uses: tj-actions/branch-names@v5.2 + uses: tj-actions/branch-names@v7.0.7 - name: Check out repository code uses: actions/checkout@v2 From 246dbb2f97d12de4ba40b22a26e1760b4aa18d93 Mon Sep 17 00:00:00 2001 From: Pol Torrent i Soler Date: Wed, 13 Mar 2024 15:24:16 +0100 Subject: [PATCH 3/5] refactor: move common logic to wirisstep --- question.php | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/question.php b/question.php index 87fbdf3..c73bc24 100644 --- a/question.php +++ b/question.php @@ -81,14 +81,10 @@ public function grade_response(array $response) { $answer = $this->get_matching_answer($response); if ($answer) { $fraction = $answer->fraction; + // Multiply Moodle fraction by quizzes grade (due to custom function // grading or compound grade distribution). - $grade = $this->step->get_var('_matching_answer_grade'); - - if (empty($grade)) { - $responsehash = md5($response['answer']); - $grade = $this->step->get_var('_' . substr($responsehash, 0, 6) . '_matching_answer_grade'); - } + $grade = $this->step->get_var_in_answer_cache('_matching_answer_grade', $response['answer']); if (!empty($grade)) { $fraction = $fraction * $grade; @@ -160,16 +156,11 @@ public function get_matching_answer(array $response) { } // Optimization in order to avoid a service call. - $responsehash = md5($response['answer']); - $cachedresponses = $this->step->get_var('_response_hash') ?? ''; - - if (str_contains($cachedresponses, $responsehash)) { - $matchinganswer = $this->step->get_var('_matching_answer'); - - if (empty($matchinganswer)) { - $matchinganswer = $this->step->get_var('_' . substr($responsehash, 0, 6) . '_matching_answer'); - } + $answer = $response['answer']; + $responsehash = md5($answer); + if ($this->step->is_answer_cached($answer)) { + $matchinganswer = $this->step->get_var_in_answer_cache('_matching_answer', $answer); if (!empty($matchinganswer)) { return $this->base->answers[$matchinganswer]; } else if (!is_null($matchinganswer)) { From c79f811fb27266d6d6ac91d8fd372fbab2f1e79f Mon Sep 17 00:00:00 2001 From: Pol Torrent i Soler Date: Sat, 23 Mar 2024 17:59:20 +0100 Subject: [PATCH 4/5] chore: bump version to v4.11.0 --- version.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version.php b/version.php index 989d88d..550a498 100644 --- a/version.php +++ b/version.php @@ -16,11 +16,11 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2024010801; +$plugin->version = 2024032200; $plugin->requires = 2015111600; // Moodle 3.0. -$plugin->release = '4.10.1'; +$plugin->release = '4.11.0'; $plugin->maturity = MATURITY_STABLE; $plugin->component = 'qtype_shortanswerwiris'; -$plugin->dependencies = array ( - 'qtype_wq' => 2024010801 +$plugin->dependencies = array( + 'qtype_wq' => 2024032200 ); From 492bc741e04dd15f43eabeb64f511e3edc113cb2 Mon Sep 17 00:00:00 2001 From: Pol Torrent i Soler Date: Tue, 2 Apr 2024 06:35:54 +0200 Subject: [PATCH 5/5] chore: bump version to v4.11.1 --- version.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/version.php b/version.php index 550a498..0f9c8e5 100644 --- a/version.php +++ b/version.php @@ -16,11 +16,11 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2024032200; +$plugin->version = 2024032201; $plugin->requires = 2015111600; // Moodle 3.0. -$plugin->release = '4.11.0'; +$plugin->release = '4.11.1'; $plugin->maturity = MATURITY_STABLE; $plugin->component = 'qtype_shortanswerwiris'; $plugin->dependencies = array( - 'qtype_wq' => 2024032200 + 'qtype_wq' => 2024032201 );