*/
class restore_qtype_match_plugin extends restore_qtype_plugin {
+ /**
+ * A simple answer, questiontext to id cache for a match answers.
+ * @var array
+ */
+ private $questionsubcache = array();
+
+ /**
+ * The id of the current question in the questionsubcache.
+ * @var int
+ */
+ private $questionsubcacheid = null;
+
+
/**
* Returns the paths to be handled by the plugin at question level.
*/
// Insert record.
$newitemid = $DB->insert_record('qtype_match_subquestions', $data);
// Create mapping (there are files and states based on this).
- $this->set_mapping('qtype_match_subquestions', $oldid, $newitemid);
if (isset($data->code)) {
$this->set_mapping('qtype_match_subquestion_codes', $data->code, $newitemid);
}
// Match questions require mapping of qtype_match_subquestions, because
// they are used by question_states->answer.
- // Look for matching subquestion (by questionid, questiontext and answertext).
- $sub = $DB->get_record_select('qtype_match_subquestions', 'questionid = ? AND ' .
- $DB->sql_compare_text('questiontext') . ' = ' .
- $DB->sql_compare_text('?').' AND answertext = ?',
- array($newquestionid, $data->questiontext, $data->answertext),
- 'id', IGNORE_MULTIPLE);
+ // Have we cached the current question?
+ if ($this->questionsubcacheid !== $newquestionid) {
+ // The question changed, purge and start again!
+ $this->questionsubcache = array();
- // Not able to find the answer, let's try cleaning the answertext
- // of all the match subquestions in DB as slower fallback. MDL-36683 / MDL-30018.
- if (!$sub) {
+ $params = array('question' => $newquestionid);
$potentialsubs = $DB->get_records('qtype_match_subquestions',
- array('questionid' => $newquestionid), '', 'id, questiontext, answertext');
+ array('questionid' => $newquestionid), '', 'id, questiontext, answertext');
+
+ $this->questionsubcacheid = $newquestionid;
+ // Cache all cleaned answers and questiontext.
foreach ($potentialsubs as $potentialsub) {
// Clean in the same way than {@link xml_writer::xml_safe_utf8()}.
$cleanquestion = preg_replace('/[\x-\x8\xb-\xc\xe-\x1f\x7f]/is',
'', $potentialsub->answertext); // Clean CTRL chars.
$cleananswer = preg_replace("/\r\n|\r/", "\n", $cleananswer); // Normalize line ending.
- if ($cleanquestion === $data->questiontext && $cleananswer == $data->answertext) {
- $sub = $potentialsub;
- }
+ $this->questionsubcache[$cleanquestion][$cleananswer] = $potentialsub->id;
}
}
- // Found one. Let's create the mapping.
- if ($sub) {
- $this->set_mapping('qtype_match_subquestions', $oldid, $sub->id);
- } else {
+ if (!isset($this->questionsubcache[$data->questiontext][$data->answertext])) {
throw new restore_step_exception('error_qtype_match_subquestion_missing_in_db', $data);
}
+ $newitemid = $this->questionsubcache[$data->questiontext][$data->answertext];
}
+
+ // Found one. Let's create the mapping.
+ $this->set_mapping('qtype_match_subquestions', $oldid, $newitemid);
}
public function recode_response($questionid, $sequencenumber, array $response) {