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 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]

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