[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
1 <?php 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 mod_quiz 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 24 25 defined('MOODLE_INTERNAL') || die(); 26 27 28 /** 29 * Structure step to restore one quiz activity 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 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 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 47 $paths[] = new restore_path_element('quiz_question_instance', 48 '/activity/quiz/question_instances/question_instance'); 49 $paths[] = new restore_path_element('quiz_feedback', '/activity/quiz/feedbacks/feedback'); 50 $paths[] = new restore_path_element('quiz_override', '/activity/quiz/overrides/override'); 51 52 if ($userinfo) { 53 $paths[] = new restore_path_element('quiz_grade', '/activity/quiz/grades/grade'); 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; 61 62 // Add states and sessions. 63 $this->add_question_usages($quizattempt, $paths); 64 65 // A chance for access subplugings to set up their attempt data. 66 $this->add_subplugin_structure('quizaccess', $quizattempt); 67 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 } 77 } 78 79 // Return the paths wrapped into standard activity structure. 80 return $this->prepare_activity_structure($paths); 81 } 82 83 protected function process_quiz($data) { 84 global $CFG, $DB; 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 95 if (property_exists($data, 'questions')) { 96 // Needed by {@link process_quiz_attempt_legacy}, in which case it will be present. 97 $this->oldquizlayout = $data->questions; 98 } 99 100 // The setting quiz->attempts can come both in data->attempts and 101 // data->attempts_number, handle both. MDL-26229. 102 if (isset($data->attempts_number)) { 103 $data->attempts = $data->attempts_number; 104 unset($data->attempts_number); 105 } 106 107 // The old optionflags and penaltyscheme from 2.0 need to be mapped to 108 // the new preferredbehaviour. See MDL-20636. 109 if (!isset($data->preferredbehaviour)) { 110 if (empty($data->optionflags)) { 111 $data->preferredbehaviour = 'deferredfeedback'; 112 } else if (empty($data->penaltyscheme)) { 113 $data->preferredbehaviour = 'adaptivenopenalty'; 114 } else { 115 $data->preferredbehaviour = 'adaptive'; 116 } 117 unset($data->optionflags); 118 unset($data->penaltyscheme); 119 } 120 121 // The old review column from 2.0 need to be split into the seven new 122 // review columns. See MDL-20636. 123 if (isset($data->review)) { 124 require_once($CFG->dirroot . '/mod/quiz/locallib.php'); 125 126 if (!defined('QUIZ_OLD_IMMEDIATELY')) { 127 define('QUIZ_OLD_IMMEDIATELY', 0x3c003f); 128 define('QUIZ_OLD_OPEN', 0x3c00fc0); 129 define('QUIZ_OLD_CLOSED', 0x3c03f000); 130 131 define('QUIZ_OLD_RESPONSES', 1*0x1041); 132 define('QUIZ_OLD_SCORES', 2*0x1041); 133 define('QUIZ_OLD_FEEDBACK', 4*0x1041); 134 define('QUIZ_OLD_ANSWERS', 8*0x1041); 135 define('QUIZ_OLD_SOLUTIONS', 16*0x1041); 136 define('QUIZ_OLD_GENERALFEEDBACK', 32*0x1041); 137 define('QUIZ_OLD_OVERALLFEEDBACK', 1*0x4440000); 138 } 139 140 $oldreview = $data->review; 141 142 $data->reviewattempt = 143 mod_quiz_display_options::DURING | 144 ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_RESPONSES ? 145 mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | 146 ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_RESPONSES ? 147 mod_quiz_display_options::LATER_WHILE_OPEN : 0) | 148 ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_RESPONSES ? 149 mod_quiz_display_options::AFTER_CLOSE : 0); 150 151 $data->reviewcorrectness = 152 mod_quiz_display_options::DURING | 153 ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_SCORES ? 154 mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | 155 ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_SCORES ? 156 mod_quiz_display_options::LATER_WHILE_OPEN : 0) | 157 ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_SCORES ? 158 mod_quiz_display_options::AFTER_CLOSE : 0); 159 160 $data->reviewmarks = 161 mod_quiz_display_options::DURING | 162 ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_SCORES ? 163 mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | 164 ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_SCORES ? 165 mod_quiz_display_options::LATER_WHILE_OPEN : 0) | 166 ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_SCORES ? 167 mod_quiz_display_options::AFTER_CLOSE : 0); 168 169 $data->reviewspecificfeedback = 170 ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_FEEDBACK ? 171 mod_quiz_display_options::DURING : 0) | 172 ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_FEEDBACK ? 173 mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | 174 ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_FEEDBACK ? 175 mod_quiz_display_options::LATER_WHILE_OPEN : 0) | 176 ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_FEEDBACK ? 177 mod_quiz_display_options::AFTER_CLOSE : 0); 178 179 $data->reviewgeneralfeedback = 180 ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_GENERALFEEDBACK ? 181 mod_quiz_display_options::DURING : 0) | 182 ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_GENERALFEEDBACK ? 183 mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | 184 ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_GENERALFEEDBACK ? 185 mod_quiz_display_options::LATER_WHILE_OPEN : 0) | 186 ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_GENERALFEEDBACK ? 187 mod_quiz_display_options::AFTER_CLOSE : 0); 188 189 $data->reviewrightanswer = 190 ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_ANSWERS ? 191 mod_quiz_display_options::DURING : 0) | 192 ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_ANSWERS ? 193 mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | 194 ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_ANSWERS ? 195 mod_quiz_display_options::LATER_WHILE_OPEN : 0) | 196 ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_ANSWERS ? 197 mod_quiz_display_options::AFTER_CLOSE : 0); 198 199 $data->reviewoverallfeedback = 200 0 | 201 ($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_OVERALLFEEDBACK ? 202 mod_quiz_display_options::IMMEDIATELY_AFTER : 0) | 203 ($oldreview & QUIZ_OLD_OPEN & QUIZ_OLD_OVERALLFEEDBACK ? 204 mod_quiz_display_options::LATER_WHILE_OPEN : 0) | 205 ($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_OVERALLFEEDBACK ? 206 mod_quiz_display_options::AFTER_CLOSE : 0); 207 } 208 209 // The old popup column from from <= 2.1 need to be mapped to 210 // the new browsersecurity. See MDL-29627. 211 if (!isset($data->browsersecurity)) { 212 if (empty($data->popup)) { 213 $data->browsersecurity = '-'; 214 } else if ($data->popup == 1) { 215 $data->browsersecurity = 'securewindow'; 216 } else if ($data->popup == 2) { 217 $data->browsersecurity = 'safebrowser'; 218 } else { 219 $data->preferredbehaviour = '-'; 220 } 221 unset($data->popup); 222 } 223 224 if (!isset($data->overduehandling)) { 225 $data->overduehandling = get_config('quiz', 'overduehandling'); 226 } 227 228 // Insert the quiz record. 229 $newitemid = $DB->insert_record('quiz', $data); 230 // Immediately after inserting "activity" record, call this. 231 $this->apply_activity_instance($newitemid); 232 } 233 234 protected function process_quiz_question_instance($data) { 235 global $DB; 236 237 $data = (object)$data; 238 239 // Backwards compatibility for old field names (MDL-43670). 240 if (!isset($data->questionid) && isset($data->question)) { 241 $data->questionid = $data->question; 242 } 243 if (!isset($data->maxmark) && isset($data->grade)) { 244 $data->maxmark = $data->grade; 245 } 246 247 if (!property_exists($data, 'slot')) { 248 $page = 1; 249 $slot = 1; 250 foreach (explode(',', $this->oldquizlayout) as $item) { 251 if ($item == 0) { 252 $page += 1; 253 continue; 254 } 255 if ($item == $data->questionid) { 256 $data->slot = $slot; 257 $data->page = $page; 258 break; 259 } 260 $slot += 1; 261 } 262 } 263 264 if (!property_exists($data, 'slot')) { 265 // There was a question_instance in the backup file for a question 266 // that was not acutally in the quiz. Drop it. 267 $this->log('question ' . $data->questionid . ' was associated with quiz ' . 268 $this->get_new_parentid('quiz') . ' but not actually used. ' . 269 'The instance has been ignored.', backup::LOG_INFO); 270 return; 271 } 272 273 $data->quizid = $this->get_new_parentid('quiz'); 274 $data->questionid = $this->get_mappingid('question', $data->questionid); 275 276 $DB->insert_record('quiz_slots', $data); 277 } 278 279 protected function process_quiz_feedback($data) { 280 global $DB; 281 282 $data = (object)$data; 283 $oldid = $data->id; 284 285 $data->quizid = $this->get_new_parentid('quiz'); 286 287 $newitemid = $DB->insert_record('quiz_feedback', $data); 288 $this->set_mapping('quiz_feedback', $oldid, $newitemid, true); // Has related files. 289 } 290 291 protected function process_quiz_override($data) { 292 global $DB; 293 294 $data = (object)$data; 295 $oldid = $data->id; 296 297 // Based on userinfo, we'll restore user overides or no. 298 $userinfo = $this->get_setting_value('userinfo'); 299 300 // Skip user overrides if we are not restoring userinfo. 301 if (!$userinfo && !is_null($data->userid)) { 302 return; 303 } 304 305 $data->quiz = $this->get_new_parentid('quiz'); 306 307 $data->userid = $this->get_mappingid('user', $data->userid); 308 $data->groupid = $this->get_mappingid('group', $data->groupid); 309 310 $data->timeopen = $this->apply_date_offset($data->timeopen); 311 $data->timeclose = $this->apply_date_offset($data->timeclose); 312 313 $newitemid = $DB->insert_record('quiz_overrides', $data); 314 315 // Add mapping, restore of logs needs it. 316 $this->set_mapping('quiz_override', $oldid, $newitemid); 317 } 318 319 protected function process_quiz_grade($data) { 320 global $DB; 321 322 $data = (object)$data; 323 $oldid = $data->id; 324 325 $data->quiz = $this->get_new_parentid('quiz'); 326 327 $data->userid = $this->get_mappingid('user', $data->userid); 328 $data->grade = $data->gradeval; 329 330 $data->timemodified = $this->apply_date_offset($data->timemodified); 331 332 $DB->insert_record('quiz_grades', $data); 333 } 334 335 protected function process_quiz_attempt($data) { 336 $data = (object)$data; 337 338 $data->quiz = $this->get_new_parentid('quiz'); 339 $data->attempt = $data->attemptnum; 340 341 $data->userid = $this->get_mappingid('user', $data->userid); 342 343 $data->timestart = $this->apply_date_offset($data->timestart); 344 $data->timefinish = $this->apply_date_offset($data->timefinish); 345 $data->timemodified = $this->apply_date_offset($data->timemodified); 346 if (!empty($data->timecheckstate)) { 347 $data->timecheckstate = $this->apply_date_offset($data->timecheckstate); 348 } else { 349 $data->timecheckstate = 0; 350 } 351 352 // Deals with up-grading pre-2.3 back-ups to 2.3+. 353 if (!isset($data->state)) { 354 if ($data->timefinish > 0) { 355 $data->state = 'finished'; 356 } else { 357 $data->state = 'inprogress'; 358 } 359 } 360 361 // The data is actually inserted into the database later in inform_new_usage_id. 362 $this->currentquizattempt = clone($data); 363 } 364 365 protected function process_quiz_attempt_legacy($data) { 366 global $DB; 367 368 $this->process_quiz_attempt($data); 369 370 $quiz = $DB->get_record('quiz', array('id' => $this->get_new_parentid('quiz'))); 371 $quiz->oldquestions = $this->oldquizlayout; 372 $this->process_legacy_quiz_attempt_data($data, $quiz); 373 } 374 375 protected function inform_new_usage_id($newusageid) { 376 global $DB; 377 378 $data = $this->currentquizattempt; 379 380 $oldid = $data->id; 381 $data->uniqueid = $newusageid; 382 383 $newitemid = $DB->insert_record('quiz_attempts', $data); 384 385 // Save quiz_attempt->id mapping, because logs use it. 386 $this->set_mapping('quiz_attempt', $oldid, $newitemid, false); 387 } 388 389 protected function after_execute() { 390 parent::after_execute(); 391 // Add quiz related files, no need to match by itemname (just internally handled context). 392 $this->add_related_files('mod_quiz', 'intro', null); 393 // Add feedback related files, matching by itemname = 'quiz_feedback'. 394 $this->add_related_files('mod_quiz', 'feedback', 'quiz_feedback'); 395 } 396 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |