Rev 1 | AutorÃa | Comparar con el anterior | Ultima modificación | Ver Log |
<?php// This file is part of Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>./*** restore user interface stages** This file contains the classes required to manage the stages that make up the* restore user interface.* These will be primarily operated a {@link restore_ui} instance.** @package core_backup* @copyright 2010 Sam Hemelryk* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*//*** Abstract stage class** This class should be extended by all restore stages (a requirement of many restore ui functions).* Each stage must then define two abstract methods* - process : To process the stage* - initialise_stage_form : To get a restore_moodleform instance for the stage** @package core_backup* @copyright 2010 Sam Hemelryk* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/abstract class restore_ui_stage extends base_ui_stage {/*** Constructor* @param restore_ui $ui* @param array $params*/public function __construct(restore_ui $ui, ?array $params = null) {$this->ui = $ui;$this->params = $params;}/*** The restore id from the restore controller* @return string*/final public function get_restoreid() {return $this->get_uniqueid();}/*** This is an independent stage* @return int*/final public function is_independent() {return false;}/*** No sub stages for this stage* @return false*/public function has_sub_stages() {return false;}/*** The name of this stage* @return string*/final public function get_name() {return get_string('restorestage'.$this->stage, 'backup');}/*** Returns true if this is the settings stage* @return bool*/final public function is_first_stage() {return $this->stage == restore_ui::STAGE_SETTINGS;}}/*** Abstract class used to represent a restore stage that is indenependent.** An independent stage is a judged to be so because it doesn't require, and has* no use for the restore controller.** @package core_backup* @copyright 2010 Sam Hemelryk* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/abstract class restore_ui_independent_stage {/*** @var \core\progress\base Optional progress reporter*/private $progressreporter;/*** Constructs the restore stage.* @param int $contextid*/abstract public function __construct($contextid);/*** Processes the current restore stage.* @return mixed*/abstract public function process();/*** Displays this restore stage.* @param core_backup_renderer $renderer* @return mixed*/abstract public function display(core_backup_renderer $renderer);/*** Returns the current restore stage.* @return int*/abstract public function get_stage();/*** Gets the progress reporter object in use for this restore UI stage.** IMPORTANT: This progress reporter is used only for UI progress that is* outside the restore controller. The restore controller has its own* progress reporter which is used for progress during the main restore.* Use the restore controller's progress reporter to report progress during* a restore operation, not this one.** This extra reporter is necessary because on some restore UI screens,* there are long-running tasks even though there is no restore controller* in use. There is a similar function in restore_ui. but that class is not* used on some stages.** @return \core\progress\none*/public function get_progress_reporter() {if (!$this->progressreporter) {$this->progressreporter = new \core\progress\none();}return $this->progressreporter;}/*** Sets the progress reporter that will be returned by get_progress_reporter.** @param \core\progress\base $progressreporter Progress reporter*/public function set_progress_reporter(\core\progress\base $progressreporter) {$this->progressreporter = $progressreporter;}/*** Gets an array of progress bar items that can be displayed through the restore renderer.* @return array Array of items for the progress bar*/public function get_progress_bar() {global $PAGE;$stage = restore_ui::STAGE_COMPLETE;$currentstage = $this->get_stage();$items = array();while ($stage > 0) {$classes = array('backup_stage');if (floor($stage / 2) == $currentstage) {$classes[] = 'backup_stage_next';} else if ($stage == $currentstage) {$classes[] = 'backup_stage_current';} else if ($stage < $currentstage) {$classes[] = 'backup_stage_complete';}$item = array('text' => strlen(decbin($stage)).'. '.get_string('restorestage'.$stage, 'backup'), 'class' => join(' ', $classes));if ($stage < $currentstage && $currentstage < restore_ui::STAGE_COMPLETE) {// By default you can't go back to independent stages, if that changes in the future uncomment the next line.// $item['link'] = new moodle_url($PAGE->url, array('restore' => $this->get_restoreid(), 'stage' => $stage));}array_unshift($items, $item);$stage = floor($stage / 2);}return $items;}/*** Returns the restore stage name.* @return string*/abstract public function get_stage_name();/*** Obviously true* @return true*/final public function is_independent() {return true;}/*** Handles the destruction of this object.*/public function destroy() {// Nothing to destroy here!.}}/*** The confirmation stage.** This is the first stage, it is independent.** @package core_backup* @copyright 2010 Sam Hemelryk* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class restore_ui_stage_confirm extends restore_ui_independent_stage implements file_progress {/*** The context ID.* @var int*/protected $contextid;/*** The file name.* @var string*/protected $filename = null;/*** The file path.* @var string*/protected $filepath = null;/*** @var string Content hash of archive file to restore (if specified by hash)*/protected $contenthash = null;/*** @var string Pathname hash of stored_file object to restore*/protected $pathnamehash = null;/*** @var array*/protected $details;/*** @var bool True if we have started reporting progress*/protected $startedprogress = false;/*** Constructor* @param int $contextid* @throws coding_exception*/public function __construct($contextid) {$this->contextid = $contextid;$this->filename = optional_param('filename', null, PARAM_FILE);if ($this->filename === null) {// Identify file object by its pathname hash.$this->pathnamehash = required_param('pathnamehash', PARAM_ALPHANUM);// The file content hash is also passed for security; users// cannot guess the content hash (unless they know the file contents),// so this guarantees that either the system generated this link or// else the user has access to the restore archive anyhow.$this->contenthash = required_param('contenthash', PARAM_ALPHANUM);}}/*** Processes this restore stage* @return bool* @throws restore_ui_exception*/public function process() {$backuptempdir = make_backup_temp_directory('');if ($this->filename) {$archivepath = $backuptempdir . '/' . $this->filename;if (!file_exists($archivepath)) {throw new restore_ui_exception('invalidrestorefile');}$outcome = $this->extract_file_to_dir($archivepath);if ($outcome) {fulldelete($archivepath);}} else {$fs = get_file_storage();$storedfile = $fs->get_file_by_hash($this->pathnamehash);if (!$storedfile || $storedfile->get_contenthash() !== $this->contenthash) {throw new restore_ui_exception('invalidrestorefile');}$outcome = $this->extract_file_to_dir($storedfile);}return $outcome;}/*** Extracts the file.** @param string|stored_file $source Archive file to extract* @return bool*/protected function extract_file_to_dir($source) {global $USER;$this->filepath = restore_controller::get_tempdir_name($this->contextid, $USER->id);$backuptempdir = make_backup_temp_directory('', false);$fb = get_file_packer('application/vnd.moodle.backup');$result = $fb->extract_to_pathname($source,$backuptempdir . '/' . $this->filepath . '/', null, $this);// If any progress happened, end it.if ($this->startedprogress) {$this->get_progress_reporter()->end_progress();}return $result;}/*** Implementation for file_progress interface to display unzip progress.** @param int $progress Current progress* @param int $max Max value*/public function progress($progress = file_progress::INDETERMINATE, $max = file_progress::INDETERMINATE) {$reporter = $this->get_progress_reporter();// Start tracking progress if necessary.if (!$this->startedprogress) {$reporter->start_progress('extract_file_to_dir',($max == file_progress::INDETERMINATE) ? \core\progress\base::INDETERMINATE : $max);$this->startedprogress = true;}// Pass progress through to whatever handles it.$reporter->progress(($progress == file_progress::INDETERMINATE) ? \core\progress\base::INDETERMINATE : $progress);}/*** Renders the confirmation stage screen** @param core_backup_renderer $renderer renderer instance to use* @return string HTML code*/public function display(core_backup_renderer $renderer) {$prevstageurl = new moodle_url('/backup/restorefile.php', array('contextid' => $this->contextid));$nextstageurl = new moodle_url('/backup/restore.php', array('contextid' => $this->contextid,'filepath' => $this->filepath,'stage' => restore_ui::STAGE_DESTINATION));$format = backup_general_helper::detect_backup_format($this->filepath);if ($format === backup::FORMAT_UNKNOWN) {// Unknown format - we can't do anything here.return $renderer->backup_details_unknown($prevstageurl);} else if ($format !== backup::FORMAT_MOODLE) {// Non-standard format to be converted.$details = array('format' => $format, 'type' => backup::TYPE_1COURSE); // todo type to be returned by a converterreturn $renderer->backup_details_nonstandard($nextstageurl, $details);} else {// Standard MBZ backup, let us get information from it and display.$this->details = backup_general_helper::get_backup_information($this->filepath);return $renderer->backup_details($this->details, $nextstageurl);}}/*** The restore stage name.* @return string* @throws coding_exception*/public function get_stage_name() {return get_string('restorestage'.restore_ui::STAGE_CONFIRM, 'backup');}/*** The restore stage this class is for.* @return int*/public function get_stage() {return restore_ui::STAGE_CONFIRM;}}/*** This is the destination stage.** This stage is the second stage and is also independent** @package core_backup* @copyright 2010 Sam Hemelryk* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class restore_ui_stage_destination extends restore_ui_independent_stage {/*** The context ID.* @var int*/protected $contextid;/*** The backup file path.* @var mixed|null*/protected $filepath = null;/*** The course ID.* @var null*/protected $courseid = null;/*** The restore target. One of backup::TARGET_NEW* @var int*/protected $target = backup::TARGET_NEW_COURSE;/*** The course search component.* @var null|restore_course_search*/protected $coursesearch = null;/*** The category search component.* @var null|restore_category_search*/protected $categorysearch = null;/*** Constructs the destination stage.* @param int $contextid* @throws coding_exception*/public function __construct($contextid) {global $PAGE;$this->contextid = $contextid;$this->filepath = required_param('filepath', PARAM_ALPHANUM);$url = new moodle_url($PAGE->url, array('filepath' => $this->filepath,'contextid' => $this->contextid,'stage' => restore_ui::STAGE_DESTINATION));// The context level can be course category, course or module. We need to make sure that we always use correct one.$context = context::instance_by_id($contextid);if ($context->contextlevel != CONTEXT_COURSE && $coursecontext = $context->get_course_context(false)) {$context = $coursecontext;}$this->coursesearch = new restore_course_search(array('url' => $url), $context->instanceid);$this->categorysearch = new restore_category_search(array('url' => $url));}/*** Processes the destination stage.* @return bool* @throws coding_exception* @throws restore_ui_exception*/public function process() {global $DB;$filepathdir = make_backup_temp_directory($this->filepath, false);if (!file_exists($filepathdir) || !is_dir($filepathdir)) {throw new restore_ui_exception('invalidrestorepath');}if (optional_param('searchcourses', false, PARAM_BOOL)) {return false;}$this->target = optional_param('target', backup::TARGET_NEW_COURSE, PARAM_INT);$targetid = optional_param('targetid', null, PARAM_INT);if (!is_null($this->target) && !is_null($targetid) && confirm_sesskey()) {if ($this->target == backup::TARGET_NEW_COURSE) {list($fullname, $shortname) = restore_dbops::calculate_course_names(0, get_string('restoringcourse', 'backup'), get_string('restoringcourseshortname', 'backup'));$this->courseid = restore_dbops::create_new_course($fullname, $shortname, $targetid);} else {$this->courseid = $targetid;}return ($DB->record_exists('course', array('id' => $this->courseid)));}return false;}/*** Renders the destination stage screen** @param core_backup_renderer $renderer renderer instance to use* @return string HTML code*/public function display(core_backup_renderer $renderer) {$format = backup_general_helper::detect_backup_format($this->filepath);if ($format === backup::FORMAT_MOODLE) {// Standard Moodle 2 format, let use get the type of the backup.$details = backup_general_helper::get_backup_information($this->filepath);if ($details->type === backup::TYPE_1COURSE) {$wholecourse = true;} else {$wholecourse = false;}} else {// Non-standard format to be converted. We assume it contains the// whole course for now. However, in the future there might be a callback// to the installed converters.$wholecourse = true;}$nextstageurl = new moodle_url('/backup/restore.php', array('contextid' => $this->contextid,'filepath' => $this->filepath,'stage' => restore_ui::STAGE_SETTINGS));$context = context::instance_by_id($this->contextid);if ($context->contextlevel == CONTEXT_COURSE and has_capability('moodle/restore:restorecourse', $context)) {$currentcourse = $context->instanceid;} else {$currentcourse = false;}return $renderer->course_selector($nextstageurl, $wholecourse, $this->categorysearch, $this->coursesearch, $currentcourse);}/*** Returns the stage name.* @return string* @throws coding_exception*/public function get_stage_name() {return get_string('restorestage'.restore_ui::STAGE_DESTINATION, 'backup');}/*** Returns the backup file path* @return mixed|null*/public function get_filepath() {return $this->filepath;}/*** Returns the course id.* @return null*/public function get_course_id() {return $this->courseid;}/*** Returns the current restore stage* @return int*/public function get_stage() {return restore_ui::STAGE_DESTINATION;}/*** Returns the target for this restore.* One of backup::TARGET_** @return int*/public function get_target() {return $this->target;}}/*** This stage is the settings stage.** This stage is the third stage, it is dependent on a restore controller and* is the first stage as such.** @package core_backup* @copyright 2010 Sam Hemelryk* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class restore_ui_stage_settings extends restore_ui_stage {/*** Initial restore stage constructor* @param restore_ui $ui* @param array $params*/public function __construct(restore_ui $ui, ?array $params = null) {$this->stage = restore_ui::STAGE_SETTINGS;parent::__construct($ui, $params);}/*** Process the settings stage.** @param base_moodleform $form* @return bool|int*/public function process(?base_moodleform $form = null) {$form = $this->initialise_stage_form();if ($form->is_cancelled()) {$this->ui->cancel_process();}$data = $form->get_data();if ($data && confirm_sesskey()) {$tasks = $this->ui->get_tasks();$changes = 0;foreach ($tasks as &$task) {// We are only interesting in the backup root task for this stage.if ($task instanceof restore_root_task || $task instanceof restore_course_task) {// Get all settings into a var so we can iterate by reference.$settings = $task->get_settings();foreach ($settings as &$setting) {$name = $setting->get_ui_name();if (isset($data->$name) && $data->$name != $setting->get_value()) {$setting->set_value($data->$name);$changes++;} else if (!isset($data->$name) && $setting->get_ui_type() == backup_setting::UI_HTML_CHECKBOX && $setting->get_value()) {$setting->set_value(0);$changes++;}}}}// Return the number of changes the user made.return $changes;} else {return false;}}/*** Initialise the stage form.** @return backup_moodleform|base_moodleform|restore_settings_form* @throws coding_exception*/protected function initialise_stage_form() {global $PAGE;if ($this->stageform === null) {$form = new restore_settings_form($this, $PAGE->url);// Store as a variable so we can iterate by reference.$tasks = $this->ui->get_tasks();$headingprinted = false;// Iterate all tasks by reference.foreach ($tasks as &$task) {// For the initial stage we are only interested in the root settings.if ($task instanceof restore_root_task) {if (!$headingprinted) {$form->add_heading('rootsettings', get_string('restorerootsettings', 'backup'));$headingprinted = true;}$settings = $task->get_settings();// First add all settings except the filename setting.foreach ($settings as &$setting) {if ($setting->get_name() == 'filename') {continue;}$form->add_setting($setting, $task);}// Then add all dependencies.foreach ($settings as &$setting) {if ($setting->get_name() == 'filename') {continue;}$form->add_dependencies($setting);}}}$this->stageform = $form;}// Return the form.return $this->stageform;}}/*** Schema stage of backup process** During the schema stage the user is required to set the settings that relate* to the area that they are backing up as well as its children.** @package core_backup* @copyright 2010 Sam Hemelryk* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class restore_ui_stage_schema extends restore_ui_stage {/*** @var int Maximum number of settings to add to form at once*/const MAX_SETTINGS_BATCH = 1000;/*** Schema stage constructor* @param restore_ui $ui* @param array $params*/public function __construct(restore_ui $ui, ?array $params = null) {$this->stage = restore_ui::STAGE_SCHEMA;parent::__construct($ui, $params);}/*** Processes the schema stage** @param base_moodleform $form* @return int The number of changes the user made*/public function process(?base_moodleform $form = null) {$form = $this->initialise_stage_form();// Check it wasn't cancelled.if ($form->is_cancelled()) {$this->ui->cancel_process();}// Check it has been submit.$data = $form->get_data();if ($data && confirm_sesskey()) {// Get the tasks into a var so we can iterate by reference.$tasks = $this->ui->get_tasks();$changes = 0;// Iterate all tasks by reference.foreach ($tasks as &$task) {// We are only interested in schema settings.if (!($task instanceof restore_root_task)) {// Store as a variable so we can iterate by reference.$settings = $task->get_settings();// Iterate by reference.foreach ($settings as &$setting) {$name = $setting->get_ui_name();if (isset($data->$name) && $data->$name != $setting->get_value()) {$setting->set_value($data->$name);$changes++;} else if (!isset($data->$name) && $setting->get_ui_type() == backup_setting::UI_HTML_CHECKBOX && $setting->get_value()) {$setting->set_value(0);$changes++;}}}}// Return the number of changes the user made.return $changes;} else {return false;}}/*** Creates the backup_schema_form instance for this stage** @return backup_schema_form*/protected function initialise_stage_form() {global $PAGE;if ($this->stageform === null) {$form = new restore_schema_form($this, $PAGE->url);$tasks = $this->ui->get_tasks();$courseheading = false;// Track progress through each stage.$progress = $this->ui->get_progress_reporter();$progress->start_progress('Initialise schema stage form', 3);$progress->start_progress('', count($tasks));$done = 1;$allsettings = array();foreach ($tasks as $task) {if (!($task instanceof restore_root_task)) {if (!$courseheading) {// If we haven't already display a course heading to group nicely.$form->add_heading('coursesettings', get_string('coursesettings', 'backup'));$courseheading = true;}// Put each setting into an array of settings to add. Adding// a setting individually is a very slow operation, so we add.// them all in a batch later on.foreach ($task->get_settings() as $setting) {$allsettings[] = array($setting, $task);}} else if ($this->ui->enforce_changed_dependencies()) {// Only show these settings if dependencies changed them.// Add a root settings heading to group nicely.$form->add_heading('rootsettings', get_string('rootsettings', 'backup'));// Iterate all settings and add them to the form as a fixed// setting. We only want schema settings to be editable.foreach ($task->get_settings() as $setting) {if ($setting->get_name() != 'filename') {$form->add_fixed_setting($setting, $task);}}}// Update progress.$progress->progress($done++);}$progress->end_progress();// Add settings for tasks in batches of up to 1000. Adding settings// in larger batches improves performance, but if it takes too long,// we won't be able to update the progress bar so the backup might.// time out. 1000 is chosen to balance this.$numsettings = count($allsettings);$progress->start_progress('', ceil($numsettings / self::MAX_SETTINGS_BATCH));$start = 0;$done = 1;while ($start < $numsettings) {$length = min(self::MAX_SETTINGS_BATCH, $numsettings - $start);$form->add_settings(array_slice($allsettings, $start, $length));$start += $length;$progress->progress($done++);}$progress->end_progress();// Add the dependencies for all the settings.$progress->start_progress('', count($allsettings));$done = 1;foreach ($allsettings as $settingtask) {$form->add_dependencies($settingtask[0]);$progress->progress($done++);}$progress->end_progress();$progress->end_progress();$this->stageform = $form;}return $this->stageform;}}/*** Confirmation stage** On this stage the user reviews the setting for the backup and can change the filename* of the file that will be generated.** @package core_backup* @copyright 2010 Sam Hemelryk* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class restore_ui_stage_review extends restore_ui_stage {/*** Constructs the stage* @param restore_ui $ui* @param array $params*/public function __construct($ui, ?array $params = null) {$this->stage = restore_ui::STAGE_REVIEW;parent::__construct($ui, $params);}/*** Processes the confirmation stage** @param base_moodleform $form* @return int The number of changes the user made*/public function process(?base_moodleform $form = null) {$form = $this->initialise_stage_form();// Check it hasn't been cancelled.if ($form->is_cancelled()) {$this->ui->cancel_process();}$data = $form->get_data();if ($data && confirm_sesskey()) {return 0;} else {return false;}}/*** Creates the backup_confirmation_form instance this stage requires** @return backup_confirmation_form*/protected function initialise_stage_form() {global $PAGE;if ($this->stageform === null) {// Get the form.$form = new restore_review_form($this, $PAGE->url);$content = '';$courseheading = false;$progress = $this->ui->get_progress_reporter();$tasks = $this->ui->get_tasks();$progress->start_progress('initialise_stage_form', count($tasks));$done = 1;foreach ($tasks as $task) {if ($task instanceof restore_root_task) {// If its a backup root add a root settings heading to group nicely.$form->add_heading('rootsettings', get_string('restorerootsettings', 'backup'));} else if (!$courseheading) {// We haven't already add a course heading.$form->add_heading('coursesettings', get_string('coursesettings', 'backup'));$courseheading = true;}// Iterate all settings, doesnt need to happen by reference.foreach ($task->get_settings() as $setting) {$form->add_fixed_setting($setting, $task);}// Update progress.$progress->progress($done++);}$progress->end_progress();$this->stageform = $form;}return $this->stageform;}}/*** Final stage of backup** This stage is special in that it is does not make use of a form. The reason for* this is the order of procession of backup at this stage.* The processesion is:* 1. The final stage will be intialise.* 2. The confirmation stage will be processed.* 3. The backup will be executed* 4. The complete stage will be loaded by execution* 5. The complete stage will be displayed** This highlights that we neither need a form nor a display method for this stage* we simply need to process.** @package core_backup* @copyright 2010 Sam Hemelryk* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class restore_ui_stage_process extends restore_ui_stage {/*** There is no substage required.*/const SUBSTAGE_NONE = 0;/*** The prechecks substage is required/the current substage.*/const SUBSTAGE_PRECHECKS = 2;/*** The current substage.* @var int*/protected $substage = 0;/*** Constructs the final stage* @param base_ui $ui* @param array $params*/public function __construct(base_ui $ui, ?array $params = null) {$this->stage = restore_ui::STAGE_PROCESS;parent::__construct($ui, $params);}/*** Processes the final stage.** In this case it checks to see if there is a sub stage that we need to display* before execution, if there is we gear up to display the subpage, otherwise* we return true which will lead to execution of the restore and the loading* of the completed stage.** @param base_moodleform $form*/public function process(?base_moodleform $form = null) {if (optional_param('cancel', false, PARAM_BOOL)) {redirect(new moodle_url('/course/view.php', array('id' => $this->get_ui()->get_controller()->get_courseid())));}// First decide whether a substage is needed.$rc = $this->ui->get_controller();if ($rc->get_status() == backup::STATUS_SETTING_UI) {$rc->finish_ui();}if ($rc->get_status() == backup::STATUS_NEED_PRECHECK) {if (!$rc->precheck_executed()) {$rc->execute_precheck(true);}$results = $rc->get_precheck_results();if (!empty($results)) {$this->substage = self::SUBSTAGE_PRECHECKS;}}$substage = optional_param('substage', null, PARAM_INT);if (empty($this->substage) && !empty($substage)) {$this->substage = $substage;// Now check whether that substage has already been submit.if ($this->substage == self::SUBSTAGE_PRECHECKS && optional_param('sesskey', null, PARAM_RAW) == sesskey()) {$info = $rc->get_info();if (!empty($info->role_mappings->mappings)) {foreach ($info->role_mappings->mappings as $key => &$mapping) {$mapping->targetroleid = optional_param('mapping'.$key, $mapping->targetroleid, PARAM_INT);}$info->role_mappings->modified = true;}// We've processed the substage now setting it back to none so we// can move to the next stage.$this->substage = self::SUBSTAGE_NONE;}}return empty($this->substage);}/*** should NEVER be called... throws an exception*/protected function initialise_stage_form() {throw new backup_ui_exception('backup_ui_must_execute_first');}/*** Renders the process stage screen** @throws restore_ui_exception* @param core_backup_renderer $renderer renderer instance to use* @return string HTML code*/public function display(core_backup_renderer $renderer) {global $PAGE;$html = '';$haserrors = false;$url = new moodle_url($PAGE->url, array('restore' => $this->get_uniqueid(),'stage' => restore_ui::STAGE_PROCESS,'substage' => $this->substage,'sesskey' => sesskey()));$html .= html_writer::start_tag('form', array('action' => $url->out_omit_querystring(),'class' => 'backup-restore','enctype' => 'application/x-www-form-urlencoded', // Enforce compatibility with our max_input_vars hack.'method' => 'post'));foreach ($url->params() as $name => $value) {$html .= html_writer::empty_tag('input', array('type' => 'hidden','name' => $name,'value' => $value));}switch ($this->substage) {case self::SUBSTAGE_PRECHECKS :$results = $this->ui->get_controller()->get_precheck_results();$info = $this->ui->get_controller()->get_info();$haserrors = (!empty($results['errors']));$html .= $renderer->precheck_notices($results);if (!empty($info->role_mappings->mappings)) {$context = context_course::instance($this->ui->get_controller()->get_courseid());$assignableroles = get_assignable_roles($context, ROLENAME_ALIAS, false);// Get current role mappings.$currentroles = role_fix_names(get_all_roles(), $context);// Get backup role mappings.$rolemappings = $info->role_mappings->mappings;array_map(function($rolemapping) use ($currentroles) {foreach ($currentroles as $role) {// Find matching archetype to determine the backup's shortname for label display.if ($rolemapping->archetype == $role->archetype) {$rolemapping->name = $rolemapping->shortname;break;}}if ($rolemapping->name == null) {$rolemapping->name = get_string('undefinedrolemapping', 'backup', $rolemapping->archetype);}}, $rolemappings);$html .= $renderer->role_mappings($rolemappings, $assignableroles);}break;default:throw new restore_ui_exception('backup_ui_must_execute_first');}$html .= $renderer->substage_buttons($haserrors);$html .= html_writer::end_tag('form');return $html;}/*** Returns true if this stage can have sub-stages.* @return bool|false*/public function has_sub_stages() {return true;}}/*** This is the completed stage.** Once this is displayed there is nothing more to do.** @package core_backup* @copyright 2010 Sam Hemelryk* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class restore_ui_stage_complete extends restore_ui_stage_process {/*** The results of the backup execution* @var array*/protected $results;/*** Constructs the complete backup stage* @param restore_ui $ui* @param array $params* @param array $results*/public function __construct(restore_ui $ui, ?array $params = null, ?array $results = null) {$this->results = $results;parent::__construct($ui, $params);$this->stage = restore_ui::STAGE_COMPLETE;}/*** Displays the completed backup stage.** Currently this just envolves redirecting to the file browser with an* appropriate message.** @param core_backup_renderer $renderer* @return string HTML code to echo*/public function display(core_backup_renderer $renderer) {$html = '';if (!empty($this->results['file_aliases_restore_failures'])) {$html .= $renderer->box_start('generalbox filealiasesfailures');$html .= $renderer->heading_with_help(get_string('filealiasesrestorefailures', 'core_backup'),'filealiasesrestorefailures', 'core_backup');$html .= $renderer->container(get_string('filealiasesrestorefailuresinfo', 'core_backup'));$html .= $renderer->container_start('aliaseslist');$html .= html_writer::start_tag('ul');foreach ($this->results['file_aliases_restore_failures'] as $alias) {$html .= html_writer::tag('li', s($alias));}$html .= html_writer::end_tag('ul');$html .= $renderer->container_end();$html .= $renderer->box_end();}$html .= $renderer->box_start();if (array_key_exists('file_missing_in_backup', $this->results)) {$html .= $renderer->notification(get_string('restorefileweremissing', 'backup'), 'notifyproblem');}$html .= $renderer->notification(get_string('restoreexecutionsuccess', 'backup'), 'notifysuccess');$courseurl = course_get_url($this->get_ui()->get_controller()->get_courseid());$html .= $renderer->continue_button($courseurl, 'get');$html .= $renderer->box_end();return $html;}}