Merge branch 'MDL-62487' of https://github.com/timhunt/moodle
[moodle.git] / backup / externallib.php
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/>.
18 /**
19  * External backup API.
20  *
21  * @package    core_backup
22  * @category   external
23  * @copyright  2018 Matt Porritt <mattp@catalyst-au.net>
24  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25  */
27 defined('MOODLE_INTERNAL') || die;
29 require_once("$CFG->libdir/externallib.php");
30 require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
31 require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
33 /**
34  * Backup external functions.
35  *
36  * @package    core_backup
37  * @category   external
38  * @copyright  2018 Matt Porritt <mattp@catalyst-au.net>
39  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40  * @since Moodle 3.7
41  */
42 class core_backup_external extends external_api {
44     /**
45      * Returns description of method parameters
46      *
47      * @return external_function_parameters
48      * @since Moodle 3.7
49      */
50     public static function get_async_backup_progress_parameters() {
51         return new external_function_parameters(
52             array(
53                 'backupids' => new external_multiple_structure(
54                         new external_value(PARAM_ALPHANUM, 'Backup id to get progress for', VALUE_REQUIRED, null, NULL_ALLOWED),
55                         'Backup id to get progress for', VALUE_REQUIRED
56                  ),
57                 'contextid' => new external_value(PARAM_INT, 'Context id', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
58             )
59         );
60     }
62     /**
63      * Get asynchronous backup progress.
64      *
65      * @param string $backupids The ids of the backup to get progress for.
66      * @param int $contextid The context the backup relates to.
67      * @return array $results The array of results.
68      * @since Moodle 3.7
69      */
70     public static function get_async_backup_progress($backupids, $contextid) {
71         // Release session lock.
72         \core\session\manager::write_close();
74         // Parameter validation.
75         self::validate_parameters(
76                 self::get_async_backup_progress_parameters(),
77                 array(
78                     'backupids' => $backupids,
79                     'contextid' => $contextid
80                 )
81         );
83         // Context validation.
84         list($context, $course, $cm) = get_context_info_array($contextid);
85         self::validate_context($context);
87         if ($cm) {
88             require_capability('moodle/backup:backupactivity', $context);
89         } else {
90             require_capability('moodle/backup:backupcourse', $context);
91         }
93         $results = array();
94         foreach ($backupids as $backupid) {
95             $results[] = backup_controller_dbops::get_progress($backupid);
96         }
98         return $results;
99     }
101     /**
102      * Returns description of method result value
103      *
104      * @return external_description
105      * @since Moodle 3.7
106      */
107     public static function get_async_backup_progress_returns() {
108         return new external_multiple_structure(
109             new external_single_structure(
110                 array(
111                     'status'   => new external_value(PARAM_INT, 'Backup Status'),
112                     'progress' => new external_value(PARAM_FLOAT, 'Backup progress'),
113                     'backupid' => new external_value(PARAM_ALPHANUM, 'Backup id'),
114                     'operation' => new external_value(PARAM_ALPHANUM, 'operation type'),
115                 ), 'Backup completion status'
116           ), 'Backup data'
117         );
118     }
120     /**
121      * Returns description of method parameters
122      *
123      * @return external_function_parameters
124      * @since Moodle 3.7
125      */
126     public static function get_async_backup_links_backup_parameters() {
127         return new external_function_parameters(
128                 array(
129                     'filename' => new external_value(PARAM_FILE, 'Backup filename', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
130                     'contextid' => new external_value(PARAM_INT, 'Context id', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
131                 )
132          );
133     }
135     /**
136      * Get the data to be used when generating the table row for an asynchronous backup,
137      * the table row updates via ajax when backup is complete.
138      *
139      * @param string $filename The file name of the backup file.
140      * @param int $contextid The context the backup relates to.
141      * @since Moodle 3.7
142      */
143     public static function get_async_backup_links_backup($filename, $contextid) {
144         // Release session lock.
145         \core\session\manager::write_close();
147         // Parameter validation.
148         self::validate_parameters(
149                 self::get_async_backup_links_backup_parameters(),
150                     array(
151                         'filename' => $filename,
152                         'contextid' => $contextid
153                     )
154                 );
156         // Context validation.
157         list($context, $course, $cm) = get_context_info_array($contextid);
158         self::validate_context($context);
159         require_capability('moodle/backup:backupcourse', $context);
161         if ($cm) {
162             $filearea = 'activity';
163         } else {
164             $filearea = 'course';
165         }
167         $results = \async_helper::get_backup_file_info($filename, $filearea, $contextid);
169         return $results;
170     }
172     /**
173      * Returns description of method result value.
174      *
175      * @return external_description
176      * @since Moodle 3.7
177      */
178     public static function get_async_backup_links_backup_returns() {
179         return new external_single_structure(
180             array(
181                'filesize'   => new external_value(PARAM_TEXT, 'Backup file size'),
182                'fileurl' => new external_value(PARAM_URL, 'Backup file URL'),
183                'restoreurl' => new external_value(PARAM_URL, 'Backup restore URL'),
184         ), 'Table row data.');
185     }
186     /**
187      * Returns description of method parameters
188      *
189      * @return external_function_parameters
190      * @since Moodle 3.7
191      */
192     public static function get_async_backup_links_restore_parameters() {
193         return new external_function_parameters(
194                 array(
195                     'backupid' => new external_value(PARAM_ALPHANUMEXT, 'Backup id', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
196                     'contextid' => new external_value(PARAM_INT, 'Context id', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
197                 )
198         );
199     }
201     /**
202      * Get the data to be used when generating the table row for an asynchronous restore,
203      * the table row updates via ajax when restore is complete.
204      *
205      * @param string $backupid The id of the backup record.
206      * @param int $contextid The context the restore relates to.
207      * @return array $results The array of results.
208      * @since Moodle 3.7
209      */
210     public static function get_async_backup_links_restore($backupid, $contextid) {
211         // Release session lock.
212         \core\session\manager::write_close();
214         // Parameter validation.
215         self::validate_parameters(
216                 self::get_async_backup_links_restore_parameters(),
217                     array(
218                         'backupid' => $backupid,
219                         'contextid' => $contextid
220                     )
221                 );
223         // Context validation.
224         if ($contextid == 0) {
225             $copyrec = \async_helper::get_backup_record($backupid);
226             $context = context_course::instance($copyrec->itemid);
227         } else {
228             $context = context::instance_by_id($contextid);
229         }
230         self::validate_context($context);
231         require_capability('moodle/restore:restorecourse', $context);
233         $results = \async_helper::get_restore_url($backupid);
235         return $results;
236     }
238     /**
239      * Returns description of method result value.
240      *
241      * @return external_description
242      * @since Moodle 3.7
243      */
244     public static function get_async_backup_links_restore_returns() {
245         return new external_single_structure(
246                 array(
247                     'restoreurl' => new external_value(PARAM_URL, 'Restore url'),
248                 ), 'Table row data.');
249     }
251     /**
252      * Returns description of method parameters
253      *
254      * @return external_function_parameters
255      * @since Moodle 3.9
256      */
257     public static function get_copy_progress_parameters() {
258         return new external_function_parameters(
259             array(
260                 'copies' => new external_multiple_structure(
261                     new external_single_structure(
262                         array(
263                             'backupid' => new external_value(PARAM_ALPHANUM, 'Backup id'),
264                             'restoreid' => new external_value(PARAM_ALPHANUM, 'Restore id'),
265                             'operation' => new external_value(PARAM_ALPHANUM, 'Operation type'),
266                         ), 'Copy data'
267                     ), 'Copy data'
268                 ),
269             )
270         );
271     }
273     /**
274      * Get the data to be used when generating the table row for a course copy,
275      * the table row updates via ajax when copy is complete.
276      *
277      * @param array $copies Array of ids.
278      * @return array $results The array of results.
279      * @since Moodle 3.9
280      */
281     public static function get_copy_progress($copies) {
282         // Release session lock.
283         \core\session\manager::write_close();
285         // Parameter validation.
286         self::validate_parameters(
287             self::get_copy_progress_parameters(),
288             array('copies' => $copies)
289             );
291         $results = array();
293         foreach ($copies as $copy) {
295             if ($copy['operation'] == \backup::OPERATION_BACKUP) {
296                 $copyid = $copy['backupid'];
297             } else {
298                 $copyid = $copy['restoreid'];
299             }
301             $copyrec = \async_helper::get_backup_record($copyid);
302             $context = context_course::instance($copyrec->itemid);
303             self::validate_context($context);
305             $copycaps = \core_course\management\helper::get_course_copy_capabilities();
306             require_all_capabilities($copycaps, $context);
308             if ($copy['operation'] == \backup::OPERATION_BACKUP) {
309                 $result = \backup_controller_dbops::get_progress($copyid);
310                 if ($result['status'] == \backup::STATUS_FINISHED_OK) {
311                     $copyid = $copy['restoreid'];
312                 }
313             }
315             $results[] = \backup_controller_dbops::get_progress($copyid);
316         }
318         return $results;
319     }
321     /**
322      * Returns description of method result value.
323      *
324      * @return external_description
325      * @since Moodle 3.9
326      */
327     public static function get_copy_progress_returns() {
328         return new external_multiple_structure(
329             new external_single_structure(
330                 array(
331                     'status'   => new external_value(PARAM_INT, 'Copy Status'),
332                     'progress' => new external_value(PARAM_FLOAT, 'Copy progress'),
333                     'backupid' => new external_value(PARAM_ALPHANUM, 'Copy id'),
334                     'operation' => new external_value(PARAM_ALPHANUM, 'Operation type'),
335                 ), 'Copy completion status'
336             ), 'Copy data'
337         );
338     }
340     /**
341      * Returns description of method parameters
342      *
343      * @return external_function_parameters
344      * @since Moodle 3.9
345      */
346     public static function submit_copy_form_parameters() {
347         return new external_function_parameters(
348             array(
349                 'jsonformdata' => new external_value(PARAM_RAW, 'The data from the create copy form, encoded as a json array')
350             )
351         );
352     }
354     /**
355      * Submit the course group form.
356      *
357      * @param string $jsonformdata The data from the form, encoded as a json array.
358      * @return int new group id.
359      */
360     public static function submit_copy_form($jsonformdata) {
362         // Release session lock.
363         \core\session\manager::write_close();
365         // We always must pass webservice params through validate_parameters.
366         $params = self::validate_parameters(
367             self::submit_copy_form_parameters(),
368             array('jsonformdata' => $jsonformdata)
369             );
371         $formdata = json_decode($params['jsonformdata']);
373         $data = array();
374         parse_str($formdata, $data);
376         $context = context_course::instance($data['courseid']);
377         self::validate_context($context);
378         $copycaps = \core_course\management\helper::get_course_copy_capabilities();
379         require_all_capabilities($copycaps, $context);
381         // Submit the form data.
382         $course = get_course($data['courseid']);
383         $mform = new \core_backup\output\copy_form(
384             null,
385             array('course' => $course, 'returnto' => '', 'returnurl' => ''),
386             'post', '', ['class' => 'ignoredirty'], true, $data);
387         $mdata = $mform->get_data();
389         if ($mdata) {
390             // Create the copy task.
391             $backupcopy = new \core_backup\copy\copy($mdata);
392             $copyids = $backupcopy->create_copy();
393         } else {
394             throw new moodle_exception('copyformfail', 'backup');
395         }
397         return json_encode($copyids);
398     }
400     /**
401      * Returns description of method result value.
402      *
403      * @return external_description
404      * @since Moodle 3.9
405      */
406     public static function submit_copy_form_returns() {
407         return new external_value(PARAM_RAW, 'JSON response.');
408     }