Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.

Differences Between: [Versions 402 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  namespace core\moodlenet;
  18  
  19  use backup;
  20  use backup_controller;
  21  use backup_root_task;
  22  use cm_info;
  23  use core\context\user;
  24  use stored_file;
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
  29  
  30  /**
  31   * Packager to prepare appropriate backup of an activity to share to MoodleNet.
  32   *
  33   * @package   core
  34   * @copyright 2023 Raquel Ortega <raquel.ortega@moodle.com>
  35   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class activity_packager {
  38  
  39      /** @var backup_controller $controller */
  40      protected $controller;
  41  
  42      /**
  43       * Constructor.
  44       *
  45       * @param cm_info $cminfo context module information about the resource being packaged.
  46       * @param int $userid The ID of the user performing the packaging.
  47       */
  48      public function __construct(
  49          protected cm_info $cminfo,
  50          protected int $userid,
  51      ) {
  52          // Check backup/restore support.
  53          if (!plugin_supports('mod', $cminfo->modname , FEATURE_BACKUP_MOODLE2)) {
  54              throw new \coding_exception("Cannot backup module $cminfo->modname. This module doesn't support the backup feature.");
  55          }
  56  
  57          $this->controller = new backup_controller(
  58              backup::TYPE_1ACTIVITY,
  59              $cminfo->id,
  60              backup::FORMAT_MOODLE,
  61              backup::INTERACTIVE_NO,
  62              backup::MODE_GENERAL,
  63              $userid
  64          );
  65      }
  66  
  67      /**
  68       * Destructor
  69       */
  70      public function __destruct() {
  71          $this->controller->destroy();
  72      }
  73  
  74      /**
  75       * Prepare the backup file using appropriate setting overrides and return relevant information.
  76       *
  77       * @return stored_file
  78       */
  79      public function get_package(): stored_file {
  80          $alltasksettings = $this->get_all_task_settings();
  81  
  82          // Override relevant settings to remove user data when packaging to share to MoodleNet.
  83          $this->override_task_setting($alltasksettings, 'setting_root_users', 0);
  84          $this->override_task_setting($alltasksettings, 'setting_root_role_assignments', 0);
  85          $this->override_task_setting($alltasksettings, 'setting_root_blocks', 0);
  86          $this->override_task_setting($alltasksettings, 'setting_root_comments', 0);
  87          $this->override_task_setting($alltasksettings, 'setting_root_badges', 0);
  88          $this->override_task_setting($alltasksettings, 'setting_root_userscompletion', 0);
  89          $this->override_task_setting($alltasksettings, 'setting_root_logs', 0);
  90          $this->override_task_setting($alltasksettings, 'setting_root_grade_histories', 0);
  91          $this->override_task_setting($alltasksettings, 'setting_root_groups', 0);
  92  
  93          return $this->package();
  94      }
  95  
  96      /**
  97       * Get all backup settings available for override.
  98       *
  99       * @return array the associative array of taskclass => settings instances.
 100       */
 101      protected function get_all_task_settings(): array {
 102          $tasksettings = [];
 103          foreach ($this->controller->get_plan()->get_tasks() as $task) {
 104              $taskclass = get_class($task);
 105              $tasksettings[$taskclass] = $task->get_settings();
 106          }
 107          return $tasksettings;
 108      }
 109  
 110      /**
 111       * Override a backup task setting with a given value.
 112       *
 113       * @param array $alltasksettings All task settings.
 114       * @param string $settingname The name of the setting to be overridden (task class name format).
 115       * @param int $settingvalue Value to be given to the setting.
 116       */
 117      protected function override_task_setting(array $alltasksettings, string $settingname, int $settingvalue): void {
 118          if (empty($rootsettings = $alltasksettings[backup_root_task::class])) {
 119              return;
 120          }
 121  
 122          foreach ($rootsettings as $setting) {
 123              $name = $setting->get_ui_name();
 124              if ($name == $settingname && $settingvalue != $setting->get_value()) {
 125                  $setting->set_value($settingvalue);
 126                  return;
 127              }
 128          }
 129      }
 130  
 131      /**
 132       * Package the activity identified by CMID into a new stored_file.
 133       *
 134       * @return stored_file
 135       * @throws \moodle_exception
 136       */
 137      protected function package(): stored_file {
 138          // Execute the backup and fetch the result.
 139          $this->controller->execute_plan();
 140          $result = $this->controller->get_results();
 141  
 142          if (!isset($result['backup_destination'])) {
 143              throw new \moodle_exception('Failed to package activity.');
 144          }
 145  
 146          $backupfile = $result['backup_destination'];
 147  
 148          if (!$backupfile->get_contenthash()) {
 149              throw new \moodle_exception('Failed to package activity (invalid file).');
 150          }
 151  
 152          // Create the location we want to copy this file to.
 153          $filerecord = [
 154              'contextid' => user::instance($this->userid)->id,
 155              'userid' => $this->userid,
 156              'component' => 'user',
 157              'filearea' => 'draft',
 158              'itemid' => file_get_unused_draft_itemid(),
 159              'filepath' => '/',
 160              'filename' => $this->cminfo->modname . '_backup.mbz',
 161          ];
 162  
 163          // Create the local file based on the backup.
 164          $fs = get_file_storage();
 165          $file = $fs->create_file_from_storedfile($filerecord, $backupfile);
 166  
 167          // Delete the backup now it has been created in the file area.
 168          $backupfile->delete();
 169  
 170          return $file;
 171      }
 172  }