From 0a122a6dbd9e87e83f072ac6550632bb67199d3d Mon Sep 17 00:00:00 2001 From: Philipp Imhof <52650214+PhilippImhof@users.noreply.github.com> Date: Fri, 31 Jul 2026 17:17:48 +0200 Subject: [PATCH 1/5] add option to hide correct answer from feedback --- .../backup_qtype_formulas_plugin.class.php | 4 +-- .../restore_qtype_formulas_plugin.class.php | 7 +++++ classes/local/formulas_part.php | 3 ++ db/install.xml | 3 +- db/upgrade.php | 16 ++++++++++ edit_formulas_form.php | 8 +++++ lang/en/qtype_formulas.php | 2 ++ questiontype.php | 15 +++++++--- renderer.php | 4 +++ tests/helper.php | 29 +++++++++++++++++++ tests/renderer_test.php | 18 ++++++++++++ 11 files changed, 102 insertions(+), 7 deletions(-) diff --git a/backup/moodle2/backup_qtype_formulas_plugin.class.php b/backup/moodle2/backup_qtype_formulas_plugin.class.php index 7ecc82d1..c1dac69c 100644 --- a/backup/moodle2/backup_qtype_formulas_plugin.class.php +++ b/backup/moodle2/backup_qtype_formulas_plugin.class.php @@ -52,8 +52,8 @@ protected function define_question_plugin_structure() { $formulasanswer = new backup_nested_element('formulas_answer', ['id'], [ 'partindex', 'placeholder', 'answermark', 'answertype', 'numbox', 'vars1', 'answer', 'answernotunique', 'vars2', 'correctness', 'unitpenalty', 'postunit', 'ruleid', 'otherrule', 'subqtext', 'subqtextformat', 'feedback', - 'feedbackformat', 'partcorrectfb', 'partcorrectfbformat', 'partpartiallycorrectfb', 'partpartiallycorrectfbformat', - 'partincorrectfb', 'partincorrectfbformat', + 'feedbackformat', 'hidecorrectanswer', 'partcorrectfb', 'partcorrectfbformat', 'partpartiallycorrectfb', + 'partpartiallycorrectfbformat', 'partincorrectfb', 'partincorrectfbformat', ]); // Don't need to annotate ids nor files. diff --git a/backup/moodle2/restore_qtype_formulas_plugin.class.php b/backup/moodle2/restore_qtype_formulas_plugin.class.php index 2ace8a39..a2de11d8 100644 --- a/backup/moodle2/restore_qtype_formulas_plugin.class.php +++ b/backup/moodle2/restore_qtype_formulas_plugin.class.php @@ -148,6 +148,10 @@ public function process_formulas_answer($data) { if (!isset($data->answernotunique)) { $data->answernotunique = '1'; } + // Older backups might not yet have the hidecorrectanswer field. + if (!isset($data->hidecorrectanswer)) { + $data->hidecorrectanswer = '0'; + } // Insert record. $newitemid = $DB->insert_record('qtype_formulas_answers', $data); // Create mapping. @@ -194,6 +198,9 @@ public static function convert_backup_to_questiondata(array $backupdata): stdCla if (!key_exists('answernotunique', $answer)) { $answer['answernotunique'] = '1'; } + if (!key_exists('hidecorrectanswer', $answer)) { + $answer['hidecorrectanswer'] = '0'; + } if (!key_exists('partindex', $answer)) { $answer['partindex'] = $i; } diff --git a/classes/local/formulas_part.php b/classes/local/formulas_part.php index 5d07dcce..8cc12a05 100644 --- a/classes/local/formulas_part.php +++ b/classes/local/formulas_part.php @@ -110,6 +110,9 @@ class formulas_part { /** @var int format constant (FORMAT_MOODLE, FORMAT_HTML, FORMAT_PLAIN or FORMAT_MARKDOWN) */ public int $feedbackformat; + /** @var int whether the correct answer should be hidden from the feedback */ + public int $hidecorrectanswer; + /** @var string part's feedback for any correct response */ public string $partcorrectfb; diff --git a/db/install.xml b/db/install.xml index bc96d055..afda3c20 100644 --- a/db/install.xml +++ b/db/install.xml @@ -1,5 +1,5 @@ - @@ -46,6 +46,7 @@ + diff --git a/db/upgrade.php b/db/upgrade.php index ac7b27c4..10fa7cc3 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -546,5 +546,21 @@ function xmldb_qtype_formulas_upgrade($oldversion = 0) { upgrade_plugin_savepoint(true, 2023100800, 'qtype', 'formulas'); } + if ($oldversion < 2026073100) { + // Define field hidecorrectanswer to be added to qtype_formulas_answers. + $table = new xmldb_table('qtype_formulas_answers'); + $field = new xmldb_field('hidecorrectanswer', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'feedbackformat'); + + // Conditionally add field. + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + // Now fill it with '1' for compatibility with existing questions'. + $DB->set_field('qtype_formulas_answers', 'hidecorrectanswer', '0'); + } + + // Formulas savepoint reached. + upgrade_plugin_savepoint(true, 2026073100, 'qtype', 'formulas'); + } + return true; } diff --git a/edit_formulas_form.php b/edit_formulas_form.php index 366d7552..52270f59 100644 --- a/edit_formulas_form.php +++ b/edit_formulas_form.php @@ -327,6 +327,14 @@ protected function get_per_answer_fields( ); $repeatedoptions['feedback']['helpbutton'] = ['feedback', 'qtype_formulas']; $repeatedoptions['feedback']['advanced'] = true; + // Option to hide the correct answer, e. g. because it is included in the general feedback. + $repeated[] = $mform->createElement( + 'advcheckbox', + 'hidecorrectanswer', + get_string('hidecorrectanswer', 'qtype_formulas'), + ); + $repeatedoptions['hidecorrectanswer']['helpbutton'] = ['hidecorrectanswer', 'qtype_formulas']; + $repeatedoptions['hidecorrectanswer']['advanced'] = true; // Part's combined feedback. $repeated[] = $mform->createElement( 'editor', diff --git a/lang/en/qtype_formulas.php b/lang/en/qtype_formulas.php index 2d409316..aca46899 100644 --- a/lang/en/qtype_formulas.php +++ b/lang/en/qtype_formulas.php @@ -268,6 +268,8 @@ $string['feedback'] = 'Part general feedback'; $string['feedback_help'] = 'This part feedback will be shown to all students. It can include global and local variables that will be replaced by their values.'; $string['globalvarshdr'] = 'Variables'; +$string['hidecorrectanswer'] = 'Do not show the correct answer along with the general feedback.'; +$string['hidecorrectanswer_help'] = 'In some cases, the model answer might not be displayed in a way that suits the teacher\'s needs, e. g. for more elaborate questions. The teacher might then use the general feedback to displayed the correct answer according to their wishes. In that case, it can make sense to hide the standard "correct answer" feedback to avoid redundancy and confusion.'; $string['incorrectfeedback'] = 'For any incorrect response'; $string['incorrectfeedback_help'] = 'This feedback will be shown to students that don\'t get any mark at this part. It can include global and local variables that will be replaced by their values.'; $string['instantiate'] = 'Instantiate'; diff --git a/questiontype.php b/questiontype.php index d5302758..535287e3 100644 --- a/questiontype.php +++ b/questiontype.php @@ -74,15 +74,17 @@ class qtype_formulas extends question_type { * - numbox: number of answers for this part, not including a possible unit field * - vars1: the part's local variables * - answer: the model answer(s) for this part + * - answernotunique: whether there is more than one correct answer * - vars2: the part's grading variables * - correctness: the part's grading criterion * - unitpenalty: deduction to be made for wrong units * - postunit: the unit in which the model answer has been entered * - ruleid: ruleset used for unit conversion * - otherrule: additional rules for unit conversion + * - hidecorrectanswer: whether the correct answer should be shown along with the general feedback */ const PART_BASIC_FIELDS = ['placeholder', 'answermark', 'answertype', 'numbox', 'vars1', 'answer', 'answernotunique', 'vars2', - 'correctness', 'unitpenalty', 'postunit', 'ruleid', 'otherrule']; + 'correctness', 'unitpenalty', 'postunit', 'ruleid', 'otherrule', 'hidecorrectanswer']; /** * This function returns the "simple" additional fields defined in the qtype_formulas_options @@ -287,6 +289,7 @@ public function save_question_options($formdata) { 'answernotunique' => 1, 'correctness' => '', 'ruleid' => 1, + 'hidecorrectanswer' => 0, 'subqtext' => '', 'subqtextformat' => FORMAT_HTML, 'feedback' => '', @@ -623,16 +626,20 @@ public function import_from_xml($xml, $question, qformat_xml $format, $extra = n $question->partindex[$i] = $partindex; } foreach (self::PART_BASIC_FIELDS as $field) { - // Older questions do not have this field, so we do not want to issue an error message. - // Also, for maximum backwards compatibility, we set the default value to 1. With this, - // nothing changes for old questions. + // Older questions do not have these fields, so we do not want to issue an error message. + // Also, for maximum backwards compatibility, we set the default value to 1 for 'anwernotunique' + // and to 0 for 'hidecorrectanswer'. With this, nothing changes for old questions. if ($field === 'answernotunique') { $ifnotexists = ''; $default = '1'; + } else if ($field === 'hidecorrectanswer') { + $ifnotexists = ''; + $default = '0'; } else { $ifnotexists = get_string('error_import_missing_field', 'qtype_formulas', $field); $default = '0'; } + $question->{$field}[$i] = $format->getpath( $part, ['#', $field, 0, '#', 'text', 0, '#'], diff --git a/renderer.php b/renderer.php index 21b12b3e..c85f615a 100644 --- a/renderer.php +++ b/renderer.php @@ -853,6 +853,10 @@ public function correct_response(question_attempt $qa) { * @return string HTML fragment */ public function part_correct_response($part) { + if ($part->hidecorrectanswer) { + return ''; + } + $answers = $part->get_correct_response(true); $answertext = implode('; ', $answers); diff --git a/tests/helper.php b/tests/helper.php index 0f351115..cc7ed92d 100644 --- a/tests/helper.php +++ b/tests/helper.php @@ -122,6 +122,7 @@ public static function make_a_formulas_part(): formulas_part { $p->subqtextformat = FORMAT_HTML; $p->feedback = ''; $p->feedbackformat = FORMAT_HTML; + $p->hidecorrectanswer = '0'; $p->partcorrectfb = self::DEFAULT_CORRECT_FEEDBACK; $p->partcorrectfbformat = FORMAT_HTML; $p->partpartiallycorrectfb = self::DEFAULT_PARTIALLYCORRECT_FEEDBACK; @@ -190,6 +191,7 @@ public function get_formulas_question_form_data_testalgebraic() { $form->otherrule = ['']; $form->subqtext = [['text' => '', 'format' => FORMAT_HTML]]; $form->feedback = [['text' => '', 'format' => FORMAT_HTML]]; + $form->hidecorrectanswer = ['0']; $form->partcorrectfb = [['text' => 'Your answer is correct.', 'format' => FORMAT_HTML]]; $form->partpartiallycorrectfb = [['text' => 'Your answer is partially correct.', 'format' => FORMAT_HTML]]; $form->partincorrectfb = [['text' => 'Your answer is incorrect.', 'format' => FORMAT_HTML]]; @@ -276,6 +278,7 @@ public function get_formulas_question_form_data_testsinglenum(): stdClass { $form->feedback = [ ['text' => '', 'format' => FORMAT_HTML], ]; + $form->hidecorrectanswer = ['0']; $form->partcorrectfb = [ ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], ]; @@ -364,6 +367,7 @@ public static function get_formulas_question_data_testsinglenum(): stdClass { 'subqtextformat' => FORMAT_HTML, 'feedback' => '', 'feedbackformat' => FORMAT_HTML, + 'hidecorrectanswer' => '0', 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, 'partcorrectfbformat' => FORMAT_HTML, 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, @@ -454,6 +458,7 @@ public function get_formulas_question_form_data_testsinglenumunit() { $form->feedback = [ ['text' => '', 'format' => FORMAT_HTML], ]; + $form->hidecorrectanswer = ['0']; $form->partcorrectfb = [ ['text' => '

Correct answer, well done.

', 'format' => FORMAT_HTML], ]; @@ -536,6 +541,7 @@ public static function get_formulas_question_data_testsinglenumunit(): stdClass 'subqtextformat' => FORMAT_HTML, 'feedback' => '', 'feedbackformat' => FORMAT_HTML, + 'hidecorrectanswer' => '0', 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, 'partcorrectfbformat' => FORMAT_HTML, 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, @@ -612,6 +618,7 @@ public function get_formulas_question_form_data_testsinglenumunitsep() { $form->feedback = [ ['text' => '', 'format' => FORMAT_HTML], ]; + $form->hidecorrectanswer = ['0']; $form->partcorrectfb = [ ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], ]; @@ -693,6 +700,7 @@ public static function get_formulas_question_data_testsinglenumunitsep(): stdCla 'subqtextformat' => FORMAT_HTML, 'feedback' => '', 'feedbackformat' => FORMAT_HTML, + 'hidecorrectanswer' => '0', 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, 'partcorrectfbformat' => FORMAT_HTML, 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, @@ -769,6 +777,7 @@ public function get_formulas_question_form_data_testtwonums() { $form->feedback = [ ['text' => '', 'format' => FORMAT_HTML], ]; + $form->hidecorrectanswer = ['0']; $form->partcorrectfb = [ ['text' => 'Your answer is correct.', 'format' => FORMAT_HTML], ]; @@ -894,6 +903,7 @@ public function get_formulas_question_form_data_testthreeparts() { ['text' => '', 'format' => FORMAT_HTML], ['text' => '', 'format' => FORMAT_HTML], ]; + $form->hidecorrectanswer = ['0', '0', '0']; $form->partcorrectfb = [ ['text' => 'Part 1 correct feedback.', 'format' => FORMAT_HTML], ['text' => 'Part 2 correct feedback.', 'format' => FORMAT_HTML], @@ -1055,6 +1065,7 @@ public static function get_formulas_question_data_testmethodsinparts() { 'subqtextformat' => FORMAT_HTML, 'feedback' => '', 'feedbackformat' => FORMAT_HTML, + 'hidecorrectanswer' => '0', 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, 'partcorrectfbformat' => FORMAT_HTML, 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, @@ -1083,6 +1094,7 @@ public static function get_formulas_question_data_testmethodsinparts() { 'subqtextformat' => FORMAT_HTML, 'feedback' => '', 'feedbackformat' => FORMAT_HTML, + 'hidecorrectanswer' => '0', 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, 'partcorrectfbformat' => FORMAT_HTML, 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, @@ -1111,6 +1123,7 @@ public static function get_formulas_question_data_testmethodsinparts() { 'subqtextformat' => FORMAT_HTML, 'feedback' => '', 'feedbackformat' => FORMAT_HTML, + 'hidecorrectanswer' => '0', 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, 'partcorrectfbformat' => FORMAT_HTML, 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, @@ -1139,6 +1152,7 @@ public static function get_formulas_question_data_testmethodsinparts() { 'subqtextformat' => FORMAT_HTML, 'feedback' => '', 'feedbackformat' => FORMAT_HTML, + 'hidecorrectanswer' => '0', 'partcorrectfb' => self::DEFAULT_CORRECT_FEEDBACK, 'partcorrectfbformat' => FORMAT_HTML, 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, @@ -1282,6 +1296,12 @@ public function get_formulas_question_form_data_testmethodsinparts() { 2 => ['text' => '', 'format' => FORMAT_HTML], 3 => ['text' => '', 'format' => FORMAT_HTML], ]; + $form->hidecorrectanswer = [ + 0 => '0', + 1 => '0', + 2 => '0', + 3 => '0', + ]; $form->partcorrectfb = [ 0 => ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], 1 => ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], @@ -1369,6 +1389,7 @@ public function get_formulas_question_form_data_testzero() { $form->feedback = [ ['text' => '', 'format' => FORMAT_HTML], ]; + $form->hidecorrectanswer = ['0']; $form->partcorrectfb = [ ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], ]; @@ -1516,6 +1537,7 @@ public function get_formulas_question_form_data_test4() { ['text' => '', 'format' => FORMAT_HTML], ['text' => '', 'format' => FORMAT_HTML], ]; + $form->hidecorrectanswer = ['0', '0', '0', '0']; $form->partcorrectfb = [ ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], @@ -1604,6 +1626,7 @@ public function get_formulas_question_form_data_testmc() { $form->feedback = [ ['text' => '', 'format' => FORMAT_HTML], ]; + $form->hidecorrectanswer = ['0']; $form->partcorrectfb = [ ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], ]; @@ -1687,6 +1710,7 @@ public function get_formulas_question_form_data_testmce() { $form->feedback = [ ['text' => '', 'format' => FORMAT_HTML], ]; + $form->hidecorrectanswer = ['0']; $form->partcorrectfb = [ ['text' => self::DEFAULT_CORRECT_FEEDBACK, 'format' => FORMAT_HTML], ]; @@ -1785,6 +1809,7 @@ public function get_formulas_question_form_data_testmcetwoparts() { 0 => ['text' => '', 'format' => FORMAT_HTML], 1 => ['text' => '', 'format' => FORMAT_HTML], ]; + $form->hidecorrectanswer = ['0', '0']; $form->partcorrectfb = [ 0 => ['text' => 'Your first answer is correct.', 'format' => FORMAT_HTML], 1 => ['text' => 'Your second answer is correct.', 'format' => FORMAT_HTML], @@ -1887,6 +1912,7 @@ public function get_formulas_question_form_data_testmctwoparts() { 0 => ['text' => '', 'format' => FORMAT_HTML], 1 => ['text' => '', 'format' => FORMAT_HTML], ]; + $form->hidecorrectanswer = ['0', '0']; $form->partcorrectfb = [ 0 => ['text' => 'Your first answer is correct.', 'format' => FORMAT_HTML], 1 => ['text' => 'Your second answer is correct.', 'format' => FORMAT_HTML], @@ -1994,6 +2020,7 @@ public function get_formulas_question_form_data_testtwoandtwo() { 0 => ['text' => '', 'format' => FORMAT_HTML], 1 => ['text' => '', 'format' => FORMAT_HTML], ]; + $form->hidecorrectanswer = ['0', '0']; $form->partcorrectfb = [ 0 => ['text' => 'Your answers in part 1 are correct.', 'format' => FORMAT_HTML], 1 => ['text' => 'Your answers in part 2 are correct.', 'format' => FORMAT_HTML], @@ -2088,6 +2115,7 @@ public static function get_formulas_question_data_testtwoandtwo(): stdClass { 'subqtextformat' => FORMAT_HTML, 'feedback' => '', 'feedbackformat' => FORMAT_HTML, + 'hidecorrectanswer' => '0', 'partcorrectfb' => 'Your answers in part 1 are correct.', 'partcorrectfbformat' => FORMAT_HTML, 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, @@ -2116,6 +2144,7 @@ public static function get_formulas_question_data_testtwoandtwo(): stdClass { 'subqtextformat' => FORMAT_HTML, 'feedback' => '', 'feedbackformat' => FORMAT_HTML, + 'hidecorrectanswer' => '0', 'partcorrectfb' => 'Your answers in part 2 are correct.', 'partcorrectfbformat' => FORMAT_HTML, 'partpartiallycorrectfb' => self::DEFAULT_PARTIALLYCORRECT_FEEDBACK, diff --git a/tests/renderer_test.php b/tests/renderer_test.php index e1d2f36c..ac4acbc2 100644 --- a/tests/renderer_test.php +++ b/tests/renderer_test.php @@ -1294,4 +1294,22 @@ public function test_general_feedback_visibility_in_adaptive_mode(): void { $this->process_submission(['-finish' => 1]); $this->check_output_contains($generalfeedback); } + + public function test_hiding_correct_answer(): void { + // Create the requested question. + $q = $this->get_test_formulas_question('testsinglenum'); + + // Start question and submit wrong answer. The correct answer should be shown. + $this->start_attempt_at_question($q, 'immediatefeedback', 1); + $this->process_submission(['0_0' => '4', '-submit' => 1]); + $this->check_output_contains_lang_string('correctansweris', 'qtype_formulas', '5'); + + // Change setting. + $q->parts[0]->hidecorrectanswer = '1'; + + // Submit a wrong answer again. Now the correct answer should not be shown. + $this->start_attempt_at_question($q, 'immediatefeedback', 1); + $this->process_submission(['0_0' => '4', '-submit' => 1]); + $this->check_output_does_not_contain(get_string('correctansweris', 'qtype_formulas', '5')); + } } From 3e18c6035f92eaa43f345aea818dbd8dce3ce888 Mon Sep 17 00:00:00 2001 From: Philipp Imhof <52650214+PhilippImhof@users.noreply.github.com> Date: Fri, 31 Jul 2026 17:46:53 +0200 Subject: [PATCH 2/5] fix tests --- tests/behat/export.feature | 2 +- version.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/behat/export.feature b/tests/behat/export.feature index 1bdc0839..3068ff46 100644 --- a/tests/behat/export.feature +++ b/tests/behat/export.feature @@ -27,7 +27,7 @@ Feature: Test exporting Formulas questions When I am on the "Course 1" "core_question > course question export" page And I set the field "id_format_xml" to "1" And I press "Export questions to file" - Then following "click here" should download between "6250" and "6500" bytes + Then following "click here" should download between "6500" and "6750" bytes # If the download step is the last in the scenario then we can sometimes run # into the situation where the download page causes a http redirect but behat # has already conducted its reset (generating an error). By putting a logout diff --git a/version.php b/version.php index 11ccb2a1..48560ade 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'qtype_formulas'; -$plugin->version = 2026070300; +$plugin->version = 2026073100; $plugin->cron = 0; $plugin->requires = 2024100700; From 67ad965e6973ba2c686c2b59f24462bcef4dc86c Mon Sep 17 00:00:00 2001 From: Philipp Imhof <52650214+PhilippImhof@users.noreply.github.com> Date: Fri, 31 Jul 2026 18:02:07 +0200 Subject: [PATCH 3/5] missed coverage, code style --- tests/backup_restore_test.php | 3 +++ tests/renderer_test.php | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/backup_restore_test.php b/tests/backup_restore_test.php index 5c6a6cf3..298ce9cc 100644 --- a/tests/backup_restore_test.php +++ b/tests/backup_restore_test.php @@ -306,6 +306,7 @@ public function test_restore_quiz_with_same_stamp_questions(string $questionname */ public static function provide_xml_keys_to_remove(): array { return [ + ['hidecorrectanswer'], ['answernotunique'], ['partindex'], ]; @@ -441,6 +442,7 @@ public function test_restore_of_legacy_backup_with_missing_fields(): void { 'shownumcorrect' => 0, 'answernumbering' => 'none', 'feedbackformat' => FORMAT_HTML, + 'hidecorrectanswer' => '0', 'partindex' => null, 'correctfeedback' => '', 'partiallycorrectfeedback' => '', @@ -1097,6 +1099,7 @@ public static function provide_edited_option_fields(): array { ['otherrule', '60 s = 1 min'], ['subqtext', 'edited'], ['feedback', 'edited'], + ['hidecorrectanswer', '1'], ['partcorrectfb', 'edited'], ['partpartiallycorrectfb', 'edited'], ['partincorrectfb', 'edited'], diff --git a/tests/renderer_test.php b/tests/renderer_test.php index ac4acbc2..50218590 100644 --- a/tests/renderer_test.php +++ b/tests/renderer_test.php @@ -1248,9 +1248,10 @@ public function test_part_feedback($expectedfeedback, $input): void { $this->check_output_does_not_contain($feedback); } } - // In adaptive and interactive mode, the general feedback should not be shown if the student can still improve their grade, - // i. e. if their answer is not yet correct and there are tries left. (For adaptive mode, the number of tries is not limited, - // but after a certain number of wrong answers, the student will have too many penalties and cannot get a grade > 0 anymore. + // In adaptive and interactive mode, the general feedback should not be shown if the student can still improve their + // grade, i. e. if their answer is not yet correct and there are tries left. (For adaptive mode, the number of tries + // is not limited, but after a certain number of wrong answers, the student will have too many penalties and cannot get + // a grade > 0 anymore. if ($input['behaviour'] === 'immediatefeedback' || $expectedfeedback === qtype_formulas_test_helper::DEFAULT_CORRECT_FEEDBACK) { $this->check_output_contains($generalfeedback); } else { From 1c0777c1a37acb4c50f1ba681858dd4ace0e110b Mon Sep 17 00:00:00 2001 From: Philipp Imhof <52650214+PhilippImhof@users.noreply.github.com> Date: Sat, 1 Aug 2026 08:23:31 +0200 Subject: [PATCH 4/5] code style --- tests/renderer_test.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/renderer_test.php b/tests/renderer_test.php index 50218590..82a52e6b 100644 --- a/tests/renderer_test.php +++ b/tests/renderer_test.php @@ -1252,7 +1252,10 @@ public function test_part_feedback($expectedfeedback, $input): void { // grade, i. e. if their answer is not yet correct and there are tries left. (For adaptive mode, the number of tries // is not limited, but after a certain number of wrong answers, the student will have too many penalties and cannot get // a grade > 0 anymore. - if ($input['behaviour'] === 'immediatefeedback' || $expectedfeedback === qtype_formulas_test_helper::DEFAULT_CORRECT_FEEDBACK) { + if ( + $input['behaviour'] === 'immediatefeedback' + || $expectedfeedback === qtype_formulas_test_helper::DEFAULT_CORRECT_FEEDBACK + ) { $this->check_output_contains($generalfeedback); } else { $this->check_output_does_not_contain($generalfeedback); From c014a32fe790058fc30c6b281c463e5e5d676d93 Mon Sep 17 00:00:00 2001 From: Philipp Imhof <52650214+PhilippImhof@users.noreply.github.com> Date: Sun, 2 Aug 2026 19:28:02 +0200 Subject: [PATCH 5/5] change language --- lang/en/qtype_formulas.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/en/qtype_formulas.php b/lang/en/qtype_formulas.php index aca46899..97336dd8 100644 --- a/lang/en/qtype_formulas.php +++ b/lang/en/qtype_formulas.php @@ -268,8 +268,8 @@ $string['feedback'] = 'Part general feedback'; $string['feedback_help'] = 'This part feedback will be shown to all students. It can include global and local variables that will be replaced by their values.'; $string['globalvarshdr'] = 'Variables'; -$string['hidecorrectanswer'] = 'Do not show the correct answer along with the general feedback.'; -$string['hidecorrectanswer_help'] = 'In some cases, the model answer might not be displayed in a way that suits the teacher\'s needs, e. g. for more elaborate questions. The teacher might then use the general feedback to displayed the correct answer according to their wishes. In that case, it can make sense to hide the standard "correct answer" feedback to avoid redundancy and confusion.'; +$string['hidecorrectanswer'] = 'Do not show the correct answer along with the part\'s general feedback.'; +$string['hidecorrectanswer_help'] = 'In some cases, the model answer might not be displayed in a way that suits the teacher\'s needs, e. g. for more elaborate questions. The teacher might then use the general feedback to displayed the correct answer according to their wishes. In that case, it can make sense to hide the standard "correct answer" message to avoid redundancy and confusion.'; $string['incorrectfeedback'] = 'For any incorrect response'; $string['incorrectfeedback_help'] = 'This feedback will be shown to students that don\'t get any mark at this part. It can include global and local variables that will be replaced by their values.'; $string['instantiate'] = 'Instantiate';