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_controller; 20 use backup_root_task; 21 use cm_info; 22 use core\context\user; 23 use stdClass; 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 * Base packager to prepare appropriate backup of a resource to share to MoodleNet. 32 * 33 * @package core 34 * @copyright 2023 Safat Shahin <safat.shahin@moodle.com> 35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 */ 37 abstract class resource_packager { 38 39 /** 40 * @var string $resourcefilename The filename for the resource. 41 */ 42 protected string $resourcefilename = 'resource'; 43 44 /** 45 * @var stdClass $course The course which the resource belongs to. 46 */ 47 protected stdClass $course; 48 49 /** 50 * @var cm_info $cminfo The course module which the resource belongs to. 51 */ 52 protected cm_info $cminfo; 53 54 /** 55 * @var int $userid The ID of the user performing the packaging. 56 */ 57 protected int $userid; 58 59 /** 60 * Constructor for the base packager. 61 * 62 * @param stdClass|cm_info $resource The resource object 63 * @param int $userid The user id 64 */ 65 public function __construct( 66 stdClass|cm_info $resource, 67 int $userid, 68 string $resourcefilename, 69 ) { 70 if ($resource instanceof cm_info) { 71 $this->cminfo = $resource; 72 $this->course = $resource->get_course(); 73 } else { 74 $this->course = $resource; 75 } 76 77 $this->userid = $userid; 78 $this->resourcefilename = $resourcefilename; 79 } 80 81 /** 82 * Get the backup controller for the course. 83 * 84 * @return backup_controller The backup controller instance that will be used to package the resource. 85 */ 86 abstract protected function get_backup_controller(): backup_controller; 87 88 /** 89 * Prepare the backup file using appropriate setting overrides and return relevant information. 90 * 91 * @return stored_file 92 */ 93 public function get_package(): stored_file { 94 $controller = $this->get_backup_controller(); 95 $alltasksettings = $this->get_all_task_settings($controller); 96 97 // Override relevant settings to remove user data when packaging to share to MoodleNet. 98 $this->override_task_setting($alltasksettings, 'setting_root_users', 0); 99 $this->override_task_setting($alltasksettings, 'setting_root_role_assignments', 0); 100 $this->override_task_setting($alltasksettings, 'setting_root_blocks', 0); 101 $this->override_task_setting($alltasksettings, 'setting_root_comments', 0); 102 $this->override_task_setting($alltasksettings, 'setting_root_badges', 0); 103 $this->override_task_setting($alltasksettings, 'setting_root_userscompletion', 0); 104 $this->override_task_setting($alltasksettings, 'setting_root_logs', 0); 105 $this->override_task_setting($alltasksettings, 'setting_root_grade_histories', 0); 106 $this->override_task_setting($alltasksettings, 'setting_root_groups', 0); 107 108 $storedfile = $this->package($controller); 109 110 $controller->destroy(); // We are done with the controller, destroy it. 111 112 return $storedfile; 113 } 114 115 /** 116 * Get all backup settings available for override. 117 * 118 * @return array the associative array of taskclass => settings instances. 119 */ 120 protected function get_all_task_settings(backup_controller $controller): array { 121 $tasksettings = []; 122 foreach ($controller->get_plan()->get_tasks() as $task) { 123 $taskclass = get_class($task); 124 $tasksettings[$taskclass] = $task->get_settings(); 125 } 126 return $tasksettings; 127 } 128 129 /** 130 * Override a backup task setting with a given value. 131 * 132 * @param array $alltasksettings All task settings. 133 * @param string $settingname The name of the setting to be overridden (task class name format). 134 * @param int $settingvalue Value to be given to the setting. 135 */ 136 protected function override_task_setting(array $alltasksettings, string $settingname, int $settingvalue): void { 137 if (empty($rootsettings = $alltasksettings[backup_root_task::class])) { 138 return; 139 } 140 141 foreach ($rootsettings as $setting) { 142 $name = $setting->get_ui_name(); 143 if ($name == $settingname && $settingvalue != $setting->get_value()) { 144 $setting->set_value($settingvalue); 145 return; 146 } 147 } 148 } 149 150 /** 151 * Package the resource identified by resource id into a new stored_file. 152 * 153 * @param backup_controller $controller The backup controller. 154 * @return stored_file 155 */ 156 protected function package(backup_controller $controller): stored_file { 157 // Execute the backup and fetch the result. 158 $controller->execute_plan(); 159 $result = $controller->get_results(); 160 161 if (!isset($result['backup_destination'])) { 162 throw new \moodle_exception('Failed to package resource.'); 163 } 164 165 $backupfile = $result['backup_destination']; 166 167 if (!$backupfile->get_contenthash()) { 168 throw new \moodle_exception('Failed to package resource (invalid file).'); 169 } 170 171 // Create the location we want to copy this file to. 172 $filerecord = [ 173 'contextid' => user::instance($this->userid)->id, 174 'userid' => $this->userid, 175 'component' => 'user', 176 'filearea' => 'draft', 177 'itemid' => file_get_unused_draft_itemid(), 178 'filepath' => '/', 179 'filename' => $this->resourcefilename . '_backup.mbz', 180 ]; 181 182 // Create the local file based on the backup. 183 $fs = get_file_storage(); 184 $file = $fs->create_file_from_storedfile($filerecord, $backupfile); 185 186 // Delete the backup now it has been created in the file area. 187 $backupfile->delete(); 188 189 return $file; 190 } 191 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body