Commit | Line | Data |
---|---|---|
41941110 | 1 | <?php |
41941110 EL |
2 | // This file is part of Moodle - http://moodle.org/ |
3 | // | |
4 | // Moodle is free software: you can redistribute it and/or modify | |
5 | // it under the terms of the GNU General Public License as published by | |
6 | // the Free Software Foundation, either version 3 of the License, or | |
7 | // (at your option) any later version. | |
8 | // | |
9 | // Moodle is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | // | |
14 | // You should have received a copy of the GNU General Public License | |
15 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | /** | |
18 | * @package moodlecore | |
19 | * @subpackage backup-moodle2 | |
20 | * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} | |
21 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
22 | */ | |
23 | ||
a17b297d | 24 | |
41941110 EL |
25 | defined('MOODLE_INTERNAL') || die(); |
26 | ||
a17b297d | 27 | |
41941110 EL |
28 | /** |
29 | * restore plugin class that provides the necessary information | |
30 | * needed to restore one multianswer qtype plugin | |
f7970e3c TH |
31 | * |
32 | * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} | |
33 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
41941110 EL |
34 | */ |
35 | class restore_qtype_multianswer_plugin extends restore_qtype_plugin { | |
36 | ||
37 | /** | |
38 | * Returns the paths to be handled by the plugin at question level | |
39 | */ | |
40 | protected function define_question_plugin_structure() { | |
41 | ||
42 | $paths = array(); | |
43 | ||
44 | // This qtype uses question_answers, add them | |
45 | $this->add_question_question_answers($paths); | |
46 | ||
47 | // Add own qtype stuff | |
48 | $elename = 'multianswer'; | |
49 | $elepath = $this->get_pathfor('/multianswer'); // we used get_recommended_name() so this works | |
50 | $paths[] = new restore_path_element($elename, $elepath); | |
51 | ||
52 | ||
53 | return $paths; // And we return the interesting paths | |
54 | } | |
55 | ||
56 | /** | |
57 | * Process the qtype/multianswer element | |
58 | */ | |
59 | public function process_multianswer($data) { | |
60 | global $DB; | |
61 | ||
62 | $data = (object)$data; | |
63 | $oldid = $data->id; | |
64 | ||
65 | // Detect if the question is created or mapped | |
66 | $oldquestionid = $this->get_old_parentid('question'); | |
67 | $newquestionid = $this->get_new_parentid('question'); | |
68 | $questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false; | |
69 | ||
70 | // If the question has been created by restore, we need to create its question_multianswer too | |
71 | if ($questioncreated) { | |
72 | // Adjust some columns | |
73 | $data->question = $newquestionid; | |
74 | // Note: multianswer->sequence is a list of question->id values. We aren't | |
75 | // recoding them here (because some questions can be missing yet). Instead | |
76 | // we'll perform the recode in the {@link after_execute} method of the plugin | |
77 | // that gets executed once all questions have been created | |
78 | // Insert record | |
79 | $newitemid = $DB->insert_record('question_multianswer', $data); | |
80 | // Create mapping (need it for after_execute recode of sequence) | |
81 | $this->set_mapping('question_multianswer', $oldid, $newitemid); | |
82 | } else { | |
83 | // Nothing to remap if the question already existed | |
84 | } | |
85 | } | |
86 | ||
87 | /** | |
88 | * This method is executed once the whole restore_structure_step | |
89 | * this step is part of ({@link restore_create_categories_and_questions}) | |
90 | * has ended processing the whole xml structure. Its name is: | |
91 | * "after_execute_" + connectionpoint ("question") | |
92 | * | |
93 | * For multianswer qtype we use it to restore the sequence column, | |
94 | * containing one list of question ids | |
95 | */ | |
96 | public function after_execute_question() { | |
97 | global $DB; | |
98 | // Now that all the questions have been restored, let's process | |
99 | // the created question_multianswer sequences (list of question ids) | |
100 | $rs = $DB->get_recordset_sql("SELECT qma.id, qma.sequence | |
101 | FROM {question_multianswer} qma | |
102 | JOIN {backup_ids_temp} bi ON bi.newitemid = qma.question | |
103 | WHERE bi.backupid = ? | |
104 | AND bi.itemname = 'question_created'", array($this->get_restoreid())); | |
105 | foreach ($rs as $rec) { | |
106 | $sequencearr = explode(',', $rec->sequence); | |
107 | foreach ($sequencearr as $key => $question) { | |
108 | $sequencearr[$key] = $this->get_mappingid('question', $question); | |
109 | } | |
110 | $sequence = implode(',', $sequencearr); | |
111 | $DB->set_field('question_multianswer', 'sequence', $sequence, array('id' => $rec->id)); | |
112 | } | |
113 | $rs->close(); | |
114 | } | |
115 | ||
116 | /** | |
117 | * Given one question_states record, return the answer | |
118 | * recoded pointing to all the restored stuff for multianswer questions | |
119 | * | |
120 | * answer is one comma separated list of hypen separated pairs | |
121 | * containing sequence (pointing to questions sequence in question_multianswer) | |
122 | * and mixed answers. We'll delegate | |
123 | * the recoding of answers to the proper qtype | |
124 | */ | |
125 | public function recode_state_answer($state) { | |
126 | global $DB; | |
127 | $answer = $state->answer; | |
128 | $resultarr = array(); | |
129 | // Get sequence of questions | |
130 | $sequence = $DB->get_field('question_multianswer', 'sequence', array('question' => $state->question)); | |
131 | $sequencearr = explode(',', $sequence); | |
132 | // Let's process each pair | |
133 | foreach (explode(',', $answer) as $pair) { | |
134 | $pairarr = explode('-', $pair); | |
135 | $sequenceid = $pairarr[0]; | |
136 | $subanswer = $pairarr[1]; | |
137 | // Calculate the questionid based on sequenceid | |
138 | // Note it is already one *new* questionid that doesn't need mapping | |
139 | $questionid = $sequencearr[$sequenceid-1]; | |
140 | // Fetch qtype of the question (needed for delegation) | |
141 | $questionqtype = $DB->get_field('question', 'qtype', array('id' => $questionid)); | |
142 | // Delegate subanswer recode to proper qtype, faking one question_states record | |
143 | $substate = new stdClass(); | |
144 | $substate->question = $questionid; | |
145 | $substate->answer = $subanswer; | |
146 | $newanswer = $this->step->restore_recode_answer($substate, $questionqtype); | |
147 | $resultarr[] = implode('-', array($sequenceid, $newanswer)); | |
148 | } | |
149 | return implode(',', $resultarr); | |
150 | } | |
151 | ||
152 | } |