[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/quiz/backup/moodle2/ -> restore_quiz_stepslib.php (source)

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


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1