Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   1  <?php
   2  
   3  // This file is part of Moodle - http://moodle.org/
   4  //
   5  // Moodle is free software: you can redistribute it and/or modify
   6  // it under the terms of the GNU General Public License as published by
   7  // the Free Software Foundation, either version 3 of the License, or
   8  // (at your option) any later version.
   9  //
  10  // Moodle is distributed in the hope that it will be useful,
  11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  // GNU General Public License for more details.
  14  //
  15  // You should have received a copy of the GNU General Public License
  16  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  17  
  18  /**
  19   * Defines backup_final_task class
  20   *
  21   * @package     core_backup
  22   * @subpackage  moodle2
  23   * @category    backup
  24   * @copyright   2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
  25   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  26   */
  27  
  28  defined('MOODLE_INTERNAL') || die();
  29  
  30  /**
  31   * Final task that provides all the final steps necessary in order to finish one
  32   * backup (mainly gathering references and creating the main xml) apart from
  33   * some final cleaning
  34   *
  35   * TODO: Finish phpdocs
  36   */
  37  class backup_final_task extends backup_task {
  38  
  39      /**
  40       * Create all the steps that will be part of this task
  41       */
  42      public function build() {
  43          global $CFG;
  44  
  45          // Set the backup::VAR_CONTEXTID setting to course context as far as next steps require that
  46          $coursectxid = context_course::instance($this->get_courseid())->id;
  47          $this->add_setting(new backup_activity_generic_setting(backup::VAR_CONTEXTID, base_setting::IS_INTEGER, $coursectxid));
  48  
  49          // Set the backup::VAR_COURSEID setting to course, we'll need that in some steps
  50          $courseid = $this->get_courseid();
  51          $this->add_setting(new backup_activity_generic_setting(backup::VAR_COURSEID, base_setting::IS_INTEGER, $courseid));
  52  
  53          // Generate the groups file with the final annotated groups and groupings
  54          // including membership based on setting
  55          $this->add_step(new backup_groups_structure_step('groups', 'groups.xml'));
  56  
  57          // Generate the questions file with the final annotated question_categories
  58          $this->add_step(new backup_questions_structure_step('questions', 'questions.xml'));
  59  
  60          // Annotate all the question files for the already annotated question
  61          // categories (this is performed here and not in the structure step because
  62          // it involves multiple contexts and as far as we are always backup-ing
  63          // complete question banks we don't need to restrict at all and can be
  64          // done in a single pass
  65          $this->add_step(new backup_annotate_all_question_files('question_files'));
  66  
  67          // Annotate all the user files (conditionally) (profile and icon files)
  68          // Because each user has its own context, we need a separate/specialised step here
  69          // This step also ensures that the contexts for all the users exist, so next
  70          // step can be safely executed (join between users and contexts)
  71          // Not executed if backup is without users of anonymized
  72          if (($this->get_setting_value('users') || !empty($this->get_kept_roles())) && !$this->get_setting_value('anonymize')) {
  73              $this->add_step(new backup_annotate_all_user_files('user_files'));
  74          }
  75  
  76          // Generate the users file (conditionally) with the final annotated users
  77          // including custom profile fields, preferences, tags, role assignments and
  78          // overrides
  79          if ($this->get_setting_value('users') || !empty($this->get_kept_roles())) {
  80              $this->add_step(new backup_users_structure_step('users', 'users.xml'));
  81          }
  82  
  83          // Generate the top roles file with all the final annotated roles
  84          // that have been detected along the whole process. It's just
  85          // the list of role definitions (no assignments nor permissions)
  86          $this->add_step(new backup_final_roles_structure_step('roleslist', 'roles.xml'));
  87  
  88          // Generate the gradebook file with categories and course grade items. Do it conditionally, using
  89          // execute_condition() so only will be excuted if ALL module grade_items in course have been exported
  90          $this->add_step(new backup_gradebook_structure_step('course_gradebook','gradebook.xml'));
  91  
  92          // Generate the grade history file, conditionally.
  93          $this->add_step(new backup_grade_history_structure_step('course_grade_history','grade_history.xml'));
  94  
  95          // Generate the course completion
  96          $this->add_step(new backup_course_completion_structure_step('course_completion', 'completion.xml'));
  97  
  98          // Conditionally generate the badges file.
  99          if ($this->get_setting_value('badges')) {
 100              $this->add_step(new backup_badges_structure_step('course_badges', 'badges.xml'));
 101          }
 102  
 103          // Generate the scales file with all the (final) annotated scales
 104          $this->add_step(new backup_final_scales_structure_step('scaleslist', 'scales.xml'));
 105  
 106          // Generate the outcomes file with all the (final) annotated outcomes
 107          $this->add_step(new backup_final_outcomes_structure_step('outcomeslist', 'outcomes.xml'));
 108  
 109          // Migrate the pending annotations to final (prev steps may have added some files)
 110          // This must be executed before backup files
 111          $this->add_step(new move_inforef_annotations_to_final('migrate_inforef'));
 112  
 113          // Generate the files.xml file with all the (final) annotated files. At the same
 114          // time copy all the files from moodle storage to backup storage (uses custom
 115          // backup_nested_element for that)
 116          $this->add_step(new backup_final_files_structure_step('fileslist', 'files.xml'));
 117  
 118          // Write the main moodle_backup.xml file, with all the information related
 119          // to the backup, settings, license, versions and other useful information
 120          $this->add_step(new backup_main_structure_step('mainfile', 'moodle_backup.xml'));
 121  
 122          require_once($CFG->dirroot . '/backup/util/helper/convert_helper.class.php');
 123  
 124          // Look for converter steps only in type course and mode general backup operations.
 125          $conversion = false;
 126          if ($this->plan->get_type() == backup::TYPE_1COURSE and $this->plan->get_mode() == backup::MODE_GENERAL) {
 127              $converters = convert_helper::available_converters(false);
 128              foreach ($converters as $value) {
 129                  if ($this->get_setting_value($value)) {
 130                      // Zip class.
 131                      $zip_contents      = "{$value}_zip_contents";
 132                      $store_backup_file = "{$value}_store_backup_file";
 133                      $convert           = "{$value}_backup_convert";
 134  
 135                      $this->add_step(new $convert("package_convert_{$value}"));
 136                      $this->add_step(new $zip_contents("zip_contents_{$value}"));
 137                      $this->add_step(new $store_backup_file("save_backupfile_{$value}"));
 138                      if (!$conversion) {
 139                          $conversion = true;
 140                      }
 141                  }
 142              }
 143          }
 144  
 145          // On backup::MODE_IMPORT, we don't have to zip nor store the the file, skip these steps
 146          if (($this->plan->get_mode() != backup::MODE_IMPORT) && !$conversion) {
 147              // Generate the zip file (mbz extension)
 148              $this->add_step(new backup_zip_contents('zip_contents'));
 149  
 150              // Copy the generated zip (.mbz) file to final destination
 151              $this->add_step(new backup_store_backup_file('save_backupfile'));
 152          }
 153  
 154          // Clean the temp dir (conditionally) and drop temp tables
 155          $cleanstep = new drop_and_clean_temp_stuff('drop_and_clean_temp_stuff');
 156          // Decide about to delete the temp dir (based on backup::MODE_IMPORT)
 157          $cleanstep->skip_cleaning_temp_dir($this->plan->get_mode() == backup::MODE_IMPORT);
 158          $this->add_step($cleanstep);
 159  
 160          $this->built = true;
 161      }
 162  
 163      public function get_weight() {
 164          // The final task takes ages, so give it 20 times the weight of a normal task.
 165          return 20;
 166      }
 167  
 168  // Protected API starts here
 169  
 170      /**
 171       * Define the common setting that any backup type will have
 172       */
 173      protected function define_settings() {
 174          // This task has not settings (could have them, like destination or so in the future, let's see)
 175      }
 176  }