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/>./*** Backup user interface stages** This file contains the classes required to manage the stages that make up the* backup user interface.* These will be primarily operated a {@link backup_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 backup stages (a requirement of many backup ui functions).* Each stage must then define two abstract methods* - process : To process the stage* - initialise_stage_form : To get a backup_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 backup_ui_stage extends base_ui_stage {/*** Constructor.** @param backup_ui $ui* @param array $params*/public function __construct(backup_ui $ui, ?array $params = null) {parent::__construct($ui, $params);}/*** The backup id from the backup controller* @return string*/final public function get_backupid() {return $this->get_uniqueid();}}/*** Class representing the initial stage of a backup.** In this stage the user is required to set the root level settings.** @package core_backup* @copyright 2010 Sam Hemelryk* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class backup_ui_stage_initial extends backup_ui_stage {/*** When set to true we skip all stages and jump to immediately processing the backup.* @var bool*/protected $oneclickbackup = false;/*** Initial backup stage constructor* @param backup_ui $ui* @param array $params*/public function __construct(backup_ui $ui, ?array $params = null) {$this->stage = backup_ui::STAGE_INITIAL;parent::__construct($ui, $params);}/*** Processes the initial backup stage* @param base_moodleform $m* @return int The number of changes*/public function process(?base_moodleform $m = null) {$form = $this->initialise_stage_form();if ($form->is_cancelled()) {$this->ui->cancel_process();}$data = $form->get_data();if ($data && confirm_sesskey()) {if (isset($data->oneclickbackup)) {$this->oneclickbackup = true;}$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 backup_root_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_value() &&$setting->get_ui_type() == backup_setting::UI_HTML_CHECKBOX &&$setting->get_status() !== backup_setting::LOCKED_BY_HIERARCHY) {$setting->set_value(0);$changes++;}}}}// Return the number of changes the user made.return $changes;} else {return false;}}/*** Gets the next stage for the backup.** We override this function to implement the one click backup.* When the user performs a one click backup we jump straight to the final stage.** @return int*/public function get_next_stage() {if ($this->oneclickbackup) {// Its a one click backup.// The default filename is backup.mbz, this normally gets set to something useful in the confirmation stage.// because we skipped that stage we must manually set this to a useful value.$tasks = $this->ui->get_tasks();foreach ($tasks as $task) {if ($task instanceof backup_root_task) {// Find the filename setting.$setting = $task->get_setting('filename');if ($setting) {// Use the helper objects to get a useful name.$filename = backup_plan_dbops::get_default_backup_filename($this->ui->get_format(),$this->ui->get_type(),$this->ui->get_controller_id(),$this->ui->get_setting_value('users'),$this->ui->get_setting_value('anonymize'),false,(bool)$this->ui->get_setting_value('files'));$setting->set_value($filename);}}}return backup_ui::STAGE_FINAL;}return parent::get_next_stage();}/*** Initialises the backup_moodleform instance for this stage** @return backup_initial_form*/protected function initialise_stage_form() {global $PAGE;if ($this->stageform === null) {$form = new backup_initial_form($this, $PAGE->url);// Store as a variable so we can iterate by reference.$tasks = $this->ui->get_tasks();// Iterate all tasks by reference.$add_settings = array();$dependencies = array();foreach ($tasks as &$task) {// For the initial stage we are only interested in the root settings.if ($task instanceof backup_root_task) {if ($this->ui instanceof import_ui) {$form->add_heading('rootsettings', get_string('importrootsettings', 'backup'));} else {$form->add_heading('rootsettings', get_string('rootsettings', 'backup'));}$settings = $task->get_settings();// First add all settings except the filename setting.foreach ($settings as &$setting) {if ($setting->get_name() == 'filename') {continue;}$add_settings[] = array($setting, $task);}// Then add all dependencies.foreach ($settings as &$setting) {if ($setting->get_name() == 'filename') {continue;}$dependencies[] = $setting;}}}// Add all settings at once.$form->add_settings($add_settings);// Add dependencies.foreach ($dependencies as $depsetting) {$form->add_dependencies($depsetting);}$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 backup_ui_stage_schema extends backup_ui_stage {/*** @var int Maximum number of settings to add to form at once*/const MAX_SETTINGS_BATCH = 1000;/*** Schema stage constructor* @param backup_ui $ui* @param array $params*/public function __construct(backup_ui $ui, ?array $params = null) {$this->stage = backup_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 backup_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 backup_schema_form($this, $PAGE->url);$tasks = $this->ui->get_tasks();$content = '';$courseheading = false;$add_settings = array();$dependencies = array();// Track progress through each stage.$progress = $this->ui->get_controller()->get_progress();$progress->start_progress('Initialise stage form', 3);// Get settings for all tasks.$progress->start_progress('', count($tasks));$done = 1;foreach ($tasks as $task) {if (!($task instanceof backup_root_task)) {if (!$courseheading) {// If we haven't already display a course heading to group nicely.$form->add_heading('coursesettings', get_string('includeactivities', 'backup'));$courseheading = true;}// First add each setting.foreach ($task->get_settings() as $setting) {$add_settings[] = array($setting, $task);}// The add all the dependencies.foreach ($task->get_settings() as $setting) {$dependencies[] = $setting;}} 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($add_settings);$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($add_settings, $start, $length));$start += $length;$progress->progress($done++);}$progress->end_progress();$progress->start_progress('', count($dependencies));$done = 1;foreach ($dependencies as $depsetting) {$form->add_dependencies($depsetting);$progress->progress($done++);}$progress->end_progress();// End overall progress through creating form.$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 backup_ui_stage_confirmation extends backup_ui_stage {/*** Constructs the stage* @param backup_ui $ui* @param array $params*/public function __construct($ui, ?array $params = null) {$this->stage = backup_ui::STAGE_CONFIRMATION;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()) {// Collect into a variable so we can iterate by reference.$tasks = $this->ui->get_tasks();$changes = 0;// Iterate each task by reference.foreach ($tasks as &$task) {if ($task instanceof backup_root_task) {// At this stage all we are interested in is the filename setting.$setting = $task->get_setting('filename');$name = $setting->get_ui_name();if (isset($data->$name) && $data->$name != $setting->get_value()) {$setting->set_value($data->$name);$changes++;}}}// Return the number of changes the user made.return $changes;} 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 backup_confirmation_form($this, $PAGE->url);$content = '';$courseheading = false;foreach ($this->ui->get_tasks() as $task) {if ($setting = $task->get_setting('filename')) {$form->add_heading('filenamesetting', get_string('filename', 'backup'));if ($setting->get_value() == 'backup.mbz') {$format = $this->ui->get_format();$type = $this->ui->get_type();$id = $this->ui->get_controller_id();$users = $this->ui->get_setting_value('users');$anonymised = $this->ui->get_setting_value('anonymize');$files = (bool)$this->ui->get_setting_value('files');$filename = backup_plan_dbops::get_default_backup_filename($format,$type,$id,$users,$anonymised,false,$files);$setting->set_value($filename);}$form->add_setting($setting, $task);break;}}// Track progress through tasks.$progress = $this->ui->get_controller()->get_progress();$tasks = $this->ui->get_tasks();$progress->start_progress('initialise_stage_form', count($tasks));$done = 1;foreach ($tasks as $task) {if ($task instanceof backup_root_task) {// If its a backup root add a root settings heading to group nicely.if ($this->ui instanceof import_ui) {$form->add_heading('rootsettings', get_string('importrootsettings', 'backup'));} else {$form->add_heading('rootsettings', get_string('rootsettings', 'backup'));}} else if (!$courseheading) {// We haven't already add a course heading.$form->add_heading('coursesettings', get_string('includeditems', 'backup'));$courseheading = true;}// Iterate all settings, doesnt need to happen by reference.foreach ($task->get_settings() as $setting) {// For this stage only the filename setting should be editable.if ($setting->get_name() != 'filename') {$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 backup_ui_stage_final extends backup_ui_stage {/*** Constructs the final stage* @param backup_ui $ui* @param array $params*/public function __construct(backup_ui $ui, ?array $params = null) {$this->stage = backup_ui::STAGE_FINAL;parent::__construct($ui, $params);}/*** Processes the final stage.** In this case it ALWAYS passes processing to the previous stage (confirmation)** @param base_moodleform $form* @return bool*/public function process(?base_moodleform $form = null) {return true;}/*** should NEVER be called... throws an exception*/protected function initialise_stage_form() {throw new backup_ui_exception('backup_ui_must_execute_first');}/*** should NEVER be called... throws an exception** @throws backup_ui_exception always* @param core_backup_renderer $renderer* @return void*/public function display(core_backup_renderer $renderer) {throw new backup_ui_exception('backup_ui_must_execute_first');}}/*** The completed backup stage** At this stage everything is done and the user will be redirected to view the* backup file in the file browser.** @package core_backup* @copyright 2010 Sam Hemelryk* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class backup_ui_stage_complete extends backup_ui_stage_final {/*** The results of the backup execution* @var array*/protected $results;/*** Constructs the complete backup stage** @param backup_ui $ui* @param array $params* @param array $results*/public function __construct(backup_ui $ui, ?array $params = null, ?array $results = null) {$this->results = $results;parent::__construct($ui, $params);$this->stage = backup_ui::STAGE_COMPLETE;}/*** Displays the completed backup stage.** Currently this just involves 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) {// Get the resulting stored_file record.$type = $this->get_ui()->get_controller()->get_type();$courseid = $this->get_ui()->get_controller()->get_courseid();switch ($type) {case 'activity':$cmid = $this->get_ui()->get_controller()->get_id();$cm = get_coursemodule_from_id(null, $cmid, $courseid);$modcontext = context_module::instance($cm->id);$restorerul = new moodle_url('/backup/restorefile.php', array('contextid' => $modcontext->id));break;case 'course':default:$coursecontext = context_course::instance($courseid);$restorerul = new moodle_url('/backup/restorefile.php', array('contextid' => $coursecontext->id));}$output = '';$output .= $renderer->box_start();if (!empty($this->results['include_file_references_to_external_content'])) {$output .= $renderer->notification(get_string('filereferencesincluded', 'backup'), 'notifyproblem');}if (!empty($this->results['missing_files_in_pool'])) {$output .= $renderer->notification(get_string('missingfilesinpool', 'backup'), 'notifyproblem');}$output .= $renderer->get_samesite_notification();$output .= $renderer->notification(get_string('executionsuccess', 'backup'), 'notifysuccess');$output .= $renderer->continue_button($restorerul, 'get');$output .= $renderer->box_end();return $output;}}