Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

MDL-37600 qtype match: remove obsolete DB columns, and obey coding st…

…yle.

Tables renamed to start qtype_match, and qtype_match_options.subquestions
and qtype_match_subquestions.code columnd dropped. Also, qtype_match_options
-> question foreign key link changed to be foreign-unique, since that is
what it should be.
  • Loading branch information...
commit 87d767343d0c80f3376d8370ec3a5c91a7359e86 1 parent b3778a0
Tim Hunt timhunt authored
16 question/type/match/backup/moodle2/backup_qtype_match_plugin.class.php
@@ -49,14 +49,14 @@ protected function define_question_plugin_structure() {
49 49
50 50 // Now create the qtype own structures
51 51 $matchoptions = new backup_nested_element('matchoptions', array('id'), array(
52   - 'subquestions', 'shuffleanswers', 'correctfeedback', 'correctfeedbackformat',
  52 + 'shuffleanswers', 'correctfeedback', 'correctfeedbackformat',
53 53 'partiallycorrectfeedback', 'partiallycorrectfeedbackformat',
54 54 'incorrectfeedback', 'incorrectfeedbackformat', 'shownumcorrect'));
55 55
56 56 $matches = new backup_nested_element('matches');
57 57
58 58 $match = new backup_nested_element('match', array('id'), array(
59   - 'code', 'questiontext', 'questiontextformat', 'answertext'));
  59 + 'questiontext', 'questiontextformat', 'answertext'));
60 60
61 61 // Now the own qtype tree
62 62 $pluginwrapper->add_child($matchoptions);
@@ -64,14 +64,14 @@ protected function define_question_plugin_structure() {
64 64 $matches->add_child($match);
65 65
66 66 // set source to populate the data
67   - $matchoptions->set_source_table('question_match',
68   - array('question' => backup::VAR_PARENTID));
  67 + $matchoptions->set_source_table('qtype_match_options',
  68 + array('questionid' => backup::VAR_PARENTID));
69 69 $match->set_source_sql('
70 70 SELECT *
71   - FROM {question_match_sub}
72   - WHERE question = :question
  71 + FROM {qtype_match_subquestions}
  72 + WHERE questionid = :questionid
73 73 ORDER BY id',
74   - array('question' => backup::VAR_PARENTID));
  74 + array('questionid' => backup::VAR_PARENTID));
75 75
76 76 // don't need to annotate ids nor files
77 77
@@ -86,6 +86,6 @@ protected function define_question_plugin_structure() {
86 86 */
87 87 public static function get_qtype_fileareas() {
88 88 return array(
89   - 'subquestion' => 'question_match_sub');
  89 + 'subquestion' => 'qtype_match_subquestions');
90 90 }
91 91 }
95 question/type/match/backup/moodle2/restore_qtype_match_plugin.class.php
@@ -69,7 +69,7 @@ public function process_matchoptions($data) {
69 69 $newquestionid = $this->get_new_parentid('question');
70 70 $questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
71 71
72   - // If the question has been created by restore, we need to create its question_match too
  72 + // If the question has been created by restore, we need to create its qtype_match_options too
73 73 if ($questioncreated) {
74 74 // Fill in some field that were added in 2.1, and so which may be missing
75 75 // from backups made in older versions of Moodle.
@@ -90,14 +90,9 @@ public function process_matchoptions($data) {
90 90 }
91 91
92 92 // Adjust some columns
93   - $data->question = $newquestionid;
94   - // Keep question_match->subquestions unmodified
95   - // after_execute_question() will perform the remapping once all subquestions
96   - // have been created
97   - // Insert record
98   - $newitemid = $DB->insert_record('question_match', $data);
99   - // Create mapping
100   - $this->set_mapping('question_match', $oldid, $newitemid);
  93 + $data->questionid = $newquestionid;
  94 + $newitemid = $DB->insert_record('qtype_match_options', $data);
  95 + $this->set_mapping('qtype_match_options', $oldid, $newitemid);
101 96 }
102 97 }
103 98
@@ -117,31 +112,33 @@ public function process_match($data) {
117 112
118 113 if ($questioncreated) {
119 114 // If the question has been created by restore, we need to create its
120   - // question_match_sub too
  115 + // qtype_match_subquestions too.
121 116
122 117 // Adjust some columns
123   - $data->question = $newquestionid;
  118 + $data->questionid = $newquestionid;
124 119 // Insert record
125   - $newitemid = $DB->insert_record('question_match_sub', $data);
  120 + $newitemid = $DB->insert_record('qtype_match_subquestions', $data);
126 121 // Create mapping (there are files and states based on this)
127   - $this->set_mapping('question_match_sub', $oldid, $newitemid);
  122 + $this->set_mapping('qtype_match_subquestions', $oldid, $newitemid);
  123 + if (isset($data->code)) {
  124 + $this->set_mapping('qtype_match_subquestion_codes', $data->code, $newitemid);
  125 + }
128 126
129 127 } else {
130   - // match questions require mapping of question_match_sub, because
  128 + // match questions require mapping of qtype_match_subquestions, because
131 129 // they are used by question_states->answer
132 130
133   - // Look for matching subquestion (by question, questiontext and answertext)
134   - $sub = $DB->get_record_select('question_match_sub', 'question = ? AND ' .
  131 + // Look for matching subquestion (by questionid, questiontext and answertext)
  132 + $sub = $DB->get_record_select('qtype_match_subquestions', 'questionid = ? AND ' .
135 133 $DB->sql_compare_text('questiontext') . ' = ' .
136 134 $DB->sql_compare_text('?').' AND answertext = ?',
137   - array($newquestionid, $data->questiontext, $data->answertext),
138   - 'id', IGNORE_MULTIPLE);
  135 + array($newquestionid, $data->questiontext, $data->answertext),
  136 + 'id', IGNORE_MULTIPLE);
139 137
140 138 // Not able to find the answer, let's try cleaning the answertext
141   - // of all the question answers in DB as slower fallback. MDL-36683 / MDL-30018.
  139 + // of all the match subquestions in DB as slower fallback. MDL-36683 / MDL-30018.
142 140 if (!$sub) {
143   - $params = array('question' => $newquestionid);
144   - $potentialsubs = $DB->get_records('question_match_sub', array('question' => $newquestionid), '', 'id, questiontext, answertext');
  141 + $potentialsubs = $DB->get_records('qtype_match_subquestions', array('questionid' => $newquestionid), '', 'id, questiontext, answertext');
145 142 foreach ($potentialsubs as $potentialsub) {
146 143 // Clean in the same way than {@link xml_writer::xml_safe_utf8()}.
147 144 $cleanquestion = preg_replace('/[\x-\x8\xb-\xc\xe-\x1f\x7f]/is', '', $potentialsub->questiontext); // Clean CTRL chars.
@@ -158,43 +155,11 @@ public function process_match($data) {
158 155
159 156 // Found, let's create the mapping
160 157 if ($sub) {
161   - $this->set_mapping('question_match_sub', $oldid, $sub->id);
  158 + $this->set_mapping('qtype_match_subquestions', $oldid, $sub->id);
162 159 } else {
163   - throw new restore_step_exception('error_question_match_sub_missing_in_db', $data);
164   - }
165   - }
166   - }
167   -
168   - /**
169   - * This method is executed once the whole restore_structure_step,
170   - * more exactly ({@link restore_create_categories_and_questions})
171   - * has ended processing the whole xml structure. Its name is:
172   - * "after_execute_" + connectionpoint ("question")
173   - *
174   - * For match qtype we use it to restore the subquestions column,
175   - * containing one list of question_match_sub ids
176   - */
177   - public function after_execute_question() {
178   - global $DB;
179   - // Now that all the question_match_subs have been restored, let's process
180   - // the created question_match subquestions (list of question_match_sub ids)
181   - $rs = $DB->get_recordset_sql(
182   - "SELECT qm.id, qm.subquestions
183   - FROM {question_match} qm
184   - JOIN {backup_ids_temp} bi ON bi.newitemid = qm.question
185   - WHERE bi.backupid = ?
186   - AND bi.itemname = 'question_created'", array($this->get_restoreid()));
187   - foreach ($rs as $rec) {
188   - $subquestionsarr = explode(',', $rec->subquestions);
189   - foreach ($subquestionsarr as $key => $subquestion) {
190   - $subquestionsarr[$key] = $this->get_mappingid(
191   - 'question_match_sub', $subquestion);
  160 + throw new restore_step_exception('error_qtype_match_subquestion_missing_in_db', $data);
192 161 }
193   - $subquestions = implode(',', $subquestionsarr);
194   - $DB->set_field('question_match', 'subquestions', $subquestions,
195   - array('id' => $rec->id));
196 162 }
197   - $rs->close();
198 163 }
199 164
200 165 public function recode_response($questionid, $sequencenumber, array $response) {
@@ -212,7 +177,8 @@ public function recode_response($questionid, $sequencenumber, array $response) {
212 177 * recoded pointing to all the restored stuff for match questions
213 178 *
214 179 * answer is one comma separated list of hypen separated pairs
215   - * containing question_match_sub->id and question_match_sub->code
  180 + * containing question_match_sub->id and question_match_sub->code, which
  181 + * has been remapped to be qtype_match_subquestions->id, since code no longer exists.
216 182 */
217 183 public function recode_legacy_state_answer($state) {
218 184 $answer = $state->answer;
@@ -221,8 +187,13 @@ public function recode_legacy_state_answer($state) {
221 187 $pairarr = explode('-', $pair);
222 188 $id = $pairarr[0];
223 189 $code = $pairarr[1];
224   - $newid = $this->get_mappingid('question_match_sub', $id);
225   - $resultarr[] = implode('-', array($newid, $code));
  190 + $newid = $this->get_mappingid('qtype_match_subquestions', $id);
  191 + if ($code) {
  192 + $newcode = $this->get_mappingid('qtype_match_subquestion_codes', $code);
  193 + } else {
  194 + $newcode = $code;
  195 + }
  196 + $resultarr[] = $newid . '-' . $newcode;
226 197 }
227 198 return implode(',', $resultarr);
228 199 }
@@ -235,7 +206,7 @@ public function recode_legacy_state_answer($state) {
235 206 protected function recode_match_sub_order($order) {
236 207 $neworder = array();
237 208 foreach (explode(',', $order) as $id) {
238   - if ($newid = $this->get_mappingid('question_match_sub', $id)) {
  209 + if ($newid = $this->get_mappingid('qtype_match_subquestions', $id)) {
239 210 $neworder[] = $newid;
240 211 }
241 212 }
@@ -249,11 +220,11 @@ public static function define_decode_contents() {
249 220
250 221 $contents = array();
251 222
252   - $contents[] = new restore_decode_content('question_match_sub',
253   - array('questiontext'), 'question_match_sub');
  223 + $contents[] = new restore_decode_content('qtype_match_subquestions',
  224 + array('questiontext'), 'qtype_match_subquestions');
254 225
255 226 $fields = array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback');
256   - $contents[] = new restore_decode_content('question_match', $fields, 'question_match');
  227 + $contents[] = new restore_decode_content('qtype_match_options', $fields, 'qtype_match_options');
257 228
258 229 return $contents;
259 230 }
32 question/type/match/db/install.xml
... ... @@ -1,41 +1,39 @@
1 1 <?xml version="1.0" encoding="UTF-8" ?>
2   -<XMLDB PATH="question/type/match/db" VERSION="20120122" COMMENT="XMLDB file for Moodle question/type/match"
  2 +<XMLDB PATH="question/type/match/db" VERSION="20130121" COMMENT="XMLDB file for Moodle question/type/match"
3 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 4 xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
5 5 >
6 6 <TABLES>
7   - <TABLE NAME="question_match" COMMENT="Defines fixed matching questions" NEXT="question_match_sub">
  7 + <TABLE NAME="qtype_match_options" COMMENT="Defines the question-type specific options for matching questions" NEXT="qtype_match_subquestions">
8 8 <FIELDS>
9   - <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="question"/>
10   - <FIELD NAME="question" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="subquestions"/>
11   - <FIELD NAME="subquestions" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="question" NEXT="shuffleanswers"/>
12   - <FIELD NAME="shuffleanswers" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="subquestions" NEXT="correctfeedback"/>
  9 + <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="questionid"/>
  10 + <FIELD NAME="questionid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Foreign key link to question.id." PREVIOUS="id" NEXT="shuffleanswers"/>
  11 + <FIELD NAME="shuffleanswers" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="questionid" NEXT="correctfeedback"/>
13 12 <FIELD NAME="correctfeedback" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any correct response." PREVIOUS="shuffleanswers" NEXT="correctfeedbackformat"/>
14 13 <FIELD NAME="correctfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="correctfeedback" NEXT="partiallycorrectfeedback"/>
15 14 <FIELD NAME="partiallycorrectfeedback" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any partially correct response." PREVIOUS="correctfeedbackformat" NEXT="partiallycorrectfeedbackformat"/>
16 15 <FIELD NAME="partiallycorrectfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="partiallycorrectfeedback" NEXT="incorrectfeedback"/>
17 16 <FIELD NAME="incorrectfeedback" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any incorrect response." PREVIOUS="partiallycorrectfeedbackformat" NEXT="incorrectfeedbackformat"/>
18 17 <FIELD NAME="incorrectfeedbackformat" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="incorrectfeedback" NEXT="shownumcorrect"/>
19   - <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." PREVIOUS="incorrectfeedbackformat"/>
  18 + <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." PREVIOUS="incorrectfeedbackformat"/>
20 19 </FIELDS>
21 20 <KEYS>
22   - <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="question"/>
23   - <KEY NAME="question" TYPE="foreign" FIELDS="question" REFTABLE="question" REFFIELDS="id" PREVIOUS="primary"/>
  21 + <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="questionid"/>
  22 + <KEY NAME="questionid" TYPE="foreign-unique" FIELDS="questionid" REFTABLE="question" REFFIELDS="id" PREVIOUS="primary"/>
24 23 </KEYS>
25 24 </TABLE>
26   - <TABLE NAME="question_match_sub" COMMENT="Defines the subquestions that make up a matching question" PREVIOUS="question_match">
  25 + <TABLE NAME="qtype_match_subquestions" COMMENT="The subquestions that make up a matching question" PREVIOUS="qtype_match_options">
27 26 <FIELDS>
28   - <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="code"/>
29   - <FIELD NAME="code" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Should this point to parent question_match-&amp;gt;id ?" PREVIOUS="id" NEXT="question"/>
30   - <FIELD NAME="question" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="code" NEXT="questiontext"/>
31   - <FIELD NAME="questiontext" TYPE="text" NOTNULL="true" SEQUENCE="false" PREVIOUS="question" NEXT="questiontextformat"/>
  27 + <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="questionid"/>
  28 + <FIELD NAME="questionid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Foreign key link to question.id." PREVIOUS="id" NEXT="questiontext"/>
  29 + <FIELD NAME="questiontext" TYPE="text" NOTNULL="true" SEQUENCE="false" PREVIOUS="questionid" NEXT="questiontextformat"/>
32 30 <FIELD NAME="questiontextformat" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="questiontext" NEXT="answertext"/>
33 31 <FIELD NAME="answertext" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="questiontextformat"/>
34 32 </FIELDS>
35 33 <KEYS>
36   - <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="question"/>
37   - <KEY NAME="question" TYPE="foreign" FIELDS="question" REFTABLE="question" REFFIELDS="id" PREVIOUS="primary"/>
  34 + <KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="questionid"/>
  35 + <KEY NAME="questionid" TYPE="foreign" FIELDS="questionid" REFTABLE="question" REFFIELDS="id" PREVIOUS="primary"/>
38 36 </KEYS>
39 37 </TABLE>
40 38 </TABLES>
41   -</XMLDB>
  39 +</XMLDB>
143 question/type/match/db/upgrade.php
@@ -36,17 +36,148 @@ function xmldb_qtype_match_upgrade($oldversion) {
36 36
37 37 $dbman = $DB->get_manager();
38 38
  39 + // Moodle v2.2.0 release upgrade line.
  40 + // Put any upgrade step following this.
39 41
40   - // Moodle v2.2.0 release upgrade line
41   - // Put any upgrade step following this
  42 + // Moodle v2.3.0 release upgrade line.
  43 + // Put any upgrade step following this.
42 44
43   - // Moodle v2.3.0 release upgrade line
44   - // Put any upgrade step following this
  45 + // Moodle v2.4.0 release upgrade line.
  46 + // Put any upgrade step following this.
45 47
  48 + if ($oldversion < 2013012100) {
46 49
47   - // Moodle v2.4.0 release upgrade line
48   - // Put any upgrade step following this
  50 + // Define table question_match to be renamed to qtype_match_options.
  51 + $table = new xmldb_table('question_match');
49 52
  53 + // Launch rename table for qtype_match_options.
  54 + $dbman->rename_table($table, 'qtype_match_options');
  55 +
  56 + // Record that qtype_match savepoint was reached.
  57 + upgrade_plugin_savepoint(true, 2013012100, 'qtype', 'match');
  58 + }
  59 +
  60 + if ($oldversion < 2013012101) {
  61 +
  62 + // Define key question (foreign) to be dropped form qtype_match_options.
  63 + $table = new xmldb_table('qtype_match_options');
  64 + $key = new xmldb_key('question', XMLDB_KEY_FOREIGN, array('question'), 'question', array('id'));
  65 +
  66 + // Launch drop key question.
  67 + $dbman->drop_key($table, $key);
  68 +
  69 + // Record that qtype_match savepoint was reached.
  70 + upgrade_plugin_savepoint(true, 2013012101, 'qtype', 'match');
  71 + }
  72 +
  73 + if ($oldversion < 2013012102) {
  74 +
  75 + // Rename field question on table qtype_match_options to questionid.
  76 + $table = new xmldb_table('qtype_match_options');
  77 + $field = new xmldb_field('question', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
  78 +
  79 + // Launch rename field question.
  80 + $dbman->rename_field($table, $field, 'questionid');
  81 +
  82 + // Record that qtype_match savepoint was reached.
  83 + upgrade_plugin_savepoint(true, 2013012102, 'qtype', 'match');
  84 + }
  85 +
  86 + if ($oldversion < 2013012103) {
  87 +
  88 + // Define key questionid (foreign-unique) to be added to qtype_match_options.
  89 + $table = new xmldb_table('qtype_match_options');
  90 + $key = new xmldb_key('questionid', XMLDB_KEY_FOREIGN_UNIQUE, array('questionid'), 'question', array('id'));
  91 +
  92 + // Launch add key questionid.
  93 + $dbman->add_key($table, $key);
  94 +
  95 + // Record that qtype_match savepoint was reached.
  96 + upgrade_plugin_savepoint(true, 2013012103, 'qtype', 'match');
  97 + }
  98 +
  99 + if ($oldversion < 2013012104) {
  100 +
  101 + // Define field subquestions to be dropped from qtype_match_options.
  102 + $table = new xmldb_table('qtype_match_options');
  103 + $field = new xmldb_field('subquestions');
  104 +
  105 + // Conditionally launch drop field subquestions.
  106 + if ($dbman->field_exists($table, $field)) {
  107 + $dbman->drop_field($table, $field);
  108 + }
  109 +
  110 + // Record that qtype_match savepoint was reached.
  111 + upgrade_plugin_savepoint(true, 2013012104, 'qtype', 'match');
  112 + }
  113 +
  114 + if ($oldversion < 2013012105) {
  115 +
  116 + // Define table question_match_sub to be renamed to qtype_match_subquestions.
  117 + $table = new xmldb_table('question_match_sub');
  118 +
  119 + // Launch rename table for qtype_match_subquestions.
  120 + $dbman->rename_table($table, 'qtype_match_subquestions');
  121 +
  122 + // Record that qtype_match savepoint was reached.
  123 + upgrade_plugin_savepoint(true, 2013012105, 'qtype', 'match');
  124 + }
  125 +
  126 + if ($oldversion < 2013012106) {
  127 +
  128 + // Define key question (foreign) to be dropped form qtype_match_subquestions.
  129 + $table = new xmldb_table('qtype_match_subquestions');
  130 + $key = new xmldb_key('question', XMLDB_KEY_FOREIGN, array('question'), 'question', array('id'));
  131 +
  132 + // Launch drop key question.
  133 + $dbman->drop_key($table, $key);
  134 +
  135 + // Record that qtype_match savepoint was reached.
  136 + upgrade_plugin_savepoint(true, 2013012106, 'qtype', 'match');
  137 + }
  138 +
  139 + if ($oldversion < 2013012107) {
  140 +
  141 + // Rename field question on table qtype_match_subquestions to questionid.
  142 + $table = new xmldb_table('qtype_match_subquestions');
  143 + $field = new xmldb_field('question', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
  144 +
  145 + // Launch rename field question.
  146 + $dbman->rename_field($table, $field, 'questionid');
  147 +
  148 + // Record that qtype_match savepoint was reached.
  149 + upgrade_plugin_savepoint(true, 2013012107, 'qtype', 'match');
  150 + }
  151 +
  152 + if ($oldversion < 2013012108) {
  153 +
  154 + // Define key questionid (foreign) to be added to qtype_match_subquestions.
  155 + $table = new xmldb_table('qtype_match_subquestions');
  156 + $key = new xmldb_key('questionid', XMLDB_KEY_FOREIGN, array('questionid'), 'question', array('id'));
  157 +
  158 + // Launch add key questionid.
  159 + $dbman->add_key($table, $key);
  160 +
  161 + // Record that qtype_match savepoint was reached.
  162 + upgrade_plugin_savepoint(true, 2013012108, 'qtype', 'match');
  163 + }
  164 +
  165 + if ($oldversion < 2013012109) {
  166 +
  167 + // Define field code to be dropped from qtype_match_subquestions.
  168 + // The field code has not been needed since the new question engine in
  169 + // Moodle 2.1. It should be safe to drop it now.
  170 + $table = new xmldb_table('qtype_match_subquestions');
  171 + $field = new xmldb_field('code');
  172 +
  173 + // Conditionally launch drop field code.
  174 + if ($dbman->field_exists($table, $field)) {
  175 + $dbman->drop_field($table, $field);
  176 + }
  177 +
  178 + // Record that qtype_match savepoint was reached.
  179 + upgrade_plugin_savepoint(true, 2013012109, 'qtype', 'match');
  180 + }
50 181
51 182 return true;
52 183 }
2  question/type/match/db/upgradelib.php
@@ -98,7 +98,7 @@ protected function make_summary($pairs) {
98 98
99 99 protected function lookup_choice($choice) {
100 100 foreach ($this->question->options->subquestions as $matchsub) {
101   - if ($matchsub->code == $choice) {
  101 + if ($matchsub->id == $choice) {
102 102 if (array_key_exists($matchsub->id, $this->choices)) {
103 103 return $matchsub->id;
104 104 } else {
67 question/type/match/questiontype.php
@@ -17,10 +17,9 @@
17 17 /**
18 18 * Question type class for the matching question type.
19 19 *
20   - * @package qtype
21   - * @subpackage match
22   - * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
23   - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  20 + * @package qtype_match
  21 + * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
  22 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 23 */
25 24
26 25
@@ -33,17 +32,18 @@
33 32 /**
34 33 * The matching question type class.
35 34 *
36   - * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
37   - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35 + * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
  36 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38 37 */
39 38 class qtype_match extends question_type {
40 39
41 40 public function get_question_options($question) {
42 41 global $DB;
43 42 parent::get_question_options($question);
44   - $question->options = $DB->get_record('question_match', array('question' => $question->id));
45   - $question->options->subquestions = $DB->get_records('question_match_sub',
46   - array('question' => $question->id), 'id ASC');
  43 + $question->options = $DB->get_record('qtype_match_options',
  44 + array('questionid' => $question->id));
  45 + $question->options->subquestions = $DB->get_records('qtype_match_subquestions',
  46 + array('questionid' => $question->id), 'id ASC');
47 47 return true;
48 48 }
49 49
@@ -52,11 +52,8 @@ public function save_question_options($question) {
52 52 $context = $question->context;
53 53 $result = new stdClass();
54 54
55   - $oldsubquestions = $DB->get_records('question_match_sub',
56   - array('question' => $question->id), 'id ASC');
57   -
58   - // $subquestions will be an array with subquestion ids
59   - $subquestions = array();
  55 + $oldsubquestions = $DB->get_records('qtype_match_subquestions',
  56 + array('questionid' => $question->id), 'id ASC');
60 57
61 58 // Insert all the new question+answer pairs
62 59 foreach ($question->subquestions as $key => $questiontext) {
@@ -71,16 +68,10 @@ public function save_question_options($question) {
71 68 $subquestion = array_shift($oldsubquestions);
72 69 if (!$subquestion) {
73 70 $subquestion = new stdClass();
74   - // Determine a unique random code
75   - $subquestion->code = rand(1, 999999999);
76   - while ($DB->record_exists('question_match_sub',
77   - array('code' => $subquestion->code, 'question' => $question->id))) {
78   - $subquestion->code = rand(1, 999999999);
79   - }
80   - $subquestion->question = $question->id;
  71 + $subquestion->questionid = $question->id;
81 72 $subquestion->questiontext = '';
82 73 $subquestion->answertext = '';
83   - $subquestion->id = $DB->insert_record('question_match_sub', $subquestion);
  74 + $subquestion->id = $DB->insert_record('qtype_match_subquestions', $subquestion);
84 75 }
85 76
86 77 $subquestion->questiontext = $this->import_or_save_files($questiontext,
@@ -88,33 +79,30 @@ public function save_question_options($question) {
88 79 $subquestion->questiontextformat = $questiontext['format'];
89 80 $subquestion->answertext = trim($question->subanswers[$key]);
90 81
91   - $DB->update_record('question_match_sub', $subquestion);
92   -
93   - $subquestions[] = $subquestion->id;
  82 + $DB->update_record('qtype_match_subquestions', $subquestion);
94 83 }
95 84
96 85 // Delete old subquestions records
97 86 $fs = get_file_storage();
98 87 foreach ($oldsubquestions as $oldsub) {
99 88 $fs->delete_area_files($context->id, 'qtype_match', 'subquestion', $oldsub->id);
100   - $DB->delete_records('question_match_sub', array('id' => $oldsub->id));
  89 + $DB->delete_records('qtype_match_subquestions', array('id' => $oldsub->id));
101 90 }
102 91
103 92 // Save the question options.
104   - $options = $DB->get_record('question_match', array('question' => $question->id));
  93 + $options = $DB->get_record('qtype_match_options', array('questionid' => $question->id));
105 94 if (!$options) {
106 95 $options = new stdClass();
107   - $options->question = $question->id;
  96 + $options->questionid = $question->id;
108 97 $options->correctfeedback = '';
109 98 $options->partiallycorrectfeedback = '';
110 99 $options->incorrectfeedback = '';
111   - $options->id = $DB->insert_record('question_match', $options);
  100 + $options->id = $DB->insert_record('qtype_match_options', $options);
112 101 }
113 102
114   - $options->subquestions = implode(',', $subquestions);
115 103 $options->shuffleanswers = $question->shuffleanswers;
116 104 $options = $this->save_combined_feedback_helper($options, $question, $context, true);
117   - $DB->update_record('question_match', $options);
  105 + $DB->update_record('qtype_match_options', $options);
118 106
119 107 $this->save_hints($question, true);
120 108
@@ -122,11 +110,6 @@ public function save_question_options($question) {
122 110 return $result;
123 111 }
124 112
125   - if (count($subquestions) < 3) {
126   - $result->notice = get_string('notenoughanswers', 'question', 3);
127   - return $result;
128   - }
129   -
130 113 return true;
131 114 }
132 115
@@ -162,8 +145,8 @@ protected function make_hint($hint) {
162 145
163 146 public function delete_question($questionid, $contextid) {
164 147 global $DB;
165   - $DB->delete_records('question_match', array('question' => $questionid));
166   - $DB->delete_records('question_match_sub', array('question' => $questionid));
  148 + $DB->delete_records('qtype_match_options', array('questionid' => $questionid));
  149 + $DB->delete_records('qtype_match_subquestions', array('questionid' => $questionid));
167 150
168 151 parent::delete_question($questionid, $contextid);
169 152 }
@@ -200,8 +183,8 @@ public function move_files($questionid, $oldcontextid, $newcontextid) {
200 183
201 184 parent::move_files($questionid, $oldcontextid, $newcontextid);
202 185
203   - $subquestionids = $DB->get_records_menu('question_match_sub',
204   - array('question' => $questionid), 'id', 'id,1');
  186 + $subquestionids = $DB->get_records_menu('qtype_match_subquestions',
  187 + array('questionid' => $questionid), 'id', 'id,1');
205 188 foreach ($subquestionids as $subquestionid => $notused) {
206 189 $fs->move_area_files_to_new_context($oldcontextid,
207 190 $newcontextid, 'qtype_match', 'subquestion', $subquestionid);
@@ -217,8 +200,8 @@ protected function delete_files($questionid, $contextid) {
217 200
218 201 parent::delete_files($questionid, $contextid);
219 202
220   - $subquestionids = $DB->get_records_menu('question_match_sub',
221   - array('question' => $questionid), 'id', 'id,1');
  203 + $subquestionids = $DB->get_records_menu('qtype_match_subquestions',
  204 + array('questionid' => $questionid), 'id', 'id,1');
222 205 foreach ($subquestionids as $subquestionid => $notused) {
223 206 $fs->delete_area_files($contextid, 'qtype_match', 'subquestion', $subquestionid);
224 207 }
63 question/type/match/tests/upgradelibnewqe_test.php
@@ -110,39 +110,34 @@ public function test_match_deferredfeedback_history6220() {
110 110 'maxmark' => '3',
111 111 'options' => (object) array(
112 112 'id' => '27',
113   - 'question' => '695',
  113 + 'questionid' => '695',
114 114 'subquestions' => array(
115 115 148 => (object) array(
116   - 'code' => '511093512',
117   - 'question' => '695',
  116 + 'questionid' => '695',
118 117 'questiontext' => 'Active adjacent system',
119 118 'answertext' => 'A system that interacts with or participates in the work.',
120 119 'id' => 148,
121 120 ),
122 121 149 => (object) array(
123   - 'code' => '10881658',
124   - 'question' => '695',
  122 + 'questionid' => '695',
125 123 'questiontext' => 'Autonomous adjacent system',
126 124 'answertext' => 'An external entity that acts independently of the work under study.',
127 125 'id' => 149,
128 126 ),
129 127 150 => (object) array(
130   - 'code' => '661953276',
131   - 'question' => '695',
  128 + 'questionid' => '695',
132 129 'questiontext' => 'Cooperative adjacent system',
133 130 'answertext' => 'A system that is involved in the response to a business event.',
134 131 'id' => 150,
135 132 ),
136 133 151 => (object) array(
137   - 'code' => '786218388',
138   - 'question' => '695',
  134 + 'questionid' => '695',
139 135 'questiontext' => '',
140 136 'answertext' => 'A system which does not supply or receive data from the work.',
141 137 'id' => 151,
142 138 ),
143 139 152 => (object) array(
144   - 'code' => '166673328',
145   - 'question' => '695',
  140 + 'questionid' => '695',
146 141 'questiontext' => '',
147 142 'answertext' => 'An external entity that performs part of the work under study.',
148 143 'id' => 152,
@@ -186,7 +181,7 @@ public function test_match_deferredfeedback_history6220() {
186 181 'question' => '695',
187 182 'originalquestion' => '0',
188 183 'seq_number' => '1',
189   - 'answer' => '148-511093512,149-786218388,150-166673328,151-0,152-0',
  184 + 'answer' => '148-148,149-151,150-152,151-0,152-0',
190 185 'timestamp' => '1177419855',
191 186 'event' => '2',
192 187 'grade' => '0',
@@ -199,7 +194,7 @@ public function test_match_deferredfeedback_history6220() {
199 194 'question' => '695',
200 195 'originalquestion' => '0',
201 196 'seq_number' => '2',
202   - 'answer' => '148-511093512,149-10881658,150-661953276,151-0,152-0',
  197 + 'answer' => '148-148,149-149,150-150,151-0,152-0',
203 198 'timestamp' => '1177419956',
204 199 'event' => '2',
205 200 'grade' => '0',
@@ -212,7 +207,7 @@ public function test_match_deferredfeedback_history6220() {
212 207 'question' => '695',
213 208 'originalquestion' => '0',
214 209 'seq_number' => '3',
215   - 'answer' => '148-511093512,149-10881658,150-661953276,151-0,152-0',
  210 + 'answer' => '148-148,149-149,150-150,151-0,152-0',
216 211 'timestamp' => '1177419956',
217 212 'event' => '6',
218 213 'grade' => '3',
@@ -360,32 +355,28 @@ public function test_match_deferredfeedback_history60() {
360 355 'maxmark' => '1',
361 356 'options' => (object) array(
362 357 'id' => '35',
363   - 'question' => '738',
  358 + 'questionid' => '738',
364 359 'subquestions' => array(
365 360 213 => (object) array(
366   - 'code' => '860968335',
367   - 'question' => '738',
  361 + 'questionid' => '738',
368 362 'questiontext' => 'Subject gateways provide links to sites that have been quality checked ',
369 363 'answertext' => 'True',
370 364 'id' => 213,
371 365 ),
372 366 214 => (object) array(
373   - 'code' => '253006016',
374   - 'question' => '738',
  367 + 'questionid' => '738',
375 368 'questiontext' => 'Subject gateways offer more variety than search engines ',
376 369 'answertext' => 'False',
377 370 'id' => 214,
378 371 ),
379 372 215 => (object) array(
380   - 'code' => '964910717',
381   - 'question' => '738',
  373 + 'questionid' => '738',
382 374 'questiontext' => 'Subject gateways index websites automatically',
383 375 'answertext' => 'False',
384 376 'id' => 215,
385 377 ),
386 378 216 => (object) array(
387   - 'code' => '3109713',
388   - 'question' => '738',
  379 + 'questionid' => '738',
389 380 'questiontext' => 'Subject gateways can provide a more direct route to websites containing academic content ',
390 381 'answertext' => 'True',
391 382 'id' => 216,
@@ -429,7 +420,7 @@ public function test_match_deferredfeedback_history60() {
429 420 'question' => '738',
430 421 'originalquestion' => '0',
431 422 'seq_number' => '1',
432   - 'answer' => '213-860968335,214-253006016,215-964910717,216-3109713',
  423 + 'answer' => '213-213,214-214,215-215,216-216',
433 424 'timestamp' => '1168267508',
434 425 'event' => '6',
435 426 'grade' => '1',
@@ -572,32 +563,28 @@ public function test_match_deferredfeedback_history622220() {
572 563 'maxmark' => '1',
573 564 'options' => (object) array(
574 565 'id' => '279',
575   - 'question' => '11135',
  566 + 'questionid' => '11135',
576 567 'subquestions' => array(
577 568 1632 => (object) array(
578   - 'code' => '315604704',
579   - 'question' => '11135',
  569 + 'questionid' => '11135',
580 570 'questiontext' => 'Subject gateways provide links to sites that have been quality checked',
581 571 'answertext' => 'True',
582 572 'id' => 1632,
583 573 ),
584 574 1633 => (object) array(
585   - 'code' => '750106618',
586   - 'question' => '11135',
  575 + 'questionid' => '11135',
587 576 'questiontext' => 'Subject gateways offer more variety than search engines',
588 577 'answertext' => 'False',
589 578 'id' => 1633,
590 579 ),
591 580 1634 => (object) array(
592   - 'code' => '446418834',
593   - 'question' => '11135',
  581 + 'questionid' => '11135',
594 582 'questiontext' => 'Subject gateways index websites automatically',
595 583 'answertext' => 'False',
596 584 'id' => 1634,
597 585 ),
598 586 1635 => (object) array(
599   - 'code' => '3262827',
600   - 'question' => '11135',
  587 + 'questionid' => '11135',
601 588 'questiontext' => 'Subject gateways can provide a more direct route to websites containing academic content',
602 589 'answertext' => 'True',
603 590 'id' => 1635,
@@ -641,7 +628,7 @@ public function test_match_deferredfeedback_history622220() {
641 628 'question' => '11135',
642 629 'originalquestion' => '0',
643 630 'seq_number' => '1',
644   - 'answer' => '1633-750106618,1635-3262827,1634-0,1632-315604704',
  631 + 'answer' => '1633-1633,1635-1635,1634-0,1632-1632',
645 632 'timestamp' => '1200507025',
646 633 'event' => '2',
647 634 'grade' => '0',
@@ -654,7 +641,7 @@ public function test_match_deferredfeedback_history622220() {
654 641 'question' => '11135',
655 642 'originalquestion' => '0',
656 643 'seq_number' => '2',
657   - 'answer' => '1633-750106618,1635-3262827,1634-0,1632-315604704',
  644 + 'answer' => '1633-1633,1635-1635,1634-0,1632-1632',
658 645 'timestamp' => '1200507125',
659 646 'event' => '2',
660 647 'grade' => '0',
@@ -667,7 +654,7 @@ public function test_match_deferredfeedback_history622220() {
667 654 'question' => '11135',
668 655 'originalquestion' => '0',
669 656 'seq_number' => '3',
670   - 'answer' => '1633-750106618,1635-3262827,1634-0,1632-315604704',
  657 + 'answer' => '1633-1633,1635-1635,1634-0,1632-1632',
671 658 'timestamp' => '1200507172',
672 659 'event' => '2',
673 660 'grade' => '0',
@@ -680,7 +667,7 @@ public function test_match_deferredfeedback_history622220() {
680 667 'question' => '11135',
681 668 'originalquestion' => '0',
682 669 'seq_number' => '4',
683   - 'answer' => '1633-750106618,1635-3262827,1634-3262827,1632-315604704',
  670 + 'answer' => '1633-1633,1635-1635,1634-1635,1632-1632',
684 671 'timestamp' => '1200507467',
685 672 'event' => '2',
686 673 'grade' => '0',
@@ -693,7 +680,7 @@ public function test_match_deferredfeedback_history622220() {
693 680 'question' => '11135',
694 681 'originalquestion' => '0',
695 682 'seq_number' => '5',
696   - 'answer' => '1633-750106618,1635-3262827,1634-3262827,1632-315604704',
  683 + 'answer' => '1633-1632,1635-1635,1634-1635,1632-1632',
697 684 'timestamp' => '1200507467',
698 685 'event' => '6',
699 686 'grade' => '0.75',
2  question/type/match/version.php
@@ -26,7 +26,7 @@
26 26 defined('MOODLE_INTERNAL') || die();
27 27
28 28 $plugin->component = 'qtype_match';
29   -$plugin->version = 2012112900;
  29 +$plugin->version = 2013012109;
30 30
31 31 $plugin->requires = 2012112900;
32 32

0 comments on commit 87d7673

Please sign in to comment.
Something went wrong with that request. Please try again.