Permalink
Browse files

MDL-27414 Upgrade the randomsamatch qtype to the new question engine

Added XML import/export
Different randomsamatch questions in the same quiz can now pick the same
shortanswer question.
Images are not preserved if shortanswer question is deleted after being
used in a randomsamatch attempt.
  • Loading branch information...
1 parent acbd69f commit a1b2b00736513490ac7fd4a0d536d6584f5016f2 Jean-Michel Vedrine committed May 10, 2013
@@ -58,9 +58,7 @@ public function formulation_and_controls(question_attempt $qa,
$result .= html_writer::start_tag('tr', array('class' => 'r' . $parity));
$fieldname = 'sub' . $key;
- $result .= html_writer::tag('td', $question->format_text(
- $question->stems[$stemid], $question->stemformat[$stemid],
- $qa, 'qtype_match', 'subquestion', $stemid),
+ $result .= html_writer::tag('td', $this->format_stem_text($qa, $stemid),
array('class' => 'text'));
$classes = 'control';
@@ -109,6 +107,20 @@ public function specific_feedback(question_attempt $qa) {
return $this->combined_feedback($qa);
}
+ /**
+ * Format each question stem. Overwritten by randomsamatch renderer.
+ *
+ * @param question_attempt $qa
+ * @param integer $stemid stem index
+ * @return string
+ */
+ public function format_stem_text($qa, $stemid) {
+ $question = $qa->get_question();
+ return $question->format_text(
+ $question->stems[$stemid], $question->stemformat[$stemid],
+ $qa, 'qtype_match', 'subquestion', $stemid);
+ }
+
protected function format_choices($question) {
$choices = array();
foreach ($question->get_choice_order() as $key => $choiceid) {
@@ -125,9 +137,7 @@ public function correct_response(question_attempt $qa) {
$choices = $this->format_choices($question);
$right = array();
foreach ($stemorder as $key => $stemid) {
- $right[] = $question->format_text($question->stems[$stemid],
- $question->stemformat[$stemid], $qa,
- 'qtype_match', 'subquestion', $stemid) . '' .
+ $right[] = $this->format_stem_text($qa, $stemid) . '' .
$choices[$question->get_right_choice_for($stemid)];
}
@@ -0,0 +1,71 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Serve question type files
+ *
+ * @package qtype_randomsamatch
+ * @copyright 2013 Jean-Michel Vedrine
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Random shortanswer matching question type conversion handler.
+ *
+ * @copyright 2013 Jean-Michel Vedrine
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ */
+class moodle1_qtype_randomsamatch_handler extends moodle1_qtype_handler {
+
+ /**
+ * Returns the list of paths within one <QUESTION> that this qtype needs to have included
+ * in the grouped question structure
+ *
+ * @return array of strings
+ */
+ public function get_question_subpaths() {
+ return array(
+ 'RANDOMSAMATCH',
+ );
+ }
+
+ /**
+ * Appends the randomsamatch specific information to the question.
+ *
+ * @param array $data grouped question data
+ * @param array $raw grouped raw QUESTION data
+ */
+ public function process_question(array $data, array $raw) {
+
+ // Convert match options.
+ if (isset($data['randomsamatch'])) {
+ $randomsamatch = $data['randomsamatch'][0];
+ } else {
+ $randomsamatch = array('choose' => 4);
+ }
+ $randomsamatch['id'] = $this->converter->get_nextid();
+ $randomsamatch['subcats'] = 1;
+ $randomsamatch['correctfeedback'] = '';
+ $randomsamatch['correctfeedbackformat'] = FORMAT_HTML;
+ $randomsamatch['partiallycorrectfeedback'] = '';
+ $randomsamatch['partiallycorrectfeedbackformat'] = FORMAT_HTML;
+ $randomsamatch['incorrectfeedback'] = '';
+ $randomsamatch['incorrectfeedbackformat'] = FORMAT_HTML;
+ $this->write_xml('randomsamatch', $randomsamatch, array('/randomsamatch/id'));
+ }
+}
@@ -49,14 +49,16 @@ protected function define_question_plugin_structure() {
// Now create the qtype own structures.
$randomsamatch = new backup_nested_element('randomsamatch', array('id'), array(
- 'choose'));
+ 'choose', 'subcats', 'correctfeedback', 'correctfeedbackformat',
+ 'partiallycorrectfeedback', 'partiallycorrectfeedbackformat',
+ 'incorrectfeedback', 'incorrectfeedbackformat', 'shownumcorrect'));
// Now the own qtype tree.
$pluginwrapper->add_child($randomsamatch);
// Set source to populate the data.
- $randomsamatch->set_source_table('question_randomsamatch',
- array('question' => backup::VAR_PARENTID));
+ $randomsamatch->set_source_table('qtype_randomsamatch_options',
+ array('questionid' => backup::VAR_PARENTID));
return $plugin;
}
@@ -41,7 +41,7 @@ protected function define_question_plugin_structure() {
$paths = array();
- // Add own qtype stuff
+ // Add own qtype stuff.
$elename = 'randomsamatch';
$elepath = $this->get_pathfor('/randomsamatch');
$paths[] = new restore_path_element($elename, $elepath);
@@ -64,14 +64,34 @@ public function process_randomsamatch($data) {
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
// If the question has been created by restore, we need to create its
- // question_randomsamatch too.
+ // qtype_randomsamatch_options too.
if ($questioncreated) {
+ // Fill in some field that were added in 2.1, and so which may be missing
+ // from backups made in older versions of Moodle.
+ if (!isset($data->subcats)) {
+ $data->subcats = 1;
+ }
+ if (!isset($data->correctfeedback)) {
+ $data->correctfeedback = '';
+ $data->correctfeedbackformat = FORMAT_HTML;
+ }
+ if (!isset($data->partiallycorrectfeedback)) {
+ $data->partiallycorrectfeedback = '';
+ $data->partiallycorrectfeedbackformat = FORMAT_HTML;
+ }
+ if (!isset($data->incorrectfeedback)) {
+ $data->incorrectfeedback = '';
+ $data->incorrectfeedbackformat = FORMAT_HTML;
+ }
+ if (!isset($data->shownumcorrect)) {
+ $data->shownumcorrect = 0;
+ }
// Adjust some columns.
- $data->question = $newquestionid;
+ $data->questionid = $newquestionid;
// Insert record.
- $newitemid = $DB->insert_record('question_randomsamatch', $data);
+ $newitemid = $DB->insert_record('qtype_randomsamatch_options', $data);
// Create mapping.
- $this->set_mapping('question_randomsamatch', $oldid, $newitemid);
+ $this->set_mapping('qtype_randomsamatch_options', $oldid, $newitemid);
}
}
@@ -82,7 +102,7 @@ public function process_randomsamatch($data) {
* answer is one comma separated list of hypen separated pairs
* containing question->id and question_answers->id
*/
- public function recode_state_answer($state) {
+ public function recode_legacy_state_answer($state) {
$answer = $state->answer;
$resultarr = array();
foreach (explode(',', $answer) as $pair) {
@@ -95,4 +115,17 @@ public function recode_state_answer($state) {
}
return implode(',', $resultarr);
}
+
+ /**
+ * Return the contents of this qtype to be processed by the links decoder.
+ */
+ public static function define_decode_contents() {
+
+ $contents = array();
+
+ $fields = array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback');
+ $contents[] = new restore_decode_content('qtype_randomsamatch_options', $fields, 'qtype_randomsamatch_options');
+
+ return $contents;
+ }
}
@@ -4,15 +4,23 @@
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
- <TABLE NAME="question_randomsamatch" COMMENT="Info about a random short-answer matching question">
+ <TABLE NAME="qtype_randomsamatch_options" COMMENT="Info about a random short-answer matching question">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
- <FIELD NAME="question" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Foreign key references question.id."/>
+ <FIELD NAME="questionid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Foreign key references question.id."/>
<FIELD NAME="choose" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="4" SEQUENCE="false" COMMENT="Number of subquestions to randomly generate."/>
+ <FIELD NAME="subcats" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Whether to include or not the subcategories."/>
+ <FIELD NAME="correctfeedback" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any correct response."/>
+ <FIELD NAME="correctfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
+ <FIELD NAME="partiallycorrectfeedback" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any partially correct response."/>
+ <FIELD NAME="partiallycorrectfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
+ <FIELD NAME="incorrectfeedback" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any incorrect response."/>
+ <FIELD NAME="incorrectfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
+ <FIELD NAME="shownumcorrect" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If true, then when the user gets the question partially correct, tell them how many choices they got correct alongside the feedback."/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
- <KEY NAME="question" TYPE="foreign" FIELDS="question" REFTABLE="question" REFFIELDS="id"/>
+ <KEY NAME="questionid" TYPE="foreign-unique" FIELDS="questionid" REFTABLE="question" REFFIELDS="id"/>
</KEYS>
</TABLE>
</TABLES>
Oops, something went wrong.

0 comments on commit a1b2b00

Please sign in to comment.