MDL-68367 Question: Multi-choice Option to hide systemtext
authorMahmoud Kassaei <mk4359@open.ac.uk>
Tue, 14 Apr 2020 09:36:19 +0000 (10:36 +0100)
committerMahmoud Kassaei <mk4359@open.ac.uk>
Thu, 21 May 2020 08:47:15 +0000 (09:47 +0100)
20 files changed:
question/behaviour/interactive/tests/walkthrough_test.php
question/engine/tests/helpers.php
question/format/xml/format.php
question/format/xml/tests/xmlformat_test.php
question/type/multichoice/backup/moodle1/lib.php
question/type/multichoice/backup/moodle2/backup_qtype_multichoice_plugin.class.php
question/type/multichoice/db/install.xml
question/type/multichoice/db/upgrade.php
question/type/multichoice/edit_multichoice_form.php
question/type/multichoice/lang/en/qtype_multichoice.php
question/type/multichoice/question.php
question/type/multichoice/questiontype.php
question/type/multichoice/renderer.php
question/type/multichoice/tests/behat/export.feature
question/type/multichoice/tests/fixtures/testquestion.moodle.xml
question/type/multichoice/tests/helper.php
question/type/multichoice/tests/question_single_test.php
question/type/multichoice/tests/upgradelibnewqe_test.php
question/type/multichoice/tests/walkthrough_test.php
question/type/multichoice/version.php

index 5f370f9..2f182c5 100644 (file)
@@ -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),
index 8443178..13d48b9 100644 (file)
@@ -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);
 
index d2323d0..b2b71ff 100644 (file)
@@ -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) .
                         "</shuffleanswers>\n";
                 $expout .= "    <answernumbering>" . $question->options->answernumbering .
-                        "</answernumbering>\n";
+                    "</answernumbering>\n";
+                $expout .= "    <showstandardinstruction>" . $question->options->showstandardinstruction .
+                    "</showstandardinstruction>\n";
                 $expout .= $this->write_combined_feedback($question->options, $question->id, $question->contextid);
                 $expout .= $this->write_answers($question->options->answers);
                 break;
index c8cd52c..0889ad5 100644 (file)
@@ -893,6 +893,7 @@ END;
         $qdata->options->single = 0;
         $qdata->options->shuffleanswers = 0;
         $qdata->options->answernumbering = 'abc';
+        $qdata->options->showstandardinstruction = 0;
         $qdata->options->correctfeedback = '<p>Your answer is correct.</p>';
         $qdata->options->correctfeedbackformat = FORMAT_HTML;
         $qdata->options->partiallycorrectfeedback = '<p>Your answer is partially correct.</p>';
@@ -934,6 +935,7 @@ END;
     <single>false</single>
     <shuffleanswers>false</shuffleanswers>
     <answernumbering>abc</answernumbering>
+    <showstandardinstruction>0</showstandardinstruction>
     <correctfeedback format="html">
       <text><![CDATA[<p>Your answer is correct.</p>]]></text>
     </correctfeedback>
index b31c80b..1ccfa72 100644 (file)
@@ -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']);
index fa9441c..b8277ee 100644 (file)
@@ -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);
index 1c446fc..d779326 100644 (file)
@@ -19,6 +19,7 @@
         <FIELD NAME="incorrectfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="answernumbering" TYPE="char" LENGTH="10" NOTNULL="true" DEFAULT="abc" SEQUENCE="false" COMMENT="Indicates how and whether the choices should be numbered."/>
         <FIELD NAME="shownumcorrect" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If true, then when the user gets a multiple-response question partially correct, tell them how many choices they got correct alongside the feedback."/>
+        <FIELD NAME="showstandardinstruction" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Whether standard instruction ('Select one:' or 'Select one or more:') is displayed"/>
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
index 1cb4329..484d796 100644 (file)
@@ -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;
 }
index 372dfca..0624c3e 100644 (file)
@@ -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;
index 2473d43..2bae5b3 100644 (file)
@@ -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.';
index fcf63c5..624c909 100644 (file)
@@ -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;
index 60bd721..2414562 100644 (file)
@@ -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 {
index 261a4c0..33e45e7 100644 (file)
@@ -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) {
index 9d990b9..414a2c9 100644 (file)
@@ -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
index 7edfdbf..b4abe4e 100644 (file)
@@ -25,6 +25,7 @@
     <single>false</single>
     <shuffleanswers>true</shuffleanswers>
     <answernumbering>abc</answernumbering>
+    <showstandardinstruction>0</showstandardinstruction>
     <correctfeedback format="html">
       <text>Your answer is correct.</text>
     </correctfeedback>
index b665052..10b444c 100644 (file)
@@ -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);
index f5f10a4..6d4eff2 100644 (file)
@@ -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);
 
index cd94e1a..6471a28 100644 (file)
@@ -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.<br /><br />',
                 '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.<br /><br />',
                 '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' => '',
index 9eb2be4..95902b7 100644 (file)
@@ -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);
+    }
+
 }
index 4533acf..17c8956 100644 (file)
@@ -26,7 +26,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $plugin->component = 'qtype_multichoice';
-$plugin->version   = 2019111800;
+$plugin->version   = 2020041600;
 
 $plugin->requires  = 2019111200;