diff --git a/question/type/truefalse/backup/moodle2/backup_qtype_truefalse_plugin.class.php b/question/type/truefalse/backup/moodle2/backup_qtype_truefalse_plugin.class.php index e3482f1215f..721a5f49de1 100644 --- a/question/type/truefalse/backup/moodle2/backup_qtype_truefalse_plugin.class.php +++ b/question/type/truefalse/backup/moodle2/backup_qtype_truefalse_plugin.class.php @@ -53,7 +53,7 @@ class backup_qtype_truefalse_plugin extends backup_qtype_plugin { // Now create the qtype own structures. $truefalse = new backup_nested_element('truefalse', array('id'), array( - 'trueanswer', 'falseanswer')); + 'trueanswer', 'falseanswer', 'showstandardinstruction')); // Now the own qtype tree. $pluginwrapper->add_child($truefalse); diff --git a/question/type/truefalse/classes/privacy/provider.php b/question/type/truefalse/classes/privacy/provider.php index 22979789649..32839a770df 100644 --- a/question/type/truefalse/classes/privacy/provider.php +++ b/question/type/truefalse/classes/privacy/provider.php @@ -14,33 +14,44 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . +namespace qtype_truefalse\privacy; + +use core_privacy\local\metadata\collection; +use core_privacy\local\request\transform; +use core_privacy\local\request\writer; + /** - * Privacy Subsystem implementation for qtype_truefalse. + * Privacy Subsystem implementation for qtype_truefalse * * @package qtype_truefalse * @copyright 2018 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ - -namespace qtype_truefalse\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy Subsystem for qtype_truefalse implementing null_provider. - * - * @copyright 2018 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { +class provider implements + \core_privacy\local\metadata\provider, + \core_privacy\local\request\user_preference_provider { /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. + * Returns metadata about this system * - * @return string + * @param collection $collection + * @return collection */ - public static function get_reason() : string { - return 'privacy:metadata'; + public static function get_metadata(collection $collection): collection { + $collection->add_user_preference('qtype_truefalse_showstandardinstruction', 'privacy:preference:showstandardinstruction'); + return $collection; + } + + /** + * Export plugin user preferences for the given user + * + * @param int $userid + */ + public static function export_user_preferences(int $userid): void { + $preference = get_user_preferences('qtype_truefalse_showstandardinstruction', null, $userid); + if ($preference !== null) { + writer::export_user_preference('qtype_truefalse', 'showstandardinstruction', transform::yesno($preference), + get_string('privacy:preference:showstandardinstruction', 'qtype_truefalse')); + } } } diff --git a/question/type/truefalse/db/install.xml b/question/type/truefalse/db/install.xml index dc7daf3f7b3..2d35debb970 100644 --- a/question/type/truefalse/db/install.xml +++ b/question/type/truefalse/db/install.xml @@ -1,5 +1,5 @@ - @@ -10,6 +10,7 @@ + diff --git a/question/type/truefalse/db/upgrade.php b/question/type/truefalse/db/upgrade.php new file mode 100644 index 00000000000..155b6b82be8 --- /dev/null +++ b/question/type/truefalse/db/upgrade.php @@ -0,0 +1,52 @@ +. + +/** + * True/false question type upgrade code + * + * @package qtype_truefalse + * @copyright 2022 Paul Holden + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * Method to perform upgrade steps between versions + * + * @param int $oldversion + * @return bool + */ +function xmldb_qtype_truefalse_upgrade(int $oldversion): bool { + global $DB; + + $dbman = $DB->get_manager(); + + if ($oldversion < 2022071900) { + + // Define field showstandardinstruction to be added to question_truefalse. + $table = new xmldb_table('question_truefalse'); + $field = new xmldb_field('showstandardinstruction', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '1', 'falseanswer'); + + // Conditionally launch add field showstandardinstruction. + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Truefalse savepoint reached. + upgrade_plugin_savepoint(true, 2022071900, 'qtype', 'truefalse'); + } + + return true; +} diff --git a/question/type/truefalse/edit_truefalse_form.php b/question/type/truefalse/edit_truefalse_form.php index fc8f3170e23..81003706c42 100644 --- a/question/type/truefalse/edit_truefalse_form.php +++ b/question/type/truefalse/edit_truefalse_form.php @@ -48,6 +48,10 @@ class qtype_truefalse_edit_form extends question_edit_form { 0 => get_string('false', 'qtype_truefalse'), 1 => get_string('true', 'qtype_truefalse'))); + $mform->addElement('selectyesno', 'showstandardinstruction', get_string('showstandardinstruction', 'qtype_truefalse')); + $mform->addHelpButton('showstandardinstruction', 'showstandardinstruction', 'qtype_truefalse'); + $mform->setDefault('showstandardinstruction', $this->get_default_value('showstandardinstruction', 0)); + $mform->addElement('editor', 'feedbacktrue', get_string('feedbacktrue', 'qtype_truefalse'), array('rows' => 10), $this->editoroptions); $mform->setType('feedbacktrue', PARAM_RAW); @@ -111,6 +115,10 @@ class qtype_truefalse_edit_form extends question_edit_form { $question->feedbackfalse['itemid'] = $draftid; } + if (!empty($question->options)) { + $question->showstandardinstruction = !empty($question->options->showstandardinstruction); + } + return $question; } diff --git a/question/type/truefalse/lang/en/deprecated.txt b/question/type/truefalse/lang/en/deprecated.txt new file mode 100644 index 00000000000..93dc2272af8 --- /dev/null +++ b/question/type/truefalse/lang/en/deprecated.txt @@ -0,0 +1 @@ +privacy:metadata,qtype_truefalse diff --git a/question/type/truefalse/lang/en/qtype_truefalse.php b/question/type/truefalse/lang/en/qtype_truefalse.php index d14a5c72e5a..ae80a296781 100644 --- a/question/type/truefalse/lang/en/qtype_truefalse.php +++ b/question/type/truefalse/lang/en/qtype_truefalse.php @@ -38,4 +38,9 @@ $string['pluginname_link'] = 'question/type/truefalse'; $string['pluginnameadding'] = 'Adding a True/False question'; $string['pluginnameediting'] = 'Editing a True/False question'; $string['pluginnamesummary'] = 'A simple form of multiple choice question with just the two choices \'True\' and \'False\'.'; +$string['privacy:preference:showstandardinstruction'] = 'Whether showing standard instruction.'; +$string['showstandardinstruction'] = 'Show standard instructions'; +$string['showstandardinstruction_help'] = 'Whether to show the instructions "Select one:" before true/false answers.'; + +// Deprecated since Moodle 4.1. $string['privacy:metadata'] = 'The True/False question type plugin does not store any personal data.'; diff --git a/question/type/truefalse/questiontype.php b/question/type/truefalse/questiontype.php index 1969ae3ecb4..3f3b5693115 100644 --- a/question/type/truefalse/questiontype.php +++ b/question/type/truefalse/questiontype.php @@ -94,12 +94,14 @@ class qtype_truefalse extends question_type { // But we'll do it anyway, just for robustness. $options->trueanswer = $trueid; $options->falseanswer = $falseid; + $options->showstandardinstruction = !empty($question->showstandardinstruction); $DB->update_record('question_truefalse', $options); } else { $options = new stdClass(); $options->question = $question->id; $options->trueanswer = $trueid; $options->falseanswer = $falseid; + $options->showstandardinstruction = !empty($question->showstandardinstruction); $DB->insert_record('question_truefalse', $options); } @@ -108,6 +110,11 @@ class qtype_truefalse extends question_type { return true; } + public function save_defaults_for_new_questions(stdClass $fromform): void { + parent::save_defaults_for_new_questions($fromform); + $this->set_default_value('showstandardinstruction', $fromform->showstandardinstruction); + } + /** * Loads the question type specific options for the question. */ @@ -148,6 +155,7 @@ class qtype_truefalse extends question_type { $answers[$questiondata->options->falseanswer]->feedbackformat; $question->trueanswerid = $questiondata->options->trueanswer; $question->falseanswerid = $questiondata->options->falseanswer; + $question->showstandardinstruction = $questiondata->options->showstandardinstruction; } public function delete_question($questionid, $contextid) { diff --git a/question/type/truefalse/renderer.php b/question/type/truefalse/renderer.php index 6abb1e6d257..9b3df0133b0 100644 --- a/question/type/truefalse/renderer.php +++ b/question/type/truefalse/renderer.php @@ -100,8 +100,10 @@ class qtype_truefalse_renderer extends qtype_renderer { array('class' => 'qtext')); $result .= html_writer::start_tag('div', array('class' => 'ablock')); - $result .= html_writer::tag('div', get_string('selectone', 'qtype_truefalse'), + if (!empty($question->showstandardinstruction)) { + $result .= html_writer::tag('div', get_string('selectone', 'qtype_truefalse'), array('class' => 'prompt')); + } $result .= html_writer::start_tag('div', array('class' => 'answer')); $result .= html_writer::tag('div', $radiotrue . ' ' . $truefeedbackimg, diff --git a/question/type/truefalse/tests/behat/add.feature b/question/type/truefalse/tests/behat/add.feature index fc2f133e340..05e467f3155 100644 --- a/question/type/truefalse/tests/behat/add.feature +++ b/question/type/truefalse/tests/behat/add.feature @@ -27,6 +27,7 @@ Feature: Test creating a True/False question | Feedback for the response 'False'. | Read more about England. | Then I should see "true-false-001" + @javascript Scenario: Create a True/False question with Correct answer as True When I am on the "Course 1" "core_question > course question bank" page logged in as teacher And I add a "True/False" question filling the form with: @@ -35,6 +36,13 @@ Feature: Test creating a True/False question | Default mark | 1 | | General feedback | London is the capital city of England. | | Correct answer | True | + | Show standard instructions | Yes | | Feedback for the response 'True'. | Well done! | | Feedback for the response 'False'. | Read more about England. | Then I should see "true-false-002" + # Checking that the next new question form displays user preferences settings. + And I press "Create a new question ..." + And I set the field "True/False" to "1" + And I click on "Add" "button" in the "Choose a question type to add" "dialogue" + And the following fields match these values: + | Show standard instructions | Yes | diff --git a/question/type/truefalse/tests/walkthrough_test.php b/question/type/truefalse/tests/walkthrough_test.php index 4b46aa05018..ae7ec1d2ef1 100644 --- a/question/type/truefalse/tests/walkthrough_test.php +++ b/question/type/truefalse/tests/walkthrough_test.php @@ -66,4 +66,38 @@ class walkthrough_test extends \qbehaviour_walkthrough_test_base { new \question_no_pattern_expectation('/' . preg_quote($tf->falsefeedback, '/') . '/')); } + + /** + * @covers \qtype_truefalse_renderer::formulation_and_controls + */ + public function test_deferredfeedback_feedback_multichoice_single_showstandardinstruction_yes() { + + // Create a true-false question with correct answer false. + $tf = \test_question_maker::make_question('truefalse', 'false'); + $tf->showstandardinstruction = true; + + $this->start_attempt_at_question($tf, 'deferredfeedback', 1); + $this->render(); + + // Check for 'Show standard instruction'. + $standardinstruction = get_string('selectone', 'qtype_truefalse'); + $this->assertStringContainsString($standardinstruction, $this->currentoutput); + } + + /** + * @covers \qtype_truefalse_renderer::formulation_and_controls + */ + public function test_deferredfeedback_feedback_multichoice_single_showstandardinstruction_no() { + + // Create a true-false question with correct answer false. + $tf = \test_question_maker::make_question('truefalse', 'false'); + $tf->showstandardinstruction = false; + + $this->start_attempt_at_question($tf, 'deferredfeedback', 1); + $this->render(); + + // Check for 'Show standard instruction'. + $standardinstruction = get_string('selectone', 'qtype_truefalse'); + $this->assertStringNotContainsString($standardinstruction, $this->currentoutput); + } } diff --git a/question/type/truefalse/version.php b/question/type/truefalse/version.php index 49c59da28b6..c68323cbacf 100644 --- a/question/type/truefalse/version.php +++ b/question/type/truefalse/version.php @@ -26,7 +26,7 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'qtype_truefalse'; -$plugin->version = 2022041900; +$plugin->version = 2022071900; $plugin->requires = 2022041200;