diff --git a/question/behaviour/interactive/tests/walkthrough_test.php b/question/behaviour/interactive/tests/walkthrough_test.php index 5f370f9f788..2f182c556ce 100644 --- a/question/behaviour/interactive/tests/walkthrough_test.php +++ b/question/behaviour/interactive/tests/walkthrough_test.php @@ -183,6 +183,7 @@ class qbehaviour_interactive_walkthrough_test extends qbehaviour_walkthrough_tes // Create a multichoice single question. $mc = test_question_maker::make_a_multichoice_single_question(); + $mc->showstandardinstruction = true; $mc->hints = array( new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, false, false), ); @@ -338,6 +339,7 @@ class qbehaviour_interactive_walkthrough_test extends qbehaviour_walkthrough_tes // Create a multichoice multiple question. $mc = test_question_maker::make_a_multichoice_multi_question(); + $mc->showstandardinstruction = true; $mc->hints = array( new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, true, true), new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true), diff --git a/question/engine/tests/helpers.php b/question/engine/tests/helpers.php index 8443178a075..13d48b93fff 100644 --- a/question/engine/tests/helpers.php +++ b/question/engine/tests/helpers.php @@ -329,6 +329,7 @@ class test_question_maker { $mc->shuffleanswers = 1; $mc->answernumbering = 'abc'; + $mc->showstandardinstruction = 0; $mc->answers = array( 13 => new question_answer(13, 'A', 1, 'A is right', FORMAT_HTML), @@ -355,6 +356,7 @@ class test_question_maker { $mc->shuffleanswers = 1; $mc->answernumbering = 'abc'; + $mc->showstandardinstruction = 0; self::set_standard_combined_feedback_fields($mc); diff --git a/question/format/xml/format.php b/question/format/xml/format.php index d2323d00afd..b2b71ffd1e5 100644 --- a/question/format/xml/format.php +++ b/question/format/xml/format.php @@ -439,6 +439,8 @@ class qformat_xml extends qformat_default { $qo->answernumbering = $this->getpath($question, array('#', 'answernumbering', 0, '#'), 'abc'); $qo->shuffleanswers = $this->trans_single($shuffleanswers); + $qo->showstandardinstruction = $this->getpath($question, + array('#', 'showstandardinstruction', 0, '#'), '1'); // There was a time on the 1.8 branch when it could output an empty // answernumbering tag, so fix up any found. @@ -1255,7 +1257,9 @@ class qformat_xml extends qformat_default { $this->get_single($question->options->shuffleanswers) . "\n"; $expout .= " " . $question->options->answernumbering . - "\n"; + "\n"; + $expout .= " " . $question->options->showstandardinstruction . + "\n"; $expout .= $this->write_combined_feedback($question->options, $question->id, $question->contextid); $expout .= $this->write_answers($question->options->answers); break; diff --git a/question/format/xml/tests/xmlformat_test.php b/question/format/xml/tests/xmlformat_test.php index c8cd52c41f8..0889ad55e29 100644 --- a/question/format/xml/tests/xmlformat_test.php +++ b/question/format/xml/tests/xmlformat_test.php @@ -893,6 +893,7 @@ END; $qdata->options->single = 0; $qdata->options->shuffleanswers = 0; $qdata->options->answernumbering = 'abc'; + $qdata->options->showstandardinstruction = 0; $qdata->options->correctfeedback = '

Your answer is correct.

'; $qdata->options->correctfeedbackformat = FORMAT_HTML; $qdata->options->partiallycorrectfeedback = '

Your answer is partially correct.

'; @@ -934,6 +935,7 @@ END; false false abc + 0 Your answer is correct.

]]>
diff --git a/question/type/multichoice/backup/moodle1/lib.php b/question/type/multichoice/backup/moodle1/lib.php index b31c80ba193..1ccfa724a4c 100644 --- a/question/type/multichoice/backup/moodle1/lib.php +++ b/question/type/multichoice/backup/moodle1/lib.php @@ -62,6 +62,7 @@ class moodle1_qtype_multichoice_handler extends moodle1_qtype_handler { 'incorrectfeedback' => '', 'incorrectfeedbackformat' => FORMAT_HTML, 'answernumbering' => 'abc', + 'showstandardinstruction' => 0 )); } $this->write_multichoice($data['multichoice'], $data['oldquestiontextformat'], $data['id']); diff --git a/question/type/multichoice/backup/moodle2/backup_qtype_multichoice_plugin.class.php b/question/type/multichoice/backup/moodle2/backup_qtype_multichoice_plugin.class.php index fa9441ce2c0..b8277eec655 100644 --- a/question/type/multichoice/backup/moodle2/backup_qtype_multichoice_plugin.class.php +++ b/question/type/multichoice/backup/moodle2/backup_qtype_multichoice_plugin.class.php @@ -56,7 +56,8 @@ class backup_qtype_multichoice_plugin extends backup_qtype_plugin { 'layout', 'single', 'shuffleanswers', 'correctfeedback', 'correctfeedbackformat', 'partiallycorrectfeedback', 'partiallycorrectfeedbackformat', - 'incorrectfeedback', 'incorrectfeedbackformat', 'answernumbering', 'shownumcorrect')); + 'incorrectfeedback', 'incorrectfeedbackformat', 'answernumbering', + 'shownumcorrect', 'showstandardinstruction')); // Now the own qtype tree. $pluginwrapper->add_child($multichoice); diff --git a/question/type/multichoice/db/install.xml b/question/type/multichoice/db/install.xml index 1c446fcf95f..d7793269622 100644 --- a/question/type/multichoice/db/install.xml +++ b/question/type/multichoice/db/install.xml @@ -19,6 +19,7 @@ + diff --git a/question/type/multichoice/db/upgrade.php b/question/type/multichoice/db/upgrade.php index 1cb4329c21e..484d7961f47 100644 --- a/question/type/multichoice/db/upgrade.php +++ b/question/type/multichoice/db/upgrade.php @@ -30,7 +30,7 @@ defined('MOODLE_INTERNAL') || die(); * @param int $oldversion the version we are upgrading from. */ function xmldb_qtype_multichoice_upgrade($oldversion) { - global $CFG; + global $CFG, $DB; // Automatically generated Moodle v3.5.0 release upgrade line. // Put any upgrade step following this. @@ -44,5 +44,24 @@ function xmldb_qtype_multichoice_upgrade($oldversion) { // Automatically generated Moodle v3.8.0 release upgrade line. // Put any upgrade step following this. + // Add a new checkbox for the question author to decide + // Whether standard instruction ('Select one:' or 'Select one or more:') is displayed. + $dbman = $DB->get_manager(); + $newversion = 2020041600; + if ($oldversion < $newversion) { + + // Define field showstandardinstruction to be added to qtype_multichoice_options. + $table = new xmldb_table('qtype_multichoice_options'); + $field = new xmldb_field('showstandardinstruction', XMLDB_TYPE_INTEGER, '2', + null, XMLDB_NOTNULL, null, '1', 'shownumcorrect'); + + // Conditionally launch add field showstandardinstruction. + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Multichoice savepoint reached. + upgrade_plugin_savepoint(true, $newversion, 'qtype', 'multichoice'); + } return true; } diff --git a/question/type/multichoice/edit_multichoice_form.php b/question/type/multichoice/edit_multichoice_form.php index 372dfcadd0c..0624c3ef292 100644 --- a/question/type/multichoice/edit_multichoice_form.php +++ b/question/type/multichoice/edit_multichoice_form.php @@ -58,6 +58,11 @@ class qtype_multichoice_edit_form extends question_edit_form { qtype_multichoice::get_numbering_styles()); $mform->setDefault('answernumbering', get_config('qtype_multichoice', 'answernumbering')); + $mform->addElement('selectyesno', 'showstandardinstruction', + get_string('showstandardinstruction', 'qtype_multichoice'), null, null, [0, 1]); + $mform->addHelpButton('showstandardinstruction', 'showstandardinstruction', 'qtype_multichoice'); + $mform->setDefault('showstandardinstruction', 0); + $this->add_per_answer_fields($mform, get_string('choiceno', 'qtype_multichoice', '{no}'), question_bank::fraction_options_full(), max(5, QUESTION_NUMANS_START)); @@ -99,6 +104,7 @@ class qtype_multichoice_edit_form extends question_edit_form { $question->single = $question->options->single; $question->shuffleanswers = $question->options->shuffleanswers; $question->answernumbering = $question->options->answernumbering; + $question->showstandardinstruction = $question->options->showstandardinstruction; } return $question; diff --git a/question/type/multichoice/lang/en/qtype_multichoice.php b/question/type/multichoice/lang/en/qtype_multichoice.php index 2473d43384d..2bae5b3063e 100644 --- a/question/type/multichoice/lang/en/qtype_multichoice.php +++ b/question/type/multichoice/lang/en/qtype_multichoice.php @@ -72,4 +72,6 @@ $string['shuffleanswers'] = 'Shuffle the choices?'; $string['shuffleanswers_desc'] = 'Whether options should be randomly shuffled for each attempt by default.'; $string['shuffleanswers_help'] = 'If enabled, the order of the answers is randomly shuffled for each attempt, provided that "Shuffle within questions" in the activity settings is also enabled.'; $string['singleanswer'] = 'Choose one answer.'; +$string['showstandardinstruction'] = 'Show standard instruction'; +$string['showstandardinstruction_help'] = 'With this setting enabled, standard instruction will be supplied as part of the selection area (e.g. "Select one:" or "Select one or more:"). If disabled, question authors can instead include instructions in the question content, if required.'; $string['toomanyselected'] = 'You have selected too many options.'; diff --git a/question/type/multichoice/question.php b/question/type/multichoice/question.php index fcf63c5f9da..624c9092ef4 100644 --- a/question/type/multichoice/question.php +++ b/question/type/multichoice/question.php @@ -44,6 +44,10 @@ abstract class qtype_multichoice_base extends question_graded_automatically { public $shuffleanswers; public $answernumbering; + /** + * @var int standard instruction to be displayed if enabled. + */ + public $showstandardinstruction = 0; public $layout = self::LAYOUT_VERTICAL; public $correctfeedback; diff --git a/question/type/multichoice/questiontype.php b/question/type/multichoice/questiontype.php index 60bd72146b6..241456296b8 100644 --- a/question/type/multichoice/questiontype.php +++ b/question/type/multichoice/questiontype.php @@ -79,6 +79,7 @@ class qtype_multichoice extends question_type { } $options->answernumbering = $config->answernumbering; $options->shuffleanswers = $config->shuffleanswers; + $options->showstandardinstruction = 0; $options->shownumcorrect = 1; return $options; @@ -155,6 +156,7 @@ class qtype_multichoice extends question_type { $options->correctfeedback = ''; $options->partiallycorrectfeedback = ''; $options->incorrectfeedback = ''; + $options->showstandardinstruction = 0; $options->id = $DB->insert_record('qtype_multichoice_options', $options); } @@ -164,6 +166,7 @@ class qtype_multichoice extends question_type { } $options->answernumbering = $question->answernumbering; $options->shuffleanswers = $question->shuffleanswers; + $options->showstandardinstruction = !empty($question->showstandardinstruction); $options = $this->save_combined_feedback_helper($options, $question, $context, true); $DB->update_record('qtype_multichoice_options', $options); @@ -204,6 +207,7 @@ class qtype_multichoice extends question_type { parent::initialise_question_instance($question, $questiondata); $question->shuffleanswers = $questiondata->options->shuffleanswers; $question->answernumbering = $questiondata->options->answernumbering; + $question->showstandardinstruction = $questiondata->options->showstandardinstruction; if (!empty($questiondata->options->layout)) { $question->layout = $questiondata->options->layout; } else { diff --git a/question/type/multichoice/renderer.php b/question/type/multichoice/renderer.php index 261a4c0f846..33e45e77a00 100644 --- a/question/type/multichoice/renderer.php +++ b/question/type/multichoice/renderer.php @@ -138,7 +138,9 @@ abstract class qtype_multichoice_renderer_base extends qtype_with_combined_feedb array('class' => 'qtext')); $result .= html_writer::start_tag('div', array('class' => 'ablock')); - $result .= html_writer::tag('div', $this->prompt(), array('class' => 'prompt')); + if ($question->showstandardinstruction == 1) { + $result .= html_writer::tag('div', $this->prompt(), array('class' => 'prompt')); + } $result .= html_writer::start_tag('div', array('class' => 'answer')); foreach ($radiobuttons as $key => $radio) { diff --git a/question/type/multichoice/tests/behat/export.feature b/question/type/multichoice/tests/behat/export.feature index 9d990b96480..414a2c9e023 100644 --- a/question/type/multichoice/tests/behat/export.feature +++ b/question/type/multichoice/tests/behat/export.feature @@ -28,7 +28,7 @@ Feature: Test exporting Multiple choice questions When I navigate to "Question bank > Export" in current page administration And I set the field "id_format_xml" to "1" And I press "Export questions to file" - Then following "click here" should download between "3800" and "3950" bytes + Then following "click here" should download between "4000" and "4100" 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/question/type/multichoice/tests/fixtures/testquestion.moodle.xml b/question/type/multichoice/tests/fixtures/testquestion.moodle.xml index 7edfdbf0001..b4abe4e1b87 100644 --- a/question/type/multichoice/tests/fixtures/testquestion.moodle.xml +++ b/question/type/multichoice/tests/fixtures/testquestion.moodle.xml @@ -25,6 +25,7 @@ false true abc + 0 Your answer is correct. diff --git a/question/type/multichoice/tests/helper.php b/question/type/multichoice/tests/helper.php index b665052ccb6..10b444cb9fc 100644 --- a/question/type/multichoice/tests/helper.php +++ b/question/type/multichoice/tests/helper.php @@ -62,6 +62,7 @@ class qtype_multichoice_test_helper extends question_test_helper { $qdata->options = new stdClass(); $qdata->options->shuffleanswers = 1; $qdata->options->answernumbering = '123'; + $qdata->options->showstandardinstruction = 0; $qdata->options->layout = 0; $qdata->options->single = 0; $qdata->options->correctfeedback = @@ -146,6 +147,7 @@ class qtype_multichoice_test_helper extends question_test_helper { $qdata->shuffleanswers = 1; $qdata->answernumbering = '123'; + $qdata->showstandardinstruction = 0; $qdata->single = '0'; $qdata->correctfeedback = array('text' => test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK, 'format' => FORMAT_HTML); @@ -243,6 +245,7 @@ class qtype_multichoice_test_helper extends question_test_helper { $qdata->options = new stdClass(); $qdata->options->shuffleanswers = 1; $qdata->options->answernumbering = '123'; + $qdata->options->showstandardinstruction = 0; $qdata->options->layout = 0; $qdata->options->single = 1; $qdata->options->correctfeedback = @@ -327,6 +330,7 @@ class qtype_multichoice_test_helper extends question_test_helper { $qdata->shuffleanswers = 1; $qdata->answernumbering = '123'; + $qdata->showstandardinstruction = 0; $qdata->single = '1'; $qdata->correctfeedback = array('text' => test_question_maker::STANDARD_OVERALL_CORRECT_FEEDBACK, 'format' => FORMAT_HTML); diff --git a/question/type/multichoice/tests/question_single_test.php b/question/type/multichoice/tests/question_single_test.php index f5f10a48df6..6d4eff2f8ad 100644 --- a/question/type/multichoice/tests/question_single_test.php +++ b/question/type/multichoice/tests/question_single_test.php @@ -123,6 +123,7 @@ class qtype_multichoice_single_question_test extends advanced_testcase { $mc->qtype = question_bank::get_qtype('multichoice'); $mc->answernumbering = 'abc'; + $mc->showstandardinstruction = 0; test_question_maker::set_standard_combined_feedback_fields($mc); diff --git a/question/type/multichoice/tests/upgradelibnewqe_test.php b/question/type/multichoice/tests/upgradelibnewqe_test.php index cd94e1a4cd4..6471a282028 100644 --- a/question/type/multichoice/tests/upgradelibnewqe_test.php +++ b/question/type/multichoice/tests/upgradelibnewqe_test.php @@ -155,6 +155,7 @@ class qtype_multichoice_attempt_upgrader_test extends question_attempt_upgrader_ 'partiallycorrectfeedback' => '', 'incorrectfeedback' => '', 'answernumbering' => 'none', + 'showstandardinstruction' => 0, 'shownumcorrect' => '0', ), 'hints' => array ( @@ -374,6 +375,7 @@ class qtype_multichoice_attempt_upgrader_test extends question_attempt_upgrader_ 'partiallycorrectfeedback' => '', 'incorrectfeedback' => '', 'answernumbering' => 'abc', + 'showstandardinstruction' => 0, ), 'hints' => false, ); @@ -555,6 +557,7 @@ class qtype_multichoice_attempt_upgrader_test extends question_attempt_upgrader_ 'partiallycorrectfeedback' => '', 'incorrectfeedback' => '', 'answernumbering' => 'abc', + 'showstandardinstruction' => 0, ), 'hints' => false, ); @@ -751,6 +754,7 @@ class qtype_multichoice_attempt_upgrader_test extends question_attempt_upgrader_ 'partiallycorrectfeedback' => 'Your answer is partially correct.', 'incorrectfeedback' => 'Your answer is incorrect.', 'answernumbering' => 'abc', + 'showstandardinstruction' => 0, ), 'hints' => false, ); @@ -973,6 +977,7 @@ class qtype_multichoice_attempt_upgrader_test extends question_attempt_upgrader_ 'partiallycorrectfeedback' => '', 'incorrectfeedback' => '', 'answernumbering' => 'abc', + 'showstandardinstruction' => 0, ), 'hints' => false, ); @@ -1114,6 +1119,7 @@ public function test_multichoice_deferredfeedback_qsession140() { 'partiallycorrectfeedback' => '', 'incorrectfeedback' => '', 'answernumbering' => 'abc', + 'showstandardinstruction' => 0, ), 'hints' => false, ); @@ -1338,6 +1344,7 @@ public function test_multichoice_deferredfeedback_qsession140() { 'partiallycorrectfeedback' => '', 'incorrectfeedback' => '', 'answernumbering' => 'abc', + 'showstandardinstruction' => 0, ), 'hints' => false, ); @@ -1583,6 +1590,7 @@ public function test_multichoice_deferredfeedback_qsession140() { 'partiallycorrectfeedback' => 'This is a very polemical source which clearly has a standpoint. Whether or not you would use this material would be largely dependent on your reseach question. If you did use it, you would need to be clear that you would require academic sources that would support the claims being made.

', 'incorrectfeedback' => 'This is a very polemical source which clearly has a standpoint. Whether or not you would use this material would be largely dependent on your reseach question. If you did use it, you would need to be clear that you would require academic sources that would support the claims being made.

', 'answernumbering' => 'abc', + 'showstandardinstruction' => 0, ), 'hints' => false, ); @@ -1785,6 +1793,7 @@ public function test_multichoice_deferredfeedback_qsession140() { 'partiallycorrectfeedback' => '', 'incorrectfeedback' => '', 'answernumbering' => 'abc', + 'showstandardinstruction' => 0, ), 'hints' => false, ); @@ -2023,6 +2032,7 @@ public function test_multichoice_deferredfeedback_qsession140() { 'partiallycorrectfeedback' => '', 'incorrectfeedback' => '', 'answernumbering' => 'none', + 'showstandardinstruction' => 0, ), 'hints' => false, ); @@ -2224,6 +2234,7 @@ public function test_multichoice_deferredfeedback_qsession140() { 'partiallycorrectfeedback' => '', 'incorrectfeedback' => '', 'answernumbering' => 'abc', + 'showstandardinstruction' => 0, ), 'hints' => false, ); @@ -2442,6 +2453,7 @@ public function test_multichoice_deferredfeedback_qsession140() { 'single' => '1', 'shuffleanswers' => '0', 'answernumbering' => 'abc', + 'showstandardinstruction' => 0, 'correctfeedback' => '', 'partiallycorrectfeedback' => '', 'incorrectfeedback' => '', @@ -2652,6 +2664,7 @@ public function test_multichoice_deferredfeedback_qsession140() { 'single' => '1', 'shuffleanswers' => '0', 'answernumbering' => 'abc', + 'showstandardinstruction' => 0, 'correctfeedback' => '', 'partiallycorrectfeedback' => '', 'incorrectfeedback' => '', diff --git a/question/type/multichoice/tests/walkthrough_test.php b/question/type/multichoice/tests/walkthrough_test.php index 9eb2be43b97..95902b74a79 100644 --- a/question/type/multichoice/tests/walkthrough_test.php +++ b/question/type/multichoice/tests/walkthrough_test.php @@ -76,6 +76,34 @@ class qtype_multichoice_walkthrough_test extends qbehaviour_walkthrough_test_bas new question_pattern_expectation('/class="r1"/')); } + public function test_deferredfeedback_feedback_multichoice_single_showstandardunstruction_yes() { + + // Create a multichoice, single question. + $mc = test_question_maker::make_a_multichoice_single_question(); + $mc->showstandardinstruction = true; + + $this->start_attempt_at_question($mc, 'deferredfeedback', 3); + $this->render(); + + // Check for 'Show standard instruction'. + $standardinstruction = get_string('selectone', 'qtype_multichoice'); + $this->assertStringContainsString($standardinstruction, $this->currentoutput); + } + + public function test_deferredfeedback_feedback_multichoice_single_showstandardunstruction_no() { + + // Create a multichoice, single question. + $mc = test_question_maker::make_a_multichoice_single_question(); + $mc->showstandardinstruction = false; + + $this->start_attempt_at_question($mc, 'deferredfeedback', 3); + $this->render(); + + // Check for 'Show standard instruction'. + $standardinstruction = get_string('selectmulti', 'qtype_multichoice'); + $this->assertStringNotContainsString($standardinstruction, $this->currentoutput); + } + public function test_deferredfeedback_feedback_multichoice_multi() { // Create a multichoice, multi question. $mc = test_question_maker::make_a_multichoice_multi_question(); @@ -97,4 +125,33 @@ class qtype_multichoice_walkthrough_test extends qbehaviour_walkthrough_test_bas new question_pattern_expectation('/class="r0 correct"/'), new question_pattern_expectation('/class="r1"/')); } + + public function test_deferredfeedback_feedback_multichoice_multi_showstandardunstruction_yes() { + + // Create a multichoice, multi question. + $mc = test_question_maker::make_a_multichoice_multi_question(); + $mc->showstandardinstruction = true; + + $this->start_attempt_at_question($mc, 'deferredfeedback', 3); + $this->render(); + + // Check for 'Show standard instruction'. + $standardinstruction = get_string('selectmulti', 'qtype_multichoice'); + $this->assertStringContainsString($standardinstruction, $this->currentoutput); + } + + public function test_deferredfeedback_feedback_multichoice_multi_showstandardunstruction_no() { + + // Create a multichoice, multi question. + $mc = test_question_maker::make_a_multichoice_multi_question(); + $mc->showstandardinstruction = false; + + $this->start_attempt_at_question($mc, 'deferredfeedback', 3); + $this->render(); + + // Check for 'Show standard instruction'. + $standardinstruction = get_string('selectmulti', 'qtype_multichoice'); + $this->assertStringNotContainsString($standardinstruction, $this->currentoutput); + } + } diff --git a/question/type/multichoice/version.php b/question/type/multichoice/version.php index 4533acfe686..17c89569230 100644 --- a/question/type/multichoice/version.php +++ b/question/type/multichoice/version.php @@ -26,7 +26,7 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'qtype_multichoice'; -$plugin->version = 2019111800; +$plugin->version = 2020041600; $plugin->requires = 2019111200;