diff --git a/backup/restore.php b/backup/restore.php index 6d49b640868ac..ed72ab84b762f 100644 --- a/backup/restore.php +++ b/backup/restore.php @@ -5,7 +5,7 @@ require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php'); $contextid = required_param('contextid', PARAM_INT); -$stage = optional_param('stage', restore_ui::STAGE_CONFIRM, PARAM_INT); +$stage = optional_param('stage', restore_ui::STAGE_CONFIRM, PARAM_INT); list($context, $course, $cm) = get_context_info_array($contextid); @@ -30,9 +30,15 @@ } } if ($rc) { + // check if the format conversion must happen first + if ($rc->get_status() == backup::STATUS_REQUIRE_CONV) { + $rc->convert(); + } + $restore = new restore_ui($rc, array('contextid'=>$context->id)); } } + $outcome = $restore->process(); if (!$restore->is_independent()) { if ($restore->get_stage() == restore_ui::STAGE_PROCESS && !$restore->requires_substage()) { diff --git a/backup/util/ui/renderer.php b/backup/util/ui/renderer.php index ad1bfe49811f2..bf9b073daa97a 100644 --- a/backup/util/ui/renderer.php +++ b/backup/util/ui/renderer.php @@ -157,6 +157,49 @@ public function backup_details($details, $nextstageurl) { return $html; } + /** + * Displays the general information about a backup file with non-standard format + * + * @param string $format the name of the format + * @param moodle_url $nextstageurl URL to send user to + * @param array $details not supported yet + * @return string HTML code to display + */ + public function backup_details_nonstandard($format, $nextstageurl, array $details = array()) { + + $formatname = get_string('backupformat'.$format, 'backup'); + + $html = html_writer::start_tag('div', array('class' => 'backup-restore nonstandardformat')); + $html .= html_writer::start_tag('div', array('class' => 'backup-section')); + $html .= $this->output->heading(get_string('backupdetails', 'backup'), 2, 'header'); + $html .= $this->backup_detail_pair( + get_string('backupformat', 'backup'), + get_string('backupdetailsnonstandardinfo', 'backup', get_string('backupformat'.$format, 'backup')) + ); + $html .= html_writer::end_tag('div'); + $html .= $this->output->single_button($nextstageurl, get_string('continue'), 'post'); + $html .= html_writer::end_tag('div'); + + return $html; + } + + /** + * Displays the general information about a backup file with unknown format + * + * @param moodle_url $nextstageurl URL to send user to + * @return string HTML code to display + */ + public function backup_details_unknown(moodle_url $nextstageurl) { + + $html = html_writer::start_tag('div', array('class' => 'unknownformat')); + $html .= $this->output->heading(get_string('errorinvalidformat', 'backup'), 2, 'notifyproblem'); + $html .= html_writer::tag('div', get_string('errorinvalidformatinfo', 'backup'), array('class' => 'notifyproblem')); + $html .= $this->output->single_button($nextstageurl, get_string('continue'), 'post'); + $html .= html_writer::end_tag('div'); + + return $html; + } + /** * Displays a course selector for restore * @@ -618,23 +661,6 @@ public function render_restore_category_search(restore_category_search $componen $output .= html_writer::end_tag('div'); return $output; } - - public function invalid_format($format) { - $html = html_writer::start_tag('div', array('class'=>'invalidformat')); - $html .= html_writer::tag('h2', get_string('errorinvalidformat', 'backup'), array('class'=>'notifyproblem')); - if ($format == 'moodle1') { - // Moodle 1.x backups - $icon = $this->output->help_icon('errormoodle1format', 'backup'); - $message = get_string('errormoodle1formatdesc', 'backup').' '.$icon; - - } else { - // Totally unknown format - $message = get_string('errorinvalidformatdesc', 'backup'); - } - $html .= html_writer::tag('div', $message, array('class'=>'notifyproblem')); - $html .= html_writer::end_tag('div'); - return $html; - } } /** diff --git a/backup/util/ui/restore_ui_stage.class.php b/backup/util/ui/restore_ui_stage.class.php index 8374fd5b1dd77..a58fbecb47497 100644 --- a/backup/util/ui/restore_ui_stage.class.php +++ b/backup/util/ui/restore_ui_stage.class.php @@ -1,6 +1,5 @@ extract_to_pathname("$CFG->dataroot/temp/backup/".$this->filename, "$CFG->dataroot/temp/backup/$this->filepath/")); } + + /** + * Renders the confirmation stage screen + * + * @param core_backup_renderer $renderer renderer instance to use + * @return string HTML code + */ public function display($renderer) { - // TODO: Remove this when backup formats are better supported + $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 !== 'moodle2') { - return $renderer->invalid_format($format); - } - $this->details = backup_general_helper::get_backup_information($this->filepath); - return $renderer->backup_details($this->details, new moodle_url('/backup/restore.php', array('contextid'=>$this->contextid, 'filepath'=>$this->filepath, 'stage'=>restore_ui::STAGE_DESTINATION))); + 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 + return $renderer->backup_details_nonstandard($format, $nextstageurl); + + } 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); + } } + public function get_stage_name() { return get_string('restorestage'.restore_ui::STAGE_CONFIRM, 'backup'); } @@ -198,7 +218,6 @@ public function get_stage() { class restore_ui_stage_destination extends restore_ui_independent_stage { protected $contextid; protected $filepath = null; - protected $details; protected $courseid = null; protected $target = backup::TARGET_NEW_COURSE; protected $coursesearch = null; @@ -235,29 +254,48 @@ public function process() { } return false; } + /** + * Renders the destination stage screen * - * @global moodle_database $DB - * @param core_backup_renderer $renderer - * @return string + * @param core_backup_renderer $renderer renderer instance to use + * @return string HTML code */ public function display($renderer) { - global $DB, $USER, $PAGE; $format = backup_general_helper::detect_backup_format($this->filepath); - if ($format !== 'moodle2') { - return $renderer->invalid_format($format); + + 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; } - $this->details = backup_general_helper::get_backup_information($this->filepath); - $url = new moodle_url('/backup/restore.php', array('contextid'=>$this->contextid, 'filepath'=>$this->filepath, 'stage'=>restore_ui::STAGE_SETTINGS)); - + $nextstageurl = new moodle_url('/backup/restore.php', array( + 'contextid' => $this->contextid, + 'filepath' => $this->filepath, + 'stage' => restore_ui::STAGE_SETTINGS)); $context = get_context_instance_by_id($this->contextid); - $currentcourse = ($context->contextlevel == CONTEXT_COURSE && has_capability('moodle/restore:restorecourse', $context))?$context->instanceid:false; - $html = $renderer->course_selector($url, $this->details, $this->categorysearch, $this->coursesearch, $currentcourse); - return $html; + 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); } + public function get_stage_name() { return get_string('restorestage'.restore_ui::STAGE_DESTINATION, 'backup'); } @@ -564,7 +602,6 @@ protected function initialise_stage_form() { class restore_ui_stage_process extends restore_ui_stage { const SUBSTAGE_NONE = 0; - const SUBSTAGE_CONVERT = 1; const SUBSTAGE_PRECHECKS = 2; protected $substage = 0; @@ -592,20 +629,16 @@ public function process(base_moodleform $form=null) { // First decide whether a substage is needed $rc = $this->ui->get_controller(); - if ($rc->get_status() == backup::STATUS_REQUIRE_CONV) { - $this->substage = self::SUBSTAGE_CONVERT; - } else { - if ($rc->get_status() == backup::STATUS_SETTING_UI) { - $rc->finish_ui(); + 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); } - 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; - } + $results = $rc->get_precheck_results(); + if (!empty($results)) { + $this->substage = self::SUBSTAGE_PRECHECKS; } } @@ -635,37 +668,52 @@ public function process(base_moodleform $form=null) { protected function initialise_stage_form() { throw new backup_ui_exception('backup_ui_must_execute_first'); } + /** - * should NEVER be called... throws an exception + * Renders the process stage screen + * + * @param core_backup_renderer $renderer renderer instance to use + * @return string HTML code */ public function display($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())); - echo html_writer::start_tag('form', array('action'=>$url->out_omit_querystring(), 'class'=>'backup-restore', 'method'=>'post')); - foreach ($url->params() as $name=>$value) { - echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>$name, 'value'=>$value)); + $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', + '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_CONVERT : - echo '

Need to show the conversion screens here

'; - break; case self::SUBSTAGE_PRECHECKS : $results = $this->ui->get_controller()->get_precheck_results(); $info = $this->ui->get_controller()->get_info(); $haserrors = (!empty($results['errors'])); - echo $renderer->precheck_notices($results); + $html .= $renderer->precheck_notices($results); if (!empty($info->role_mappings->mappings)) { $context = get_context_instance(CONTEXT_COURSE, $this->ui->get_controller()->get_courseid()); $assignableroles = get_assignable_roles($context, ROLENAME_ALIAS, false); - echo $renderer->role_mappings($info->role_mappings->mappings, $assignableroles); + $html .= $renderer->role_mappings($info->role_mappings->mappings, $assignableroles); } break; default: throw new restore_ui_exception('backup_ui_must_execute_first'); } - echo $renderer->substage_buttons($haserrors); - echo html_writer::end_tag('form'); + $html .= $renderer->substage_buttons($haserrors); + $html .= html_writer::end_tag('form'); + + return $html; } public function has_sub_stages() { @@ -695,20 +743,24 @@ public function __construct(restore_ui $ui, array $params=null, array $results=n 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. * - * @global core_renderer $OUTPUT * @param core_backup_renderer $renderer */ public function display(core_backup_renderer $renderer) { - global $OUTPUT; - echo $OUTPUT->box_start(); - echo $OUTPUT->notification(get_string('restoreexecutionsuccess', 'backup'), 'notifysuccess'); - echo $renderer->continue_button(new moodle_url('/course/view.php', array('id'=>$this->get_ui()->get_controller()->get_courseid())), 'get'); - echo $OUTPUT->box_end(); + + $html = ''; + $html .= $renderer->box_start(); + $html .= $renderer->notification(get_string('restoreexecutionsuccess', 'backup'), 'notifysuccess'); + $html .= $renderer->continue_button(new moodle_url('/course/view.php', array( + 'id' => $this->get_ui()->get_controller()->get_courseid())), 'get'); + $html .= $renderer->box_end(); + + return $html; } -} \ No newline at end of file +} diff --git a/lang/en/backup.php b/lang/en/backup.php index 94fbc4d046afe..e9c0370f7baf2 100644 --- a/lang/en/backup.php +++ b/lang/en/backup.php @@ -42,11 +42,19 @@ $string['backupcoursesections'] = 'Course sections'; $string['backupdate'] = 'Date taken'; $string['backupdetails'] = 'Backup details'; +$string['backupdetailsnonstandardinfo'] = 'The selected file is not a standard Moodle backup file. The format "{$a}" has been detected. The restore process will try to convert the backup file into the standard format and then restore it.'; $string['backupformat'] = 'Format'; +$string['backupformatmoodle1'] = 'Moodle 1'; $string['backupformatmoodle2'] = 'Moodle 2'; +$string['backupformatimscc'] = 'IMS Common Cartridge'; +$string['backupformatunknown'] = 'Unknown format'; $string['backupmode'] = 'Mode'; $string['backupmode10'] = 'General'; +$string['backupmode20'] = 'Import'; $string['backupmode30'] = 'Hub'; +$string['backupmode40'] = 'Same site'; +$string['backupmode50'] = 'Automated'; +$string['backupmode60'] = 'Converted'; $string['backupsection'] = 'Backup course section: {$a}'; $string['backupsettings'] = 'Backup settings'; $string['backupsitedetails'] = 'Site details'; @@ -99,13 +107,8 @@ $string['errorfilenamemustbezip'] = 'The filename you enter must be a ZIP file and have the .mbz extension'; $string['errorminbackup20version'] = 'This backup file has been created with one development version of Moodle backup ({$a->backup}). Minimum required is {$a->min}. Cannot be restored.'; $string['errorrestorefrontpage'] = 'Restoring over front page is not allowed.'; -$string['errorinvalidformat'] = 'Invalid backup format.'; -$string['errorinvalidformatdesc'] = 'The uploaded file is not a valid Moodle backup file and could not be restored.'; -$string['errormoodle1formatdesc'] = 'The backup file was created with Moodle 1.x and can not currently be restored in Moodle 2. This functionality is coming in a future update.'; -$string['errormoodle1format'] = 'Restoring Moodle 1.9 backups'; -$string['errormoodle1format_help'] = 'Moodle 2 currently doesn\'t support restoring Moodle 1.x backups. -A temporary work around to this is to restore your Moodle 1.x backup onto a Moodle 1.9 site, and then upgrade it to Moodle 2. -Once the upgrade is complete you will be able to make new backups which will be restorable on other Moodle 2.0 sites.'; +$string['errorinvalidformat'] = 'Unknown backup format'; +$string['errorinvalidformatinfo'] = 'The selected file is not a valid Moodle backup file and can\'t be restored.'; $string['executionsuccess'] = 'The backup file was successfully created.'; $string['filename'] = 'Filename'; $string['generalactivities'] = 'Include activities';