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 | /** | |
f7970e3c | 18 | * @package moodlecore |
41941110 | 19 | * @subpackage backup-moodle2 |
f7970e3c TH |
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 | |
41941110 EL |
22 | */ |
23 | ||
a17b297d TH |
24 | |
25 | defined('MOODLE_INTERNAL') || die(); | |
26 | ||
41941110 EL |
27 | |
28 | /** | |
29 | * Structure step to restore one quiz activity | |
f7970e3c TH |
30 | * |
31 | * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com} | |
32 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
41941110 EL |
33 | */ |
34 | class restore_quiz_activity_structure_step extends restore_questions_activity_structure_step { | |
35 | ||
36 | protected function define_structure() { | |
37 | ||
38 | $paths = array(); | |
39 | $userinfo = $this->get_setting_value('userinfo'); | |
40 | ||
5adace99 TH |
41 | $quiz = new restore_path_element('quiz', '/activity/quiz'); |
42 | $paths[] = $quiz; | |
43 | ||
44 | // A chance for access subplugings to set up their quiz data. | |
45 | $this->add_subplugin_structure('quizaccess', $quiz); | |
46 | ||
55ca80ed TH |
47 | $paths[] = new restore_path_element('quiz_question_instance', |
48 | '/activity/quiz/question_instances/question_instance'); | |
41941110 EL |
49 | $paths[] = new restore_path_element('quiz_feedback', '/activity/quiz/feedbacks/feedback'); |
50 | $paths[] = new restore_path_element('quiz_override', '/activity/quiz/overrides/override'); | |
5adace99 | 51 | |
41941110 EL |
52 | if ($userinfo) { |
53 | $paths[] = new restore_path_element('quiz_grade', '/activity/quiz/grades/grade'); | |
18ab06ba TH |
54 | |
55 | if ($this->task->get_old_moduleversion() > 2011010100) { | |
56 | // Restoring from a version 2.1 dev or later. | |
57 | // Process the new-style attempt data. | |
58 | $quizattempt = new restore_path_element('quiz_attempt', | |
59 | '/activity/quiz/attempts/attempt'); | |
60 | $paths[] = $quizattempt; | |
5adace99 | 61 | |
9e83f3d1 | 62 | // Add states and sessions. |
18ab06ba TH |
63 | $this->add_question_usages($quizattempt, $paths); |
64 | ||
5adace99 TH |
65 | // A chance for access subplugings to set up their attempt data. |
66 | $this->add_subplugin_structure('quizaccess', $quizattempt); | |
67 | ||
18ab06ba TH |
68 | } else { |
69 | // Restoring from a version 2.0.x+ or earlier. | |
70 | // Upgrade the legacy attempt data. | |
71 | $quizattempt = new restore_path_element('quiz_attempt_legacy', | |
72 | '/activity/quiz/attempts/attempt', | |
73 | true); | |
74 | $paths[] = $quizattempt; | |
75 | $this->add_legacy_question_attempt_data($quizattempt, $paths); | |
76 | } | |
41941110 EL |
77 | } |
78 | ||
9e83f3d1 | 79 | // Return the paths wrapped into standard activity structure. |
41941110 EL |
80 | return $this->prepare_activity_structure($paths); |
81 | } | |
82 | ||
83 | protected function process_quiz($data) { | |
f3ca24e4 | 84 | global $CFG, $DB; |
41941110 EL |
85 | |
86 | $data = (object)$data; | |
87 | $oldid = $data->id; | |
88 | $data->course = $this->get_courseid(); | |
89 | ||
90 | $data->timeopen = $this->apply_date_offset($data->timeopen); | |
91 | $data->timeclose = $this->apply_date_offset($data->timeclose); | |
92 | $data->timecreated = $this->apply_date_offset($data->timecreated); | |
93 | $data->timemodified = $this->apply_date_offset($data->timemodified); | |
94 | ||
9e83f3d1 | 95 | // Needed by {@link process_quiz_attempt_legacy}. |
18ab06ba | 96 | $this->oldquizlayout = $data->questions; |
41941110 EL |
97 | $data->questions = $this->questions_recode_layout($data->questions); |
98 | ||
9e83f3d1 TH |
99 | // The setting quiz->attempts can come both in data->attempts and |
100 | // data->attempts_number, handle both. MDL-26229. | |
7cff4927 EL |
101 | if (isset($data->attempts_number)) { |
102 | $data->attempts = $data->attempts_number; | |
103 | unset($data->attempts_number); | |
104 | } | |
105 | ||
f3ca24e4 | 106 | // The old optionflags and penaltyscheme from 2.0 need to be mapped to |
9e83f3d1 | 107 | // the new preferredbehaviour. See MDL-20636. |
f3ca24e4 TH |
108 | if (!isset($data->preferredbehaviour)) { |
109 | if (empty($data->optionflags)) { | |
110 | $data->preferredbehaviour = 'deferredfeedback'; | |
111 | } else if (empty($data->penaltyscheme)) { | |
112 | $data->preferredbehaviour = 'adaptivenopenalty'; | |
113 | } else { | |
114 | $data->preferredbehaviour = 'adaptive'; | |
115 | } | |
116 | unset($data->optionflags); | |
117 | unset($data->penaltyscheme); | |
118 | } | |
119 | ||
120 | // The old review column from 2.0 need to be split into the seven new | |
9e83f3d1 | 121 | // review columns. See MDL-20636. |
f3ca24e4 TH |
122 | if (isset($data->review)) { |
123 | require_once($CFG->dirroot . '/mod/quiz/locallib.php'); | |
124 | ||
125 | if (!defined('QUIZ_OLD_IMMEDIATELY')) { | |
126 | define('QUIZ_OLD_IMMEDIATELY', 0x3c003f); | |
127 | define('QUIZ_OLD_OPEN', 0x3c00fc0); | |
128 | define('QUIZ_OLD_CLOSED', 0x3c03f000); | |
129 | ||
55ca80ed TH |
130 | define('QUIZ_OLD_RESPONSES', 1*0x1041); |
131 | define('QUIZ_OLD_SCORES', 2*0x1041); | |
132 | define('QUIZ_OLD_FEEDBACK', 4*0x1041); | |
133 | define('QUIZ_OLD_ANSWERS', 8*0x1041); | |
134 | define('QUIZ_OLD_SOLUTIONS', 16*0x1041); | |
135 | define('QUIZ_OLD_GENERALFEEDBACK', 32*0x1041); | |
136 | define('QUIZ_OLD_OVERALLFEEDBACK', 1*0x4440000); | |
f3ca24e4 TH |
137 | } |
138 | ||
139 | $oldreview = $data->review; | |
140 | ||
141 | $data->reviewattempt = | |
142 | mod_quiz_display_options::DURING | | |
55ca80ed TH |
143 | ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_RESPONSES ? |
144 | mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | | |
145 | ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_RESPONSES ? | |
146 | mod_quiz_display_options::LATER_WHILE_OPEN : 0) | | |
147 | ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_RESPONSES ? | |
148 | mod_quiz_display_options::AFTER_CLOSE : 0); | |
f3ca24e4 TH |
149 | |
150 | $data->reviewcorrectness = | |
151 | mod_quiz_display_options::DURING | | |
55ca80ed TH |
152 | ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_SCORES ? |
153 | mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | | |
154 | ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_SCORES ? | |
155 | mod_quiz_display_options::LATER_WHILE_OPEN : 0) | | |
156 | ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_SCORES ? | |
157 | mod_quiz_display_options::AFTER_CLOSE : 0); | |
f3ca24e4 TH |
158 | |
159 | $data->reviewmarks = | |
160 | mod_quiz_display_options::DURING | | |
55ca80ed TH |
161 | ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_SCORES ? |
162 | mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | | |
163 | ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_SCORES ? | |
164 | mod_quiz_display_options::LATER_WHILE_OPEN : 0) | | |
165 | ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_SCORES ? | |
166 | mod_quiz_display_options::AFTER_CLOSE : 0); | |
f3ca24e4 TH |
167 | |
168 | $data->reviewspecificfeedback = | |
55ca80ed TH |
169 | ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_FEEDBACK ? |
170 | mod_quiz_display_options::DURING : 0) | | |
171 | ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_FEEDBACK ? | |
172 | mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | | |
173 | ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_FEEDBACK ? | |
174 | mod_quiz_display_options::LATER_WHILE_OPEN : 0) | | |
175 | ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_FEEDBACK ? | |
176 | mod_quiz_display_options::AFTER_CLOSE : 0); | |
f3ca24e4 TH |
177 | |
178 | $data->reviewgeneralfeedback = | |
55ca80ed TH |
179 | ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_GENERALFEEDBACK ? |
180 | mod_quiz_display_options::DURING : 0) | | |
181 | ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_GENERALFEEDBACK ? | |
182 | mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | | |
183 | ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_GENERALFEEDBACK ? | |
184 | mod_quiz_display_options::LATER_WHILE_OPEN : 0) | | |
185 | ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_GENERALFEEDBACK ? | |
186 | mod_quiz_display_options::AFTER_CLOSE : 0); | |
f3ca24e4 TH |
187 | |
188 | $data->reviewrightanswer = | |
55ca80ed TH |
189 | ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_ANSWERS ? |
190 | mod_quiz_display_options::DURING : 0) | | |
191 | ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_ANSWERS ? | |
192 | mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | | |
193 | ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_ANSWERS ? | |
194 | mod_quiz_display_options::LATER_WHILE_OPEN : 0) | | |
195 | ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_ANSWERS ? | |
196 | mod_quiz_display_options::AFTER_CLOSE : 0); | |
f3ca24e4 TH |
197 | |
198 | $data->reviewoverallfeedback = | |
199 | 0 | | |
55ca80ed TH |
200 | ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_OVERALLFEEDBACK ? |
201 | mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | | |
202 | ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_OVERALLFEEDBACK ? | |
203 | mod_quiz_display_options::LATER_WHILE_OPEN : 0) | | |
204 | ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_OVERALLFEEDBACK ? | |
205 | mod_quiz_display_options::AFTER_CLOSE : 0); | |
f3ca24e4 TH |
206 | } |
207 | ||
4344c5d5 | 208 | // The old popup column from from <= 2.1 need to be mapped to |
9e83f3d1 | 209 | // the new browsersecurity. See MDL-29627. |
4344c5d5 TH |
210 | if (!isset($data->browsersecurity)) { |
211 | if (empty($data->popup)) { | |
212 | $data->browsersecurity = '-'; | |
213 | } else if ($data->popup == 1) { | |
214 | $data->browsersecurity = 'securewindow'; | |
215 | } else if ($data->popup == 2) { | |
216 | $data->browsersecurity = 'safebrowser'; | |
217 | } else { | |
218 | $data->preferredbehaviour = '-'; | |
219 | } | |
220 | unset($data->popup); | |
221 | } | |
222 | ||
6d2baaae CC |
223 | if (!isset($data->overduehandling)) { |
224 | $data->overduehandling = get_config('quiz', 'overduehandling'); | |
225 | } | |
226 | ||
9e83f3d1 | 227 | // Insert the quiz record. |
41941110 | 228 | $newitemid = $DB->insert_record('quiz', $data); |
9e83f3d1 | 229 | // Immediately after inserting "activity" record, call this. |
41941110 EL |
230 | $this->apply_activity_instance($newitemid); |
231 | } | |
232 | ||
233 | protected function process_quiz_question_instance($data) { | |
234 | global $DB; | |
235 | ||
236 | $data = (object)$data; | |
41941110 | 237 | |
e5c5f52e | 238 | // Backwards compatibility for old field names (MDL-43670). |
dc4a3ea1 TH |
239 | if (!isset($data->questionid) && isset($data->question)) { |
240 | $data->questionid = $data->question; | |
241 | } | |
242 | if (!isset($data->maxmark) && isset($data->grade)) { | |
243 | $data->maxmark = $data->grade; | |
244 | } | |
41941110 | 245 | |
dc4a3ea1 TH |
246 | $data->quizid = $this->get_new_parentid('quiz'); |
247 | $data->questionid = $this->get_mappingid('question', $data->questionid); | |
41941110 EL |
248 | |
249 | $DB->insert_record('quiz_question_instances', $data); | |
250 | } | |
251 | ||
252 | protected function process_quiz_feedback($data) { | |
253 | global $DB; | |
254 | ||
255 | $data = (object)$data; | |
256 | $oldid = $data->id; | |
257 | ||
258 | $data->quizid = $this->get_new_parentid('quiz'); | |
259 | ||
260 | $newitemid = $DB->insert_record('quiz_feedback', $data); | |
9e83f3d1 | 261 | $this->set_mapping('quiz_feedback', $oldid, $newitemid, true); // Has related files. |
41941110 EL |
262 | } |
263 | ||
264 | protected function process_quiz_override($data) { | |
265 | global $DB; | |
266 | ||
267 | $data = (object)$data; | |
268 | $oldid = $data->id; | |
269 | ||
9e83f3d1 | 270 | // Based on userinfo, we'll restore user overides or no. |
41941110 EL |
271 | $userinfo = $this->get_setting_value('userinfo'); |
272 | ||
9e83f3d1 | 273 | // Skip user overrides if we are not restoring userinfo. |
41941110 EL |
274 | if (!$userinfo && !is_null($data->userid)) { |
275 | return; | |
276 | } | |
277 | ||
278 | $data->quiz = $this->get_new_parentid('quiz'); | |
279 | ||
280 | $data->userid = $this->get_mappingid('user', $data->userid); | |
281 | $data->groupid = $this->get_mappingid('group', $data->groupid); | |
282 | ||
283 | $data->timeopen = $this->apply_date_offset($data->timeopen); | |
284 | $data->timeclose = $this->apply_date_offset($data->timeclose); | |
285 | ||
0f66aced EL |
286 | $newitemid = $DB->insert_record('quiz_overrides', $data); |
287 | ||
9e83f3d1 | 288 | // Add mapping, restore of logs needs it. |
0f66aced | 289 | $this->set_mapping('quiz_override', $oldid, $newitemid); |
41941110 EL |
290 | } |
291 | ||
292 | protected function process_quiz_grade($data) { | |
293 | global $DB; | |
294 | ||
295 | $data = (object)$data; | |
296 | $oldid = $data->id; | |
297 | ||
298 | $data->quiz = $this->get_new_parentid('quiz'); | |
299 | ||
300 | $data->userid = $this->get_mappingid('user', $data->userid); | |
301 | $data->grade = $data->gradeval; | |
302 | ||
303 | $data->timemodified = $this->apply_date_offset($data->timemodified); | |
304 | ||
305 | $DB->insert_record('quiz_grades', $data); | |
306 | } | |
307 | ||
308 | protected function process_quiz_attempt($data) { | |
41941110 | 309 | $data = (object)$data; |
41941110 EL |
310 | |
311 | $data->quiz = $this->get_new_parentid('quiz'); | |
312 | $data->attempt = $data->attemptnum; | |
313 | ||
41941110 EL |
314 | $data->userid = $this->get_mappingid('user', $data->userid); |
315 | ||
316 | $data->timestart = $this->apply_date_offset($data->timestart); | |
317 | $data->timefinish = $this->apply_date_offset($data->timefinish); | |
318 | $data->timemodified = $this->apply_date_offset($data->timemodified); | |
816138b4 TH |
319 | if (!empty($data->timecheckstate)) { |
320 | $data->timecheckstate = $this->apply_date_offset($data->timecheckstate); | |
321 | } else { | |
322 | $data->timecheckstate = 0; | |
323 | } | |
41941110 | 324 | |
584ae11a TH |
325 | // Deals with up-grading pre-2.3 back-ups to 2.3+. |
326 | if (!isset($data->state)) { | |
327 | if ($data->timefinish > 0) { | |
328 | $data->state = 'finished'; | |
329 | } else { | |
330 | $data->state = 'inprogress'; | |
331 | } | |
332 | } | |
333 | ||
50de6ad0 TH |
334 | // The data is actually inserted into the database later in inform_new_usage_id. |
335 | $this->currentquizattempt = clone($data); | |
c749527b TH |
336 | } |
337 | ||
18ab06ba TH |
338 | protected function process_quiz_attempt_legacy($data) { |
339 | global $DB; | |
340 | ||
341 | $this->process_quiz_attempt($data); | |
342 | ||
343 | $quiz = $DB->get_record('quiz', array('id' => $this->get_new_parentid('quiz'))); | |
344 | $quiz->oldquestions = $this->oldquizlayout; | |
345 | $this->process_legacy_quiz_attempt_data($data, $quiz); | |
346 | } | |
347 | ||
c749527b TH |
348 | protected function inform_new_usage_id($newusageid) { |
349 | global $DB; | |
50de6ad0 TH |
350 | |
351 | $data = $this->currentquizattempt; | |
352 | ||
353 | $oldid = $data->id; | |
354 | $data->uniqueid = $newusageid; | |
355 | ||
356 | $newitemid = $DB->insert_record('quiz_attempts', $data); | |
357 | ||
9e83f3d1 | 358 | // Save quiz_attempt->id mapping, because logs use it. |
50de6ad0 | 359 | $this->set_mapping('quiz_attempt', $oldid, $newitemid, false); |
41941110 EL |
360 | } |
361 | ||
362 | protected function after_execute() { | |
c749527b | 363 | parent::after_execute(); |
9e83f3d1 | 364 | // Add quiz related files, no need to match by itemname (just internally handled context). |
41941110 | 365 | $this->add_related_files('mod_quiz', 'intro', null); |
9e83f3d1 | 366 | // Add feedback related files, matching by itemname = 'quiz_feedback'. |
41941110 EL |
367 | $this->add_related_files('mod_quiz', 'feedback', 'quiz_feedback'); |
368 | } | |
369 | } |