Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
}