Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   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   * Define all the backup steps that will be used by the backup_quiz_activity_task
  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 backup_quiz_activity_structure_step extends backup_questions_activity_structure_step {
  35  
  36      protected function define_structure() {
  37  
  38          // To know if we are including userinfo.
  39          $userinfo = $this->get_setting_value('userinfo');
  40  
  41          // Define each element separated.
  42          $quiz = new backup_nested_element('quiz', array('id'), array(
  43              'name', 'intro', 'introformat', 'timeopen', 'timeclose', 'timelimit',
  44              'overduehandling', 'graceperiod', 'preferredbehaviour', 'canredoquestions', 'attempts_number',
  45              'attemptonlast', 'grademethod', 'decimalpoints', 'questiondecimalpoints',
  46              'reviewattempt', 'reviewcorrectness', 'reviewmarks',
  47              'reviewspecificfeedback', 'reviewgeneralfeedback',
  48              'reviewrightanswer', 'reviewoverallfeedback',
  49              'questionsperpage', 'navmethod', 'shuffleanswers',
  50              'sumgrades', 'grade', 'timecreated',
  51              'timemodified', 'password', 'subnet', 'browsersecurity',
  52              'delay1', 'delay2', 'showuserpicture', 'showblocks', 'completionattemptsexhausted', 'completionpass',
  53              'allowofflineattempts'));
  54  
  55          // Define elements for access rule subplugin settings.
  56          $this->add_subplugin_structure('quizaccess', $quiz, true);
  57  
  58          $qinstances = new backup_nested_element('question_instances');
  59  
  60          $qinstance = new backup_nested_element('question_instance', array('id'), array(
  61              'slot', 'page', 'requireprevious', 'questionid', 'questioncategoryid', 'includingsubcategories', 'maxmark'));
  62  
  63          $qinstancetags = new backup_nested_element('tags');
  64          $qinstancetag = new backup_nested_element('tag', array('id'), array('tagid', 'tagname'));
  65  
  66          $sections = new backup_nested_element('sections');
  67  
  68          $section = new backup_nested_element('section', array('id'), array(
  69              'firstslot', 'heading', 'shufflequestions'));
  70  
  71          $feedbacks = new backup_nested_element('feedbacks');
  72  
  73          $feedback = new backup_nested_element('feedback', array('id'), array(
  74              'feedbacktext', 'feedbacktextformat', 'mingrade', 'maxgrade'));
  75  
  76          $overrides = new backup_nested_element('overrides');
  77  
  78          $override = new backup_nested_element('override', array('id'), array(
  79              'userid', 'groupid', 'timeopen', 'timeclose',
  80              'timelimit', 'attempts', 'password'));
  81  
  82          $grades = new backup_nested_element('grades');
  83  
  84          $grade = new backup_nested_element('grade', array('id'), array(
  85              'userid', 'gradeval', 'timemodified'));
  86  
  87          $attempts = new backup_nested_element('attempts');
  88  
  89          $attempt = new backup_nested_element('attempt', array('id'), array(
  90              'userid', 'attemptnum', 'uniqueid', 'layout', 'currentpage', 'preview',
  91              'state', 'timestart', 'timefinish', 'timemodified', 'timemodifiedoffline', 'timecheckstate', 'sumgrades'));
  92  
  93          // This module is using questions, so produce the related question states and sessions
  94          // attaching them to the $attempt element based in 'uniqueid' matching.
  95          $this->add_question_usages($attempt, 'uniqueid');
  96  
  97          // Define elements for access rule subplugin attempt data.
  98          $this->add_subplugin_structure('quizaccess', $attempt, true);
  99  
 100          // Build the tree.
 101          $quiz->add_child($qinstances);
 102          $qinstances->add_child($qinstance);
 103  
 104          $qinstance->add_child($qinstancetags);
 105          $qinstancetags->add_child($qinstancetag);
 106  
 107          $quiz->add_child($sections);
 108          $sections->add_child($section);
 109  
 110          $quiz->add_child($feedbacks);
 111          $feedbacks->add_child($feedback);
 112  
 113          $quiz->add_child($overrides);
 114          $overrides->add_child($override);
 115  
 116          $quiz->add_child($grades);
 117          $grades->add_child($grade);
 118  
 119          $quiz->add_child($attempts);
 120          $attempts->add_child($attempt);
 121  
 122          // Define sources.
 123          $quiz->set_source_table('quiz', array('id' => backup::VAR_ACTIVITYID));
 124  
 125          $qinstance->set_source_table('quiz_slots',
 126                  array('quizid' => backup::VAR_PARENTID));
 127  
 128          $qinstancetag->set_source_table('quiz_slot_tags',
 129                  array('slotid' => backup::VAR_PARENTID));
 130  
 131          $section->set_source_table('quiz_sections',
 132                  array('quizid' => backup::VAR_PARENTID));
 133  
 134          $feedback->set_source_table('quiz_feedback',
 135                  array('quizid' => backup::VAR_PARENTID));
 136  
 137          // Quiz overrides to backup are different depending of user info.
 138          $overrideparams = array('quiz' => backup::VAR_PARENTID);
 139          if (!$userinfo) { //  Without userinfo, skip user overrides.
 140              $overrideparams['userid'] = backup_helper::is_sqlparam(null);
 141  
 142          }
 143  
 144          // Skip group overrides if not including groups.
 145          $groupinfo = $this->get_setting_value('groups');
 146          if (!$groupinfo) {
 147              $overrideparams['groupid'] = backup_helper::is_sqlparam(null);
 148          }
 149  
 150          $override->set_source_table('quiz_overrides', $overrideparams);
 151  
 152          // All the rest of elements only happen if we are including user info.
 153          if ($userinfo) {
 154              $grade->set_source_table('quiz_grades', array('quiz' => backup::VAR_PARENTID));
 155              $attempt->set_source_sql('
 156                      SELECT *
 157                      FROM {quiz_attempts}
 158                      WHERE quiz = :quiz AND preview = 0',
 159                      array('quiz' => backup::VAR_PARENTID));
 160          }
 161  
 162          // Define source alias.
 163          $quiz->set_source_alias('attempts', 'attempts_number');
 164          $grade->set_source_alias('grade', 'gradeval');
 165          $attempt->set_source_alias('attempt', 'attemptnum');
 166  
 167          // Define id annotations.
 168          $qinstance->annotate_ids('question', 'questionid');
 169          $override->annotate_ids('user', 'userid');
 170          $override->annotate_ids('group', 'groupid');
 171          $grade->annotate_ids('user', 'userid');
 172          $attempt->annotate_ids('user', 'userid');
 173  
 174          // Define file annotations.
 175          $quiz->annotate_files('mod_quiz', 'intro', null); // This file area hasn't itemid.
 176          $feedback->annotate_files('mod_quiz', 'feedback', 'id');
 177  
 178          // Return the root element (quiz), wrapped into standard activity structure.
 179          return $this->prepare_activity_structure($quiz);
 180      }
 181  }