ÿØÿà JFIF    ÿÛ „  ( %"1!%)+...383,7(-.+  -+++--++++---+-+-----+---------------+---+-++7-----ÿÀ  ß â" ÿÄ     ÿÄ H    !1AQaq"‘¡2B±ÁÑð#R“Ò Tbr‚²á3csƒ’ÂñDS¢³$CÿÄ   ÿÄ %  !1AQa"23‘ÿÚ   ? ôÿ ¨pŸªáÿ —åYõõ\?àÒü©ŠÄï¨pŸªáÿ —åYõõ\?àÓü©ŠÄá 0Ÿªáÿ Ÿå[úƒ ú®ði~TÁbqÐ8OÕpÿ ƒOò¤Oè`–RÂáœá™êi€ßÉ< FtŸI“öÌ8úDf´°å}“¾œ6  öFá°y¥jñÇh†ˆ¢ã/ÃÐ:ªcÈ "Y¡ðÑl>ÿ ”ÏËte:qž\oäŠe÷󲍷˜HT4&ÿ ÓÐü6ö®¿øþßèô Ÿ•7Ñi’•j|“ñì>b…þS?*Óôÿ ÓÐü*h¥£ír¶ü UãS炟[AÐaè[ûª•õ&õj?†Éö+EzP—WeÒírJFt ‘BŒ†Ï‡%#tE Øz ¥OÛ«!1›üä±Í™%ºÍãö]°î(–:@<‹ŒÊö×òÆt¦ãº+‡¦%ÌÁ²h´OƒJŒtMÜ>ÀÜÊw3Y´•牋4ǍýʏTì>œú=Íwhyë,¾Ôò×õ¿ßÊa»«þˆѪQ|%6ž™A õ%:øj<>É—ÿ Å_ˆCbõ¥š±ý¯Ýƒï…¶|RëócÍf溪“t.СøTÿ *Ä¿-{†çàczůŽ_–^XþŒ±miB[X±d 1,é”zEù»& î9gœf™9Ð'.;—™i}!ôšåîqêÛ٤ёý£½ÆA–àôe"A$˝Úsäÿ ÷Û #°xŸëí(l »ý3—¥5m! rt`†0~'j2(]S¦¦kv,ÚÇ l¦øJA£Šƒ J3E8ÙiŽ:cÉžúeZ°€¯\®kÖ(79«Ž:¯X”¾³Š&¡* ….‰Ž(ÜíŸ2¥ª‡×Hi²TF¤ò[¨íÈRëÉ䢍mgÑ.Ÿ<öäS0í„ǹÁU´f#Vß;Õ–…P@3ío<ä-±»Ž.L|kªÀê›fÂ6@»eu‚|ÓaÞÆŸ…¨ááå>åŠ?cKü6ùTÍÆ”†sĤÚ;H2RÚ†õ\Ö·Ÿn'¾ ñ#ºI¤Å´%çÁ­‚â7›‹qT3Iï¨ÖÚ5I7Ë!ÅOóŸ¶øÝñØôת¦$Tcö‘[«Ö³šÒ';Aþ ¸èíg A2Z"i¸vdÄ÷.iõ®§)¿]¤À†–‡É&ä{V¶iŽ”.Ó×Õÿ û?h¬Mt–íª[ÿ Ñÿ ÌV(í}=ibÔ¡›¥¢±b Lô¥‡piη_Z<‡z§èŒ)iÖwiÇ 2hÙ3·=’d÷8éŽ1¦¸c¤µ€7›7Ø ð\á)} ¹fËí›pAÃL%âc2 í§æQz¿;T8sæ°qø)QFMð‰XŒÂ±N¢aF¨…8¯!U  Z©RÊ ÖPVÄÀÍin™Ì-GˆªÅËŠ›•zË}º±ŽÍFò¹}Uw×#ä5B¤{î}Ð<ÙD é©¤&‡ïDbàÁôMÁ.. /** * 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; } }