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..97336dd8 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 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'; 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/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/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/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..82a52e6b 100644 --- a/tests/renderer_test.php +++ b/tests/renderer_test.php @@ -1248,10 +1248,14 @@ 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. - if ($input['behaviour'] === 'immediatefeedback' || $expectedfeedback === qtype_formulas_test_helper::DEFAULT_CORRECT_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. + 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); @@ -1294,4 +1298,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')); + } } 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;