protected $checksum; // Cache @checksumable results for lighter @is_checksum_correct() uses
+ /**
+ *
+ * @param string $tempdir Directory under dataroot/temp/backup awaiting restore
+ * @param int $courseid Course id where restore is going to happen
+ * @param bool $interactive backup::INTERACTIVE_YES[true] or backup::INTERACTIVE_NO[false]
+ * @param int $mode backup::MODE_[ GENERAL | HUB | IMPORT | SAMESITE ]
+ * @param int $userid
+ * @param int $target backup::TARGET_[ NEW_COURSE | CURRENT_ADDING | CURRENT_DELETING | EXISTING_ADDING | EXISTING_DELETING ]
+ */
public function __construct($tempdir, $courseid, $interactive, $mode, $userid, $target){
$this->tempdir = $tempdir;
$this->courseid = $courseid;
public function finish_ui() {
if ($this->status != backup::STATUS_SETTING_UI) {
- throw new backup_controller_exception('cannot_finish_ui_if_not_setting_ui');
+ throw new restore_controller_exception('cannot_finish_ui_if_not_setting_ui');
}
$this->set_status(backup::STATUS_NEED_PRECHECK);
}
return $this->executiontime;
}
+ /**
+ * Returns the restore plan
+ * @return restore_plan
+ */
public function get_plan() {
return $this->plan;
}
*/
protected function define_settings() {
+ //$name, $vtype, $value = null, $visibility = self::VISIBLE, $status = self::NOT_LOCKED
+ $fullname = new restore_course_generic_text_setting('course_fullname', base_setting::IS_TEXT, $this->get_info()->original_course_fullname);
+ $fullname->get_ui()->set_label(get_string('setting_course_fullname', 'backup'));
+ $this->add_setting($fullname);
+
+ $shortname = new restore_course_generic_text_setting('course_shortname', base_setting::IS_TEXT, $this->get_info()->original_course_shortname);
+ $shortname->get_ui()->set_label(get_string('setting_course_shortname', 'backup'));
+ $this->add_setting($shortname);
+
+ $startdate = new restore_course_generic_text_setting('course_startdate', base_setting::IS_INTEGER, $this->get_info()->original_course_startdate);
+ $startdate->set_ui(new backup_setting_ui_dateselector($startdate, get_string('setting_course_startdate', 'backup')));
+ $this->add_setting($startdate);
+
// Define overwrite_conf to decide if course configuration will be restored over existing one
$overwrite = new restore_course_overwrite_conf_setting('overwrite_conf', base_setting::IS_BOOLEAN, false);
$overwrite->set_ui(new backup_setting_ui_select($overwrite, $overwrite->get_name(), array(1=>get_string('yes'), 0=>get_string('no'))));
+ $overwrite->get_ui()->set_label(get_string('setting_overwriteconf', 'backup'));
$this->add_setting($overwrite);
}
class restore_course_overwrite_conf_setting extends restore_course_generic_setting {}
+class restore_course_generic_text_setting extends restore_course_generic_setting {
+
+ public function __construct($name, $vtype, $value = null, $visibility = self::VISIBLE, $status = self::NOT_LOCKED) {
+ parent::__construct($name, $vtype, $value, $visibility, $status);
+ $this->set_ui(new backup_setting_ui_text($this, $name));
+ }
+
+}
+
// Section restore settings
/**
$coursetags = isset($data->tags['tag']) ? $data->tags['tag'] : array();
$coursemodules = isset($data->allowed_modules['module']) ? $data->allowed_modules['module'] : array();
$oldid = $data->id; // We'll need this later
- debugging ('review the these lines of process_course() to change to settings once available', DEBUG_DEVELOPER);
- // TODO: Get fullname, shortname, startdate and category from settings
- // $fullname = $this->get_setting_value('course_fullname');
- // $shortname = $this->get_setting_value('course_shortname');
- // $category = $this->get_setting_value('course_category');
- // $startdate = $this->get_setting_value('course_startdate');
- // TODO: Delete this lines once we are getting the vars above from settings
- $fullname = $this->task->get_info()->original_course_fullname;
- $shortname= $this->task->get_info()->original_course_shortname;
- $startdate= $this->task->get_info()->original_course_startdate;
- $category = get_course_category()->id;
+
+ $fullname = $this->get_setting_value('course_fullname');
+ $shortname = $this->get_setting_value('course_shortname');
+ $startdate = $this->get_setting_value('course_startdate');
// Calculate final course names, to avoid dupes
list($fullname, $shortname) = restore_dbops::calculate_course_names($this->get_courseid(), $fullname, $shortname);
$data->fullname = $fullname;
$data->shortname= $shortname;
$data->idnumber = '';
- $data->category = $category;
+ // TODO: Set category from the UI, its not a setting just a param
+ $data->category = get_course_category()->id;
$data->startdate= $this->apply_date_offset($data->startdate);
if ($data->defaultgroupingid) {
$data->defaultgroupingid = $this->get_mappingid('grouping', $data->defaultgroupingid);
<?php
//This script is used to configure and execute the restore proccess.
- //Define some globals for all the script
+require_once('../config.php');
+require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
+require_once($CFG->dirroot . '/backup/moodle2/restore_plan_builder.class.php');
- //Units used
- require_once("../config.php");
- require_once("../lib/xmlize.php");
- require_once("../course/lib.php");
- require_once("lib.php");
- require_once("restorelib.php");
- require_once("bb/restore_bb.php");
- require_once("$CFG->libdir/wiki_to_markdown.php" );
- require_once("$CFG->libdir/adminlib.php");
+$contextid = required_param('contextid', PARAM_INT);
+$stage = optional_param('stage', restore_ui::STAGE_CONFIRM, PARAM_INT);
- //Optional
- $id = optional_param('id', 0, PARAM_INT);
- $file = optional_param( 'file', 0, PARAM_PATH);
- $cancel = optional_param('cancel', '', PARAM_RAW);
- $launch = optional_param( 'launch', '', PARAM_ACTION);
- $to = optional_param('to', '', PARAM_INT);
- $method = optional_param('method', '', PARAM_ACTION);
- $backup_unique_code = optional_param('backup_unique_code',0,PARAM_INT);
+list($context, $course, $cm) = get_context_info_array($contextid);
- $url = new moodle_url('/backup/restore.php');
- if ($id !== 0) {
- $url->param('id', $id);
- }
- if ($file !== 0) {
- $url->param('file', $file);
- }
- if ($cancel !== '') {
- $url->param('cancel', $cancel);
- }
- if ($launch !== '') {
- $url->param('launch', $launch);
- }
- if ($to !== '') {
- $url->param('to', $to);
- }
- if ($method !== '') {
- $url->param('method', $method);
- }
- if ($backup_unique_code !== 0) {
- $url->param('backup_unique_code', $backup_unique_code);
- }
- $PAGE->set_url($url);
-
- $site = get_site();
-
-/// With method=manual, we come from the FileManager so we delete all the backup/restore/import session structures
- if ($method == 'manual') {
- if (isset($SESSION->course_header)) {
- unset ($SESSION->course_header);
- }
- if (isset($SESSION->info)) {
- unset ($SESSION->info);
- }
- if (isset($SESSION->backupprefs)) {
- unset ($SESSION->backupprefs);
- }
- if (isset($SESSION->restore)) {
- unset ($SESSION->restore);
- }
- if (isset($SESSION->import_preferences)) {
- unset ($SESSION->import_preferences);
- }
- }
+$PAGE->set_url(new moodle_url('/backup/restore.php', array('contextid'=>$contextid)));
+$PAGE->set_context($context);
+$PAGE->set_pagelayout('standard');
- if (!$to && isset($SESSION->restore->restoreto) && isset($SESSION->restore->importing) && isset($SESSION->restore->course_id)) {
- $to = $SESSION->restore->course_id;
- }
+require_login($course, null, $cm);
- $loginurl = get_login_url();
+$isfrontpage = ($course->id == SITEID);
- if (!empty($id)) {
- require_login($id);
- if (!has_capability('moodle/restore:restorecourse', get_context_instance(CONTEXT_COURSE, $id))) {
- if (empty($to)) {
- print_error("cannotuseadminadminorteacher", '', $loginurl);
- } else {
- if (!has_capability('moodle/restore:restorecourse', get_context_instance(CONTEXT_COURSE, $to))
- && !has_capability('moodle/restore:restoretargetimport', get_context_instance(CONTEXT_COURSE, $to))) {
- print_error("cannotuseadminadminorteacher", '', $loginurl);
- }
- }
- }
- } else {
- if (!has_capability('moodle/restore:restorecourse', get_context_instance(CONTEXT_SYSTEM))) {
- print_error("cannotuseadmin", '', $loginurl);
+if ($stage & restore_ui::STAGE_CONFIRM + restore_ui::STAGE_DESTINATION) {
+ $restore = restore_ui::engage_independent_stage($stage, $contextid);
+} else {
+ $restoreid = optional_param('restore', false, PARAM_ALPHANUM);
+ $rc = restore_ui::load_controller($restoreid);
+ if (!$rc) {
+ $restore = restore_ui::engage_independent_stage($stage/2, $contextid);
+ if ($restore->process()) {
+ $rc = new restore_controller($restore->get_filepath(), $restore->get_course_id(), backup::INTERACTIVE_YES,
+ backup::MODE_GENERAL, $USER->id, backup::TARGET_NEW_COURSE);
}
}
-
- //Check site
- $site = get_site();
-
- //Check necessary functions exists. Thanks to gregb@crowncollege.edu
- backup_required_functions();
-
- //Get strings
- if (empty($to)) {
- $strcourserestore = get_string("courserestore");
- } else {
- $strcourserestore = get_string("importdata");
- }
- $stradministration = get_string("administration");
-
- //If no file has been selected from the FileManager, inform and end
- $PAGE->set_title("$site->shortname: $strcourserestore");
- $PAGE->set_heading($site->fullname);
- if (!$file) {
- $PAGE->navbar->add($stradministration, new moodle_url('/admin/index.php'));
- $PAGE->navbar->add($strcourserestore);
- echo $OUTPUT->header();
- echo $OUTPUT->heading(get_string("nofilesselected"));
- echo $OUTPUT->continue_button("$CFG->wwwroot/$CFG->admin/index.php");
- echo $OUTPUT->footer();
- exit;
- }
-
- //If cancel has been selected, inform and end
- if ($cancel) {
- $PAGE->navbar->add($stradministration, new moodle_url('/admin/index.php'));
- $PAGE->navbar->add($strcourserestore);
- echo $OUTPUT->header();
- echo $OUTPUT->heading(get_string("restorecancelled"));
- echo $OUTPUT->continue_button("$CFG->wwwroot/course/view.php?id=".$id);
- echo $OUTPUT->footer();
- exit;
- }
-
- //We are here, so we have a file.
-
- //Get and check course
- if (! $course = $DB->get_record('course', array('id'=>$id))) {
- error("Course ID was incorrect (can't find it)");
- }
-
- //Print header
- if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
- $PAGE->navbar->add(basename($file));
- echo $OUTPUT->header();
- } else {
- $PAGE->navbar->add($course->shortname, new moodle_url('/course/view.php', array('id'=>$course->id)));
- $PAGE->navbar->add($strcourserestore);
- echo $OUTPUT->header();
+ if ($rc) {
+ $restore = new restore_ui($rc, array('contextid'=>$context->id));
}
- //Print form
- echo $OUTPUT->heading("$strcourserestore".((empty($to) ? ': '.basename($file) : '')));
- echo $OUTPUT->box_start();
-
- //Adjust some php variables to the execution of this script
- @ini_set("max_execution_time","3000");
- if (empty($CFG->extramemorylimit)) {
- raise_memory_limit('128M');
+}
+$outcome = $restore->process();
+if (!$restore->is_independent()) {
+ if ($restore->get_stage() == restore_ui::STAGE_PROCESS && !$restore->requires_substage()) {
+ $restore->execute();
} else {
- raise_memory_limit($CFG->extramemorylimit);
- }
-
- //Call the form, depending the step we are
-
- if (!$launch) {
- include_once("restore_precheck.html");
- } else if ($launch == "form") {
- if (!empty($SESSION->restore->importing)) {
- // set up all the config stuff and skip asking the user about it.
- restore_setup_for_check($SESSION->restore,$backup_unique_code);
- require_sesskey();
- include_once("restore_execute.html");
- } else {
- include_once("restore_form.html");
- }
- } else if ($launch == "check") {
- include_once("restore_check.html");
- //To avoid multiple restore executions...
- $SESSION->cancontinue = true;
- } else if ($launch == "execute") {
- //Prevent multiple restore executions...
- if (empty($SESSION->cancontinue)) {
- print_error('multiplerestorenotallow');
- }
- //Unset this for the future
- unset($SESSION->cancontinue);
- require_sesskey();
- include_once("restore_execute.html");
- }
- echo $OUTPUT->box_end();
-
- //Print footer
- echo $OUTPUT->footer();
+ $restore->save_controller();
+ }
+}
+$heading = $course->fullname;
+
+$PAGE->set_title($heading.': '.$restore->get_stage_name());
+$PAGE->set_heading($heading);
+$PAGE->settingsnav->get('courseadmin')->find('restore', navigation_node::TYPE_SETTING)->make_active();
+$PAGE->navbar->add($restore->get_stage_name());
+
+$renderer = $PAGE->get_renderer('core','backup');
+echo $OUTPUT->header();
+if (!$restore->is_independent() && $restore->enforce_changed_dependencies()) {
+ echo $renderer->dependency_notification(get_string('dependenciesenforced','backup'));
+}
+echo $renderer->progress_bar($restore->get_progress_bar());
+echo $restore->display($renderer);
+echo $OUTPUT->footer();
\ No newline at end of file
}
$rs->close();
}
+
+ public static function create_new_course($fullname, $shortname, $categoryid) {
+ global $DB;
+ $category = $DB->get_record('course_categories', array('id'=>$categoryid), '*', MUST_EXIST);
+
+ $course = new stdClass;
+ $course->fullname = $fullname;
+ $course->shortname = $shortname;
+ $course->category = $category->id;
+ $course->sortorder = 0;
+ $course->timecreated = time();
+ $course->timemodified = $course->timecreated;
+ $course->visible = $category->visible;
+
+ return $DB->insert_record('course', $course);
+ }
+
+ public static function delete_course_content($courseid) {
+ return remove_course_contents($courseid);
+ }
}
/*
require_once($CFG->dirroot . '/backup/util/plan/backup_structure_step.class.php');
require_once($CFG->dirroot . '/backup/util/plan/backup_execution_step.class.php');
require_once($CFG->dirroot . '/backup/controller/backup_controller.class.php');
+require_once($CFG->dirroot . '/backup/util/ui/base_moodleform.class.php');
+require_once($CFG->dirroot . '/backup/util/ui/base_ui.class.php');
+require_once($CFG->dirroot . '/backup/util/ui/base_ui_stage.class.php');
require_once($CFG->dirroot . '/backup/util/ui/backup_moodleform.class.php');
require_once($CFG->dirroot . '/backup/util/ui/backup_ui.class.php');
require_once($CFG->dirroot . '/backup/util/ui/backup_ui_stage.class.php');
require_once($CFG->dirroot . '/backup/util/plan/restore_execution_step.class.php');
require_once($CFG->dirroot . '/backup/moodle2/restore_plan_builder.class.php');
require_once($CFG->dirroot . '/backup/controller/restore_controller.class.php');
-//require_once($CFG->dirroot . '/backup/util/ui/backup_ui.class.php');
-//require_once($CFG->dirroot . '/backup/util/ui/backup_ui_stage.class.php');
+require_once($CFG->dirroot . '/backup/util/ui/base_moodleform.class.php');
+require_once($CFG->dirroot . '/backup/util/ui/base_ui.class.php');
+require_once($CFG->dirroot . '/backup/util/ui/base_ui_stage.class.php');
require_once($CFG->dirroot . '/backup/util/ui/backup_ui_setting.class.php');
+require_once($CFG->dirroot . '/backup/util/ui/restore_ui_stage.class.php');
+require_once($CFG->dirroot . '/backup/util/ui/restore_ui.class.php');
+require_once($CFG->dirroot . '/backup/util/ui/restore_moodleform.class.php');
// And some moodle stuff too
require_once ($CFG->dirroot . '/tag/lib.php');
return $this->task->get_courseid();
}
+ protected function get_userid() {
+ if (is_null($this->task)) {
+ throw new base_step_exception('not_specified_base_task');
+ }
+ return $this->task->get_userid();
+ }
+
protected function get_basepath() {
return $this->task->get_basepath();
}
*/
class restore_plan extends base_plan implements loggable {
+ /**
+ *
+ * @var restore_controller
+ */
protected $controller; // The restore controller building/executing this plan
protected $basepath; // Fullpath to dir where backup is available
protected $preloaded; // When executing the plan, do we have preloaded (from checks) info
const IS_INTEGER = 'int';
const IS_FILENAME= 'file';
const IS_PATH = 'path';
+ const IS_TEXT = 'text';
// Visible/hidden
const VISIBLE = 1;
public function __construct($name, $vtype, $value = null, $visibility = self::VISIBLE, $status = self::NOT_LOCKED) {
// Check vtype
if ($vtype !== self::IS_BOOLEAN && $vtype !== self::IS_INTEGER &&
- $vtype !== self::IS_FILENAME && $vtype !== self::IS_PATH) {
+ $vtype !== self::IS_FILENAME && $vtype !== self::IS_PATH &&
+ $vtype !== self::IS_TEXT) {
throw new base_setting_exception('setting_invalid_type');
}
throw new base_setting_exception('setting_invalid_path', $oldvalue);
}
break;
+ case self::IS_TEXT:
+ $value = clean_param($oldvalue, PARAM_TEXT);
+ if ($value != $oldvalue) {
+ throw new base_setting_exception('setting_invalid_text', $oldvalue);
+ }
+ break;
}
return $value;
}
defined('MOODLE_INTERNAL') || die();
-require_once($CFG->libdir . '/formslib.php');
-
/**
* Backup moodleform bridge
*
* @copyright 2010 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-abstract class backup_moodleform extends moodleform {
- /**
- * The stage this form belongs to
- * @var backup_ui_stage
- */
- protected $uistage = null;
- /**
- * True if we have a course div open, false otherwise
- * @var bool
- */
- protected $coursediv = false;
- /**
- * True if we have a section div open, false otherwise
- * @var bool
- */
- protected $sectiondiv = false;
- /**
- * True if we have an activity div open, false otherwise
- * @var bool
- */
- protected $activitydiv = false;
+abstract class backup_moodleform extends base_moodleform {
/**
* Creates the form
*
* @param array $attributes
* @param bool $editable
*/
- function __construct(backup_ui_stage $uistage, $action=null, $customdata=null, $method='post', $target='', $attributes=null, $editable=true) {
- $this->uistage = $uistage;
- parent::__construct($action, $customdata, $method, $target, $attributes, $editable);
- }
- /**
- * The standard form definition... obviously not much here
- */
- function definition() {
- $mform = $this->_form;
- $stage = $mform->addElement('hidden', 'stage', $this->uistage->get_stage());
- $stage = $mform->addElement('hidden', 'backup', $this->uistage->get_backupid());
- $params = $this->uistage->get_params();
- if (is_array($params) && count($params) > 0) {
- foreach ($params as $name=>$value) {
- $stage = $mform->addElement('hidden', $name, $value);
- }
- }
- }
- /**
- * Definition applied after the data is organised.. why's it here? because I want
- * to add elements on the fly.
- */
- function definition_after_data() {
- $buttonarray=array();
- if ($this->uistage->get_stage() > backup_ui::STAGE_INITIAL) {
- $buttonarray[] = $this->_form->createElement('submit', 'previous', get_string('previousstage','backup'));
- }
- $buttonarray[] = $this->_form->createElement('submit', 'submitbutton', get_string('onstage'.$this->uistage->get_stage().'action', 'backup'));
- $buttonarray[] = $this->_form->createElement('cancel');
- $this->_form->addGroup($buttonarray, 'buttonar', '', array(' '), false);
- $this->_form->closeHeaderBefore('buttonar');
- }
- /**
- * Closes any open divs
- */
- function close_task_divs() {
- if ($this->activitydiv) {
- $this->_form->addElement('html', html_writer::end_tag('div'));
- $this->activitydiv = false;
- }
- if ($this->sectiondiv) {
- $this->_form->addElement('html', html_writer::end_tag('div'));
- $this->sectiondiv = false;
- }
- if ($this->coursediv) {
- $this->_form->addElement('html', html_writer::end_tag('div'));
- $this->coursediv = false;
- }
- }
- /**
- * Adds the backup_setting as a element to the form
- * @param backup_setting $setting
- * @return bool
- */
- function add_setting(backup_setting $setting, backup_task $task=null) {
-
- // If the setting cant be changed then add it as a fixed setting.
- if (!$setting->get_ui()->is_changeable()) {
- return $this->add_fixed_setting($setting);
- }
-
- // First add the formatting for this setting
- $this->add_html_formatting($setting);
- // The call the add method with the get_element_properties array
- call_user_method_array('addElement', $this->_form, $setting->get_ui()->get_element_properties($task));
- $this->_form->setDefault($setting->get_ui_name(), $setting->get_value());
- if ($setting->has_help()) {
- list($identifier, $component) = $setting->get_help();
- $this->_form->addHelpButton($setting->get_ui_name(), $identifier, $component);
- }
- $this->_form->addElement('html', html_writer::end_tag('div'));
- return true;
- }
- /**
- * Adds a heading to the form
- * @param string $name
- * @param string $text
- */
- function add_heading($name , $text) {
- $this->_form->addElement('header', $name, $text);
- }
- /**
- * Adds HTML formatting for the given backup setting, needed to group/segment
- * correctly.
- * @param backup_setting $setting
- */
- protected function add_html_formatting(backup_setting $setting) {
- $mform = $this->_form;
- $isincludesetting = (strpos($setting->get_name(), '_include')!==false);
- if ($isincludesetting && $setting->get_level() != backup_setting::ROOT_LEVEL) {
- switch ($setting->get_level()) {
- case backup_setting::COURSE_LEVEL:
- if ($this->activitydiv) {
- $this->_form->addElement('html', html_writer::end_tag('div'));
- $this->activitydiv = false;
- }
- if ($this->sectiondiv) {
- $this->_form->addElement('html', html_writer::end_tag('div'));
- $this->sectiondiv = false;
- }
- if ($this->coursediv) {
- $this->_form->addElement('html', html_writer::end_tag('div'));
- }
- $mform->addElement('html', html_writer::start_tag('div', array('class'=>'grouped_settings course_level')));
- $mform->addElement('html', html_writer::start_tag('div', array('class'=>'include_setting course_level')));
- $this->coursediv = true;
- break;
- case backup_setting::SECTION_LEVEL:
- if ($this->activitydiv) {
- $this->_form->addElement('html', html_writer::end_tag('div'));
- $this->activitydiv = false;
- }
- if ($this->sectiondiv) {
- $this->_form->addElement('html', html_writer::end_tag('div'));
- }
- $mform->addElement('html', html_writer::start_tag('div', array('class'=>'grouped_settings section_level')));
- $mform->addElement('html', html_writer::start_tag('div', array('class'=>'include_setting section_level')));
- $this->sectiondiv = true;
- break;
- case backup_setting::ACTIVITY_LEVEL:
- if ($this->activitydiv) {
- $this->_form->addElement('html', html_writer::end_tag('div'));
- }
- $mform->addElement('html', html_writer::start_tag('div', array('class'=>'grouped_settings activity_level')));
- $mform->addElement('html', html_writer::start_tag('div', array('class'=>'include_setting activity_level')));
- $this->activitydiv = true;
- break;
- default:
- $mform->addElement('html', html_writer::start_tag('div', array('class'=>'normal_setting')));
- break;
- }
- } else if ($setting->get_level() == backup_setting::ROOT_LEVEL) {
- $mform->addElement('html', html_writer::start_tag('div', array('class'=>'root_setting')));
- } else {
- $mform->addElement('html', html_writer::start_tag('div', array('class'=>'normal_setting')));
- }
- }
- /**
- * Adds a fixed or static setting to the form
- * @param backup_setting $setting
- */
- function add_fixed_setting(backup_setting $setting) {
- global $OUTPUT;
- $settingui = $setting->get_ui();
- if ($setting->get_visibility() == backup_setting::VISIBLE) {
- $this->add_html_formatting($setting);
- switch ($setting->get_status()) {
- case backup_setting::LOCKED_BY_PERMISSION:
- $icon = ' '.$OUTPUT->pix_icon('i/permissionlock', get_string('lockedbypermission', 'backup'), 'moodle', array('class'=>'smallicon lockedicon permissionlock'));
- break;
- case backup_setting::LOCKED_BY_CONFIG:
- $icon = ' '.$OUTPUT->pix_icon('i/configlock', get_string('lockedbyconfig', 'backup'), 'moodle', array('class'=>'smallicon lockedicon configlock'));
- break;
- case backup_setting::LOCKED_BY_HIERARCHY:
- $icon = ' '.$OUTPUT->pix_icon('i/hierarchylock', get_string('lockedbyhierarchy', 'backup'), 'moodle', array('class'=>'smallicon lockedicon configlock'));
- break;
- default:
- $icon = '';
- break;
- }
- $this->_form->addElement('static', 'static_'.$settingui->get_name(), $settingui->get_label(), $settingui->get_static_value().$icon);
- $this->_form->addElement('html', html_writer::end_tag('div'));
- }
- $this->_form->addElement('hidden', $settingui->get_name(), $settingui->get_value());
- }
- /**
- * Adds dependencies to the form recursively
- *
- * @param backup_setting $setting
- */
- function add_dependencies(backup_setting $setting) {
- $mform = $this->_form;
- // Apply all dependencies for backup
- foreach ($setting->get_my_dependency_properties() as $key=>$dependency) {
- call_user_method_array('disabledIf', $this->_form, $dependency);
- }
- }
- /**
- * Returns true if the form was cancelled, false otherwise
- * @return bool
- */
- public function is_cancelled() {
- return (optional_param('cancel', false, PARAM_BOOL) || parent::is_cancelled());
+ public function __construct(backup_ui_stage $uistage, $action = null, $customdata = null, $method = 'post', $target = '', $attributes = null, $editable = true) {
+ parent::__construct($uistage, $action, $customdata, $method, $target, $attributes, $editable);
}
}
/**
* @copyright 2010 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-class backup_ui {
+class backup_ui extends base_ui {
/**
* The stages of the backup user interface.
*/
const STAGE_CONFIRMATION = 4;
const STAGE_FINAL = 8;
const STAGE_COMPLETE = 16;
- /**
- * The progress of this instance of the backup ui class
- */
- const PROGRESS_INTIAL = 0;
- const PROGRESS_PROCESSED = 1;
- const PROGRESS_SAVED = 2;
- const PROGRESS_EXECUTED = 3;
- /**
- * The backup controller
- * @var backup_controller
- */
- protected $controller;
- /**
- * The current stage
- * @var backup_ui_stage
- */
- protected $stage;
- /**
- * The current progress of the UI
- * @var int One of self::PROGRESS_*
- */
- protected $progress;
- /**
- * The number of changes made by dependency enforcement
- * @var int
- */
- protected $dependencychanges = 0;
- /**
- * Yay for constructors
- * @param backup_controller $controller
- */
- public function __construct(backup_controller $controller, array $params=null) {
- $this->controller = $controller;
- $this->progress = self::PROGRESS_INTIAL;
- $this->stage = $this->initialise_stage(null, $params);
- // Process UI event before to be safe
- $this->controller->process_ui_event();
- }
/**
* Intialises what ever stage is requested. If none are requested we check
* params for 'stage' and default to initial
}
return $stage;
}
- /**
- * This processes the current stage of the backup
- * @return bool
- */
- public function process() {
- if ($this->progress >= self::PROGRESS_PROCESSED) {
- throw new backup_ui_exception('backupuialreadyprocessed');
- }
- $this->progress = self::PROGRESS_PROCESSED;
-
- if (optional_param('previous', false, PARAM_BOOL) && $this->stage->get_stage() > self::STAGE_INITIAL) {
- $this->stage = $this->initialise_stage($this->stage->get_prev_stage(), $this->stage->get_params());
- return false;
- }
-
- // Process the stage
- $processoutcome = $this->stage->process();
-
- if ($processoutcome !== false) {
- $this->stage = $this->initialise_stage($this->stage->get_next_stage(), $this->stage->get_params());
- }
-
- // Process UI event after to check changes are valid
- $this->controller->process_ui_event();
- return $processoutcome;
- }
- /**
- * Saves the backup controller.
- *
- * Once this has been called nothing else can be changed in the controller.
- *
- * @return bool
- */
- public function save_controller() {
- if ($this->progress >= self::PROGRESS_SAVED) {
- throw new backup_ui_exception('backupuialreadysaved');
- }
- $this->progress = self::PROGRESS_SAVED;
- // First enforce dependencies
- $this->enforce_dependencies();
- // Process UI event after to check any changes are valid
- $this->controller->process_ui_event();
- // Save the controller
- $this->controller->save_controller();
- return true;
- }
- /**
- * Displays the UI for the backup!
- *
- * Note: The UI makes use of mforms (ewww!) thus it will automatically print
- * out the result rather than returning a string of HTML like other parts of Moodle
- *
- * @return bool
- */
- public function display() {
- if ($this->progress < self::PROGRESS_SAVED) {
- throw new backup_ui_exception('backupsavebeforedisplay');
- }
- $this->stage->display();
- }
- /**
- * Gets all backup tasks from the controller
- * @return array Array of backup_task
- */
- public function get_backup_tasks() {
- $plan = $this->controller->get_plan();
- $tasks = $plan->get_tasks();
- return $tasks;
- }
- /**
- * Gets the stage we are on
- * @return backup_ui_stage
- */
- public function get_stage() {
- return $this->stage->get_stage();
- }
- /**
- * Gets the name of the stage we are on
- * @return string
- */
- public function get_stage_name() {
- return $this->stage->get_name();
+ public function get_uniqueid() {
+ return $this->get_backupid();
}
/**
* Gets the backup id from the controller
$this->stage = new backup_ui_stage_complete($this, $this->stage->get_params(), $this->controller->get_results());
return true;
}
- /**
- * Enforces dependencies on all settings. Call before save
- * @return bool True if dependencies were enforced and changes were made
- */
- protected function enforce_dependencies() {
- // Get the plan
- $plan = $this->controller->get_plan();
- // Get the tasks as a var so we can iterate by reference
- $tasks = $plan->get_tasks();
- $changes = 0;
- foreach ($tasks as &$task) {
- // Store as a var so we can iterate by reference
- $settings = $task->get_settings();
- foreach ($settings as &$setting) {
- // Get all dependencies for iteration by reference
- $dependencies = $setting->get_dependencies();
- foreach ($dependencies as &$dependency) {
- // Enforce each dependency
- if ($dependency->enforce()) {
- $changes++;
- }
- }
- }
- }
- // Store the number of settings that changed through enforcement
- $this->dependencychanges = $changes;
- return ($changes>0);
- }
- /**
- * Returns true if enforce_dependencies changed any settings
- * @return bool
- */
- public function enforce_changed_dependencies() {
- return ($this->dependencychanges > 0);
- }
/**
* Loads the backup controller if we are tracking one
* @return backup_controller|false
}
return $items;
}
- /**
- * Gets the format for the backup
- * @return int
- */
- public function get_backup_format() {
- return $this->controller->get_format();
- }
- /**
- * Gets the type of the backup
- * @return int
- */
- public function get_backup_type() {
- return $this->controller->get_type();
- }
- /**
- * Gets the ID used in creating the controller. Relates to course/section/cm
- * @return int
- */
- public function get_controller_id() {
- return $this->controller->get_id();
- }
- /**
- * Gets the requested setting
- * @param string $name
- * @return mixed
- */
- public function get_setting($name, $default = false) {
- try {
- return $this->controller->get_plan()->get_setting($name);
- } catch (Exception $e) {
- debugging('Failed to find the setting: '.$name, DEBUG_DEVELOPER);
- return $default;
- }
+
+ public function get_name() {
+ return 'backup';
}
- /**
- * Gets the value for the requested setting
- *
- * @param string $name
- * @return mixed
- */
- public function get_setting_value($name, $default = false) {
- try {
- return $this->controller->get_plan()->get_setting($name)->get_value();
- } catch (Exception $e) {
- debugging('Failed to find the setting: '.$name, DEBUG_DEVELOPER);
- return $default;
- }
+
+ public function get_first_stage_id() {
+ return self::STAGE_INITIAL;
}
}
/**
* Backup user interface exception. Modelled off the backup_exception class
*/
-class backup_ui_exception extends backup_exception {}
\ No newline at end of file
+class backup_ui_exception extends base_ui_exception {}
\ No newline at end of file
* Get element properties that can be used to make a quickform element
* @return array
*/
- abstract public function get_element_properties(backup_task $task=null);
+ abstract public function get_element_properties(base_task $task=null);
/**
* Applies config options to a given properties array and then returns it
* @param array $properties
* $task is used to set the setting label
* @return string
*/
- public function get_label(backup_task $task=null) {
+ public function get_label(base_task $task=null) {
// If a task has been provided and the label is not already set meaniningfully
// we will attempt to improve it.
if (!is_null($task) && $this->label == $this->setting->get_name() && strpos($this->setting->get_name(), '_include')!==false) {
* @param backup_task|null $task
* @return array (element, name, label, attributes)
*/
- public function get_element_properties(backup_task $task=null) {
+ public function get_element_properties(base_task $task=null) {
// name, label, attributes
return $this->apply_options(array('element'=>'text','name'=>self::NAME_PREFIX.$this->name, 'label'=>$this->get_label($task), 'attributes'=>$this->attributes));
}
* @param backup_task|null $task
* @return array (element, name, label, text, attributes);
*/
- public function get_element_properties(backup_task $task=null) {
+ public function get_element_properties(base_task $task=null) {
// name, label, text, attributes
return $this->apply_options(array('element'=>'checkbox','name'=>self::NAME_PREFIX.$this->name, 'label'=>$this->get_label($task), 'text'=>$this->text, 'attributes'=>$this->attributes));
}
* @param backup_task|null $task
* @return array (element, name, label, text, value, attributes)
*/
- public function get_element_properties(backup_task $task=null) {
+ public function get_element_properties(base_task $task=null) {
// name, label, text, value, attributes
return $this->apply_options(array('element'=>'radio','name'=>self::NAME_PREFIX.$this->name, 'label'=>$this->get_label($task), 'text'=>$this->text, 'value'=>$this->value, 'attributes'=>$this->attributes));
}
* @param backup_task|null $task
* @return array (element, name, label, options, attributes)
*/
- public function get_element_properties(backup_task $task = null) {
+ public function get_element_properties(base_task $task = null) {
// name, label, options, attributes
return $this->apply_options(array('element'=>'select','name'=>self::NAME_PREFIX.$this->name, 'label'=>$this->get_label($task), 'options'=>$this->values, 'attributes'=>$this->attributes));
}
public function get_static_value() {
return $this->values[$this->get_value()];
}
+
+ public function is_changeable() {
+ if (count($this->values) == 1) {
+ return false;
+ } else {
+ return parent::is_changeable();
+ }
+ }
+}
+
+class backup_setting_ui_dateselector extends backup_setting_ui_text {
+ public function get_element_properties(base_task $task = null) {
+ if (!array_key_exists('optional', $this->attributes)) {
+ $this->attributes['optional'] = false;
+ }
+ $properties = parent::get_element_properties($task);
+ $properties['element'] = 'date_selector';
+ return $properties;
+ }
+ public function get_static_value() {
+ $value = $this->get_value();
+ if (!empty($value)) {
+ return userdate($value);
+ }
+ return parent::get_static_value();
+ }
}
\ No newline at end of file
* @copyright 2010 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-abstract class backup_ui_stage {
- /**
- * The current stage
- * @var int
- */
- protected $stage = backup_ui::STAGE_INITIAL;
- /**
- * The backuck UI object
- * @var backup_ui
- */
- protected $ui;
- /**
- * The moodleform for this stage
- * @var backup_moodleform
- */
- protected $stageform = null;
- /**
- * Custom form params that will be added as hidden inputs
- */
- protected $params = null;
- /**
- *
- * @param backup_ui $ui
- */
- public function __construct(backup_ui $ui, array $params=null) {
- $this->ui = $ui;
- $this->params = $params;
- }
- /**
- * Returns the custom params for this stage
- * @return array|null
- */
- final public function get_params() {
- return $this->params;
- }
- /**
- * The current stage
- * @return int
- */
- final public function get_stage() {
- return $this->stage;
- }
- /**
- * The next stage
- * @return int
- */
- final public function get_next_stage() {
- return floor($this->stage*2);
- }
- /**
- * The previous stage
- * @return int
- */
- final public function get_prev_stage() {
- return floor($this->stage/2);
- }
- /**
- * The name of this stage
- * @return string
- */
- final public function get_name() {
- return get_string('currentstage'.$this->stage,'backup');
+abstract class backup_ui_stage extends base_ui_stage {
+
+ 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->ui->get_backupid();
- }
- /**
- * Displays the stage.
- *
- * By default this involves instantiating the form for the stage and the calling
- * it to display. Remember this is a moodleform instance so it will print
- * rather than return.
- */
- public function display() {
- $form = $this->initialise_stage_form();
- $form->display();
+ return $this->get_uniqueid();
}
- /**
- * Processes the stage.
- *
- * This must be overridden by every stage as it will be different for every stage
- *
- * @abstract
- * @param backup_moodleform|null $form
- */
- abstract public function process(backup_moodleform $form=null);
- /**
- * Creates an instance of the correct moodleform properly populated and all
- * dependencies instantiated
- *
- * @abstract
- * @return backup_moodleform
- */
- abstract protected function initialise_stage_form();
}
/**
* @param backup_moodleform $form
* @return int The number of changes
*/
- public function process(backup_moodleform $m = null) {
+ public function process(base_moodleform $m = null) {
$form = $this->initialise_stage_form();
$data = $form->get_data();
if ($data && confirm_sesskey()) {
- $tasks = $this->ui->get_backup_tasks();
+ $tasks = $this->ui->get_tasks();
$changes = 0;
foreach ($tasks as &$task) {
// We are only interesting in the backup root task for this stage
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_backup_tasks();
+ $tasks = $this->ui->get_tasks();
// Iterate all tasks by reference
foreach ($tasks as &$task) {
// For the initial stage we are only interested in the root settings
* @param backup_moodleform|null $form
* @return int The number of changes the user made
*/
- public function process(backup_moodleform $form = null) {
+ public function process(base_moodleform $form = null) {
$form = $this->initialise_stage_form();
// Check it wasn't cancelled
if ($form->is_cancelled()) {
$data = $form->get_data();
if ($data && confirm_sesskey()) {
// Get the tasks into a var so we can iterate by reference
- $tasks = $this->ui->get_backup_tasks();
+ $tasks = $this->ui->get_tasks();
$changes = 0;
// Iterate all tasks by reference
foreach ($tasks as &$task) {
global $PAGE;
if ($this->stageform === null) {
$form = new backup_schema_form($this, $PAGE->url);
- $tasks = $this->ui->get_backup_tasks();
+ $tasks = $this->ui->get_tasks();
$content = '';
$courseheading = false;
foreach ($tasks as $task) {
* @param backup_moodleform $form
* @return int The number of changes the user made
*/
- public function process(backup_moodleform $form = null) {
+ public function process(base_moodleform $form = null) {
$form = $this->initialise_stage_form();
// Check it hasn't been cancelled
if ($form->is_cancelled()) {
$data = $form->get_data();
if ($data && confirm_sesskey()) {
// Collect into a variable so we can iterate by reference
- $tasks = $this->ui->get_backup_tasks();
+ $tasks = $this->ui->get_tasks();
$changes = 0;
// Iterate each task by reference
foreach ($tasks as &$task) {
if ($setting = $this->ui->get_setting('filename')) {
$form->add_heading('filenamesetting', get_string('filename', 'backup'));
if ($setting->get_value() == 'backup.zip') {
- $format = $this->ui->get_backup_format();
- $type = $this->ui->get_backup_type();
+ $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');
$form->add_setting($setting);
}
- foreach ($this->ui->get_backup_tasks() as $task) {
+ foreach ($this->ui->get_tasks() as $task) {
if ($task instanceof backup_root_task) {
// If its a backup root add a root settings heading to group nicely
$form->add_heading('rootsettings', get_string('rootsettings', 'backup'));
*
* In this case it ALWAYS passes processing to the previous stage (confirmation)
*/
- public function process(backup_moodleform $form=null) {
+ public function process(base_moodleform $form=null) {
return true;
}
/**
--- /dev/null
+<?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/>.
+
+/**
+ * This file contains the generic moodleform bridge for the backup user interface
+ * as well as the individual forms that relate to the different stages the user
+ * interface can exist within.
+ *
+ * @package moodlecore
+ * @copyright 2010 Sam Hemelryk
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once($CFG->libdir . '/formslib.php');
+
+/**
+ * Backup moodleform bridge
+ *
+ * Ahhh the mighty moodleform bridge! Strong enough to take the weight of 682 full
+ * grown african swallows all of whom have been carring coconuts for several days.
+ * EWWWWW!!!!!!!!!!!!!!!!!!!!!!!!
+ *
+ * @copyright 2010 Sam Hemelryk
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+abstract class base_moodleform extends moodleform {
+ /**
+ * The stage this form belongs to
+ * @var base_ui_stage
+ */
+ protected $uistage = null;
+ /**
+ * True if we have a course div open, false otherwise
+ * @var bool
+ */
+ protected $coursediv = false;
+ /**
+ * True if we have a section div open, false otherwise
+ * @var bool
+ */
+ protected $sectiondiv = false;
+ /**
+ * True if we have an activity div open, false otherwise
+ * @var bool
+ */
+ protected $activitydiv = false;
+ /**
+ * Creates the form
+ *
+ * @param backup_ui_stage $uistage
+ * @param moodle_url|string $action
+ * @param mixed $customdata
+ * @param string $method get|post
+ * @param string $target
+ * @param array $attributes
+ * @param bool $editable
+ */
+ function __construct(base_ui_stage $uistage, $action=null, $customdata=null, $method='post', $target='', $attributes=null, $editable=true) {
+ $this->uistage = $uistage;
+ parent::__construct($action, $customdata, $method, $target, $attributes, $editable);
+ }
+ /**
+ * The standard form definition... obviously not much here
+ */
+ function definition() {
+ $ui = $this->uistage->get_ui();
+ $mform = $this->_form;
+ $stage = $mform->addElement('hidden', 'stage', $this->uistage->get_stage());
+ $stage = $mform->addElement('hidden', $ui->get_name(), $ui->get_uniqueid());
+ $params = $this->uistage->get_params();
+ if (is_array($params) && count($params) > 0) {
+ foreach ($params as $name=>$value) {
+ $stage = $mform->addElement('hidden', $name, $value);
+ }
+ }
+ }
+ /**
+ * Definition applied after the data is organised.. why's it here? because I want
+ * to add elements on the fly.
+ */
+ function definition_after_data() {
+ $buttonarray=array();
+ if (!$this->uistage->is_first_stage()) {
+ $buttonarray[] = $this->_form->createElement('submit', 'previous', get_string('previousstage','backup'));
+ }
+ $buttonarray[] = $this->_form->createElement('submit', 'submitbutton', get_string($this->uistage->get_ui()->get_name().'stage'.$this->uistage->get_stage().'action', 'backup'));
+ $buttonarray[] = $this->_form->createElement('cancel');
+ $this->_form->addGroup($buttonarray, 'buttonar', '', array(' '), false);
+ $this->_form->closeHeaderBefore('buttonar');
+ }
+ /**
+ * Closes any open divs
+ */
+ function close_task_divs() {
+ if ($this->activitydiv) {
+ $this->_form->addElement('html', html_writer::end_tag('div'));
+ $this->activitydiv = false;
+ }
+ if ($this->sectiondiv) {
+ $this->_form->addElement('html', html_writer::end_tag('div'));
+ $this->sectiondiv = false;
+ }
+ if ($this->coursediv) {
+ $this->_form->addElement('html', html_writer::end_tag('div'));
+ $this->coursediv = false;
+ }
+ }
+ /**
+ * Adds the backup_setting as a element to the form
+ * @param backup_setting $setting
+ * @return bool
+ */
+ function add_setting(backup_setting $setting, base_task $task=null) {
+
+ // If the setting cant be changed then add it as a fixed setting.
+ if (!$setting->get_ui()->is_changeable()) {
+ return $this->add_fixed_setting($setting);
+ }
+
+ // First add the formatting for this setting
+ $this->add_html_formatting($setting);
+
+ // The call the add method with the get_element_properties array
+ call_user_method_array('addElement', $this->_form, $setting->get_ui()->get_element_properties($task));
+ $this->_form->setDefault($setting->get_ui_name(), $setting->get_value());
+ if ($setting->has_help()) {
+ list($identifier, $component) = $setting->get_help();
+ $this->_form->addHelpButton($setting->get_ui_name(), $identifier, $component);
+ }
+ $this->_form->addElement('html', html_writer::end_tag('div'));
+ return true;
+ }
+ /**
+ * Adds a heading to the form
+ * @param string $name
+ * @param string $text
+ */
+ function add_heading($name , $text) {
+ $this->_form->addElement('header', $name, $text);
+ }
+ /**
+ * Adds HTML formatting for the given backup setting, needed to group/segment
+ * correctly.
+ * @param backup_setting $setting
+ */
+ protected function add_html_formatting(backup_setting $setting) {
+ $mform = $this->_form;
+ $isincludesetting = (strpos($setting->get_name(), '_include')!==false);
+ if ($isincludesetting && $setting->get_level() != backup_setting::ROOT_LEVEL) {
+ switch ($setting->get_level()) {
+ case backup_setting::COURSE_LEVEL:
+ if ($this->activitydiv) {
+ $this->_form->addElement('html', html_writer::end_tag('div'));
+ $this->activitydiv = false;
+ }
+ if ($this->sectiondiv) {
+ $this->_form->addElement('html', html_writer::end_tag('div'));
+ $this->sectiondiv = false;
+ }
+ if ($this->coursediv) {
+ $this->_form->addElement('html', html_writer::end_tag('div'));
+ }
+ $mform->addElement('html', html_writer::start_tag('div', array('class'=>'grouped_settings course_level')));
+ $mform->addElement('html', html_writer::start_tag('div', array('class'=>'include_setting course_level')));
+ $this->coursediv = true;
+ break;
+ case backup_setting::SECTION_LEVEL:
+ if ($this->activitydiv) {
+ $this->_form->addElement('html', html_writer::end_tag('div'));
+ $this->activitydiv = false;
+ }
+ if ($this->sectiondiv) {
+ $this->_form->addElement('html', html_writer::end_tag('div'));
+ }
+ $mform->addElement('html', html_writer::start_tag('div', array('class'=>'grouped_settings section_level')));
+ $mform->addElement('html', html_writer::start_tag('div', array('class'=>'include_setting section_level')));
+ $this->sectiondiv = true;
+ break;
+ case backup_setting::ACTIVITY_LEVEL:
+ if ($this->activitydiv) {
+ $this->_form->addElement('html', html_writer::end_tag('div'));
+ }
+ $mform->addElement('html', html_writer::start_tag('div', array('class'=>'grouped_settings activity_level')));
+ $mform->addElement('html', html_writer::start_tag('div', array('class'=>'include_setting activity_level')));
+ $this->activitydiv = true;
+ break;
+ default:
+ $mform->addElement('html', html_writer::start_tag('div', array('class'=>'normal_setting')));
+ break;
+ }
+ } else if ($setting->get_level() == backup_setting::ROOT_LEVEL) {
+ $mform->addElement('html', html_writer::start_tag('div', array('class'=>'root_setting')));
+ } else {
+ $mform->addElement('html', html_writer::start_tag('div', array('class'=>'normal_setting')));
+ }
+ }
+ /**
+ * Adds a fixed or static setting to the form
+ * @param backup_setting $setting
+ */
+ function add_fixed_setting(backup_setting $setting) {
+ global $OUTPUT;
+ $settingui = $setting->get_ui();
+ if ($setting->get_visibility() == backup_setting::VISIBLE) {
+ $this->add_html_formatting($setting);
+ switch ($setting->get_status()) {
+ case backup_setting::LOCKED_BY_PERMISSION:
+ $icon = ' '.$OUTPUT->pix_icon('i/permissionlock', get_string('lockedbypermission', 'backup'), 'moodle', array('class'=>'smallicon lockedicon permissionlock'));
+ break;
+ case backup_setting::LOCKED_BY_CONFIG:
+ $icon = ' '.$OUTPUT->pix_icon('i/configlock', get_string('lockedbyconfig', 'backup'), 'moodle', array('class'=>'smallicon lockedicon configlock'));
+ break;
+ case backup_setting::LOCKED_BY_HIERARCHY:
+ $icon = ' '.$OUTPUT->pix_icon('i/hierarchylock', get_string('lockedbyhierarchy', 'backup'), 'moodle', array('class'=>'smallicon lockedicon configlock'));
+ break;
+ default:
+ $icon = '';
+ break;
+ }
+ $this->_form->addElement('static', 'static_'.$settingui->get_name(), $settingui->get_label(), $settingui->get_static_value().$icon);
+ $this->_form->addElement('html', html_writer::end_tag('div'));
+ }
+ $this->_form->addElement('hidden', $settingui->get_name(), $settingui->get_value());
+ }
+ /**
+ * Adds dependencies to the form recursively
+ *
+ * @param backup_setting $setting
+ */
+ function add_dependencies(backup_setting $setting) {
+ $mform = $this->_form;
+ // Apply all dependencies for backup
+ foreach ($setting->get_my_dependency_properties() as $key=>$dependency) {
+ call_user_method_array('disabledIf', $this->_form, $dependency);
+ }
+ }
+ /**
+ * Returns true if the form was cancelled, false otherwise
+ * @return bool
+ */
+ public function is_cancelled() {
+ return (optional_param('cancel', false, PARAM_BOOL) || parent::is_cancelled());
+ }
+}
\ No newline at end of file
--- /dev/null
+<?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/>.
+
+/**
+ * This file contains the backup user interface class
+ *
+ * @package moodlecore
+ * @copyright 2010 Sam Hemelryk
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * This is the backup user interface class
+ *
+ * The backup user interface class manages the user interface and backup for
+ * Moodle.
+ *
+ * @copyright 2010 Sam Hemelryk
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+abstract class base_ui {
+ /**
+ * The progress of this instance of the backup ui class
+ */
+ const PROGRESS_INTIAL = 0;
+ const PROGRESS_PROCESSED = 1;
+ const PROGRESS_SAVED = 2;
+ const PROGRESS_EXECUTED = 3;
+ /**
+ * The controller
+ * @var backup_controller|restore_controller
+ */
+ protected $controller;
+ /**
+ * The current stage
+ * @var base_ui_stage
+ */
+ protected $stage;
+ /**
+ * The current progress of the UI
+ * @var int One of self::PROGRESS_*
+ */
+ protected $progress;
+ /**
+ * The number of changes made by dependency enforcement
+ * @var int
+ */
+ protected $dependencychanges = 0;
+
+ /**
+ * Yay for constructors
+ * @param backup_controller $controller
+ */
+ public function __construct($controller, array $params=null) {
+ $this->controller = $controller;
+ $this->progress = self::PROGRESS_INTIAL;
+ $this->stage = $this->initialise_stage(null, $params);
+ // Process UI event before to be safe
+ $this->controller->process_ui_event();
+ }
+ /**
+ * Intialises what ever stage is requested. If none are requested we check
+ * params for 'stage' and default to initial
+ *
+ * @param int|null $stage The desired stage to intialise or null for the default
+ * @return base_ui_stage
+ */
+ abstract protected function initialise_stage($stage = null, array $params=null);
+ /**
+ * This processes the current stage of the backup
+ * @return bool
+ */
+ public function process() {
+ if ($this->progress >= self::PROGRESS_PROCESSED) {
+ throw new backup_ui_exception('backupuialreadyprocessed');
+ }
+ $this->progress = self::PROGRESS_PROCESSED;
+
+ if (optional_param('previous', false, PARAM_BOOL) && $this->stage->get_stage() > self::STAGE_INITIAL) {
+ $this->stage = $this->initialise_stage($this->stage->get_prev_stage(), $this->stage->get_params());
+ return false;
+ }
+
+ // Process the stage
+ $processoutcome = $this->stage->process();
+
+ if ($processoutcome !== false) {
+ $this->stage = $this->initialise_stage($this->stage->get_next_stage(), $this->stage->get_params());
+ }
+
+ // Process UI event after to check changes are valid
+ $this->controller->process_ui_event();
+ return $processoutcome;
+ }
+ /**
+ * Saves the backup controller.
+ *
+ * Once this has been called nothing else can be changed in the controller.
+ *
+ * @return bool
+ */
+ public function save_controller() {
+ if ($this->progress >= self::PROGRESS_SAVED) {
+ throw new base_ui_exception('backupuialreadysaved');
+ }
+ $this->progress = self::PROGRESS_SAVED;
+ // First enforce dependencies
+ $this->enforce_dependencies();
+ // Process UI event after to check any changes are valid
+ $this->controller->process_ui_event();
+ // Save the controller
+ $this->controller->save_controller();
+ return true;
+ }
+ /**
+ * Displays the UI for the backup!
+ *
+ * Note: The UI makes use of mforms (ewww!) thus it will automatically print
+ * out the result rather than returning a string of HTML like other parts of Moodle
+ *
+ * @return bool
+ */
+ public function display() {
+ if ($this->progress < self::PROGRESS_SAVED) {
+ throw new base_ui_exception('backupsavebeforedisplay');
+ }
+ $this->stage->display();
+ }
+ /**
+ * Gets all backup tasks from the controller
+ * @return array Array of backup_task
+ */
+ public function get_tasks() {
+ $plan = $this->controller->get_plan();
+ $tasks = $plan->get_tasks();
+ return $tasks;
+ }
+ /**
+ * Gets the stage we are on
+ * @return int
+ */
+ public function get_stage() {
+ return $this->stage->get_stage();
+ }
+ /**
+ * Gets the name of the stage we are on
+ * @return string
+ */
+ public function get_stage_name() {
+ return $this->stage->get_name();
+ }
+ /**
+ * Gets the backup id from the controller
+ * @return string
+ */
+ abstract public function get_uniqueid();
+ /**
+ * Executes the backup plan
+ * @return bool
+ */
+ abstract public function execute();
+ /**
+ * Enforces dependencies on all settings. Call before save
+ * @return bool True if dependencies were enforced and changes were made
+ */
+ protected function enforce_dependencies() {
+ // Get the plan
+ $plan = $this->controller->get_plan();
+ // Get the tasks as a var so we can iterate by reference
+ $tasks = $plan->get_tasks();
+ $changes = 0;
+ foreach ($tasks as &$task) {
+ // Store as a var so we can iterate by reference
+ $settings = $task->get_settings();
+ foreach ($settings as &$setting) {
+ // Get all dependencies for iteration by reference
+ $dependencies = $setting->get_dependencies();
+ foreach ($dependencies as &$dependency) {
+ // Enforce each dependency
+ if ($dependency->enforce()) {
+ $changes++;
+ }
+ }
+ }
+ }
+ // Store the number of settings that changed through enforcement
+ $this->dependencychanges = $changes;
+ return ($changes>0);
+ }
+ /**
+ * Returns true if enforce_dependencies changed any settings
+ * @return bool
+ */
+ public function enforce_changed_dependencies() {
+ return ($this->dependencychanges > 0);
+ }
+ /**
+ * Loads the backup controller if we are tracking one
+ * @return backup_controller|false
+ */
+ abstract public static function load_controller($uniqueid=false);
+ /**
+ * Gets an array of progress bar items that can be displayed through the backup renderer.
+ * @return array Array of items for the progress bar
+ */
+ abstract public function get_progress_bar();
+ /**
+ * Gets the format for the backup
+ * @return int
+ */
+ public function get_format() {
+ return $this->controller->get_format();
+ }
+ /**
+ * Gets the type of the backup
+ * @return int
+ */
+ public function get_type() {
+ return $this->controller->get_type();
+ }
+ public function get_controller() {
+ return $this->controller;
+ }
+ /**
+ * Gets the ID used in creating the controller. Relates to course/section/cm
+ * @return int
+ */
+ public function get_controller_id() {
+ return $this->controller->get_id();
+ }
+ /**
+ * Gets the requested setting
+ * @param string $name
+ * @return mixed
+ */
+ public function get_setting($name, $default = false) {
+ try {
+ return $this->controller->get_plan()->get_setting($name);
+ } catch (Exception $e) {
+ debugging('Failed to find the setting: '.$name, DEBUG_DEVELOPER);
+ return $default;
+ }
+ }
+ /**
+ * Gets the value for the requested setting
+ *
+ * @param string $name
+ * @return mixed
+ */
+ public function get_setting_value($name, $default = false) {
+ try {
+ return $this->controller->get_plan()->get_setting($name)->get_value();
+ } catch (Exception $e) {
+ debugging('Failed to find the setting: '.$name, DEBUG_DEVELOPER);
+ return $default;
+ }
+ }
+
+ abstract public function get_name();
+
+ abstract public function get_first_stage_id();
+}
+
+/**
+ * Backup user interface exception. Modelled off the backup_exception class
+ */
+class base_ui_exception extends backup_exception {}
\ No newline at end of file
--- /dev/null
+<?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 {@see backup_ui} instance.
+ *
+ * @package moodlecore
+ * @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
+ *
+ * @copyright 2010 Sam Hemelryk
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+abstract class base_ui_stage {
+ /**
+ * The current stage
+ * @var int
+ */
+ protected $stage = 1;
+ /**
+ * The backuck UI object
+ * @var base_ui
+ */
+ protected $ui;
+ /**
+ * The moodleform for this stage
+ * @var base_moodleform
+ */
+ protected $stageform = null;
+ /**
+ * Custom form params that will be added as hidden inputs
+ */
+ protected $params = null;
+ /**
+ *
+ * @param base_ui $ui
+ */
+ public function __construct(base_ui $ui, array $params=null) {
+ $this->ui = $ui;
+ $this->params = $params;
+ }
+ /**
+ * Returns the custom params for this stage
+ * @return array|null
+ */
+ final public function get_params() {
+ return $this->params;
+ }
+ /**
+ * The current stage
+ * @return int
+ */
+ final public function get_stage() {
+ return $this->stage;
+ }
+ /**
+ * The next stage
+ * @return int
+ */
+ final public function get_next_stage() {
+ return floor($this->stage*2);
+ }
+ /**
+ * The previous stage
+ * @return int
+ */
+ final public function get_prev_stage() {
+ return floor($this->stage/2);
+ }
+ /**
+ * The name of this stage
+ * @return string
+ */
+ public function get_name() {
+ return get_string('currentstage'.$this->stage,'backup');
+ }
+ /**
+ * The backup id from the backup controller
+ * @return string
+ */
+ final public function get_uniqueid() {
+ return $this->ui->get_uniqueid();
+ }
+ /**
+ * Displays the stage.
+ *
+ * By default this involves instantiating the form for the stage and the calling
+ * it to display. Remember this is a moodleform instance so it will print
+ * rather than return.
+ */
+ public function display() {
+ $form = $this->initialise_stage_form();
+ $form->display();
+ }
+ /**
+ * Processes the stage.
+ *
+ * This must be overridden by every stage as it will be different for every stage
+ *
+ * @abstract
+ * @param backup_moodleform|null $form
+ */
+ abstract public function process(base_moodleform $form=null);
+ /**
+ * Creates an instance of the correct moodleform properly populated and all
+ * dependencies instantiated
+ *
+ * @abstract
+ * @return backup_moodleform
+ */
+ abstract protected function initialise_stage_form();
+
+ final public function get_ui() {
+ return $this->ui;
+ }
+
+ final public function is_first_stage() {
+ return $this->stage == 1;
+ }
+}
\ No newline at end of file
public function dependency_notification($message) {
return html_writer::tag('div', $message, array('class'=>'notification dependencies_enforced'));
}
+
+ public function backup_details($details, $nextstageurl) {
+ $yestick = $this->output->pix_icon('i/tick_green_big', get_string('yes'));
+ $notick = $this->output->pix_icon('i/cross_red_big', get_string('no'));
+
+ $html = html_writer::start_tag('div', array('class'=>'backup-restore'));
+
+ $html .= html_writer::start_tag('div', array('class'=>'backup-section'));
+ $html .= $this->output->heading(get_string('backupdetails', 'backup'), 2, array('class'=>'header'));
+ $html .= $this->backup_detail_pair(get_string('backuptype', 'backup'), get_string('backuptype'.$details->type, 'backup'));
+ $html .= $this->backup_detail_pair(get_string('backupformat', 'backup'), get_string('backupformat'.$details->format, 'backup'));
+ $html .= $this->backup_detail_pair(get_string('backupmode', 'backup'), get_string('backupmode'.$details->mode, 'backup'));
+ $html .= $this->backup_detail_pair(get_string('backupdate', 'backup'), userdate($details->backup_date));
+ $html .= $this->backup_detail_pair(get_string('moodleversion', 'backup'),
+ html_writer::tag('span', $details->moodle_release, array('class'=>'moodle_release')).
+ html_writer::tag('span', '['.$details->moodle_version.']', array('class'=>'moodle_version sub-detail')));
+ $html .= $this->backup_detail_pair(get_string('backupversion', 'backup'),
+ html_writer::tag('span', $details->backup_release, array('class'=>'moodle_release')).
+ html_writer::tag('span', '['.$details->backup_version.']', array('class'=>'moodle_version sub-detail')));
+ $html .= $this->backup_detail_pair(get_string('originalwwwroot', 'backup'),
+ html_writer::tag('span', $details->original_wwwroot, array('class'=>'originalwwwroot')).
+ html_writer::tag('span', '['.$details->original_site_identifier_hash.']', array('class'=>'sitehash sub-detail')));
+ $html .= html_writer::end_tag('div');
+
+ $html .= html_writer::start_tag('div', array('class'=>'backup-section settings-section'));
+ $html .= $this->output->heading(get_string('backupsettings', 'backup'), 2, array('class'=>'header'));
+ foreach ($details->root_settings as $label=>$value) {
+ if ($label == 'filename') continue;
+ $html .= $this->backup_detail_pair(get_string('general'.str_replace('_','',$label), 'backup'), $value?$yestick:$notick);
+ }
+ $html .= html_writer::end_tag('div');
+
+ $html .= html_writer::start_tag('div', array('class'=>'backup-section'));
+ $html .= $this->output->heading(get_string('backupcoursedetails', 'backup'), 2, array('class'=>'header'));
+ $html .= $this->backup_detail_pair(get_string('coursetitle', 'backup'), $details->course->title);
+ $html .= $this->backup_detail_pair(get_string('courseid', 'backup'), $details->course->courseid);
+
+ $html .= html_writer::start_tag('div', array('class'=>'backup-sub-section'));
+ $html .= $this->output->heading(get_string('backupcoursesections', 'backup'), 3, array('class'=>'subheader'));
+ foreach ($details->sections as $key=>$section) {
+ $included = $key.'_included';
+ $userinfo = $key.'_userinfo';
+ if ($section->settings[$included] && $section->settings[$userinfo]) {
+ $value = get_string('sectionincanduser','backup');
+ } else if ($section->settings[$included]) {
+ $value = get_string('sectioninc','backup');
+ } else {
+ continue;
+ }
+ $html .= $this->backup_detail_pair(get_string('backupcoursesection', 'backup', $section->title), $value);
+ $table = null;
+ foreach ($details->activities as $activitykey=>$activity) {
+ if ($activity->sectionid != $section->sectionid) {
+ continue;
+ }
+ if (empty($table)) {
+ $table = new html_table();
+ $table->head = array('Module', 'Title', 'Userinfo');
+ $table->colclasses = array('modulename', 'moduletitle', 'userinfoincluded');
+ $table->align = array('left','left', 'center');
+ $table->attributes = array('class'=>'activitytable generaltable');
+ $table->data = array();
+ }
+ $table->data[] = array(
+ get_string('pluginname', $activity->modulename),
+ $activity->title,
+ ($activity->settings[$activitykey.'_userinfo'])?$yestick:$notick,
+ );
+ }
+ if (!empty($table)) {
+ $html .= $this->backup_detail_pair(get_string('sectionactivities','backup'), html_writer::table($table));
+ }
+
+ }
+ $html .= html_writer::end_tag('div');
+ $html .= html_writer::end_tag('div');
+ $html .= html_writer::end_tag('div');
+
+ $html .= $this->output->single_button($nextstageurl, get_string('continue'), 'post');
+
+ return $html;
+ }
+
+ public function course_selector(moodle_url $nextstageurl, $details, $categories, $courses, $currentcourse = null) {
+ global $CFG;
+ require_once($CFG->dirroot.'/course/lib.php');
+
+ $nextstageurl->param('sesskey', sesskey());
+
+ $form = html_writer::start_tag('form', array('method'=>'post', 'action'=>$nextstageurl->out_omit_querystring()));
+ foreach ($nextstageurl->params() as $key=>$value) {
+ $form .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>$key, 'value'=>$value));
+ }
+
+ $html = html_writer::start_tag('div', array('class'=>'backup-course-selector backup-restore'));
+
+ // Current course
+ if (!empty($currentcourse)) {
+ $html .= $form;
+ $form .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'targetid', 'value'=>$currentcourse));
+ $html .= html_writer::start_tag('div', array('class'=>'bcs-current-course backup-section'));
+ $html .= $this->output->heading(get_string('restoretocurrentcourse', 'backup'), 2, array('class'=>'header'));
+ $html .= $this->backup_detail_input(get_string('restoretocurrentcourseadding', 'backup'), 'radio', 'target', backup::TARGET_CURRENT_ADDING);
+ $html .= $this->backup_detail_input(get_string('restoretocurrentcoursedeleting', 'backup'), 'radio', 'target', backup::TARGET_CURRENT_DELETING);
+ $html .= $this->backup_detail_pair('', html_writer::empty_tag('input', array('type'=>'submit', 'value'=>get_string('continue'))));
+ $html .= html_writer::end_tag('div');
+ $html .= html_writer::end_tag('form');
+ }
+
+ // New course
+ $html .= $form;
+ $html .= html_writer::start_tag('div', array('class'=>'bcs-new-course backup-section'));
+ $html .= $this->output->heading(get_string('restoretonewcourse', 'backup'), 2, array('class'=>'header'));
+ $html .= $this->backup_detail_input(get_string('restoretonewcourse', 'backup'), 'radio', 'target', backup::TARGET_NEW_COURSE, array('checked'=>'checked'));
+ $html .= $this->backup_detail_select(get_string('coursecategory', 'backup'), 'targetid', $categories);
+ $html .= $this->backup_detail_pair('', html_writer::empty_tag('input', array('type'=>'submit', 'value'=>get_string('continue'))));
+ $html .= html_writer::end_tag('div');
+ $html .= html_writer::end_tag('form');
+
+ // Existing course
+ $html .= $form;
+ $html .= html_writer::start_tag('div', array('class'=>'bcs-existing-course backup-section'));
+ $html .= $this->output->heading(get_string('restoretoexistingcourse', 'backup'), 2, array('class'=>'header'));
+ $html .= $this->backup_detail_input(get_string('restoretoexistingcourseadding', 'backup'), 'radio', 'target', backup::TARGET_EXISTING_ADDING);
+ $html .= $this->backup_detail_input(get_string('restoretoexistingcoursedeleting', 'backup'), 'radio', 'target', backup::TARGET_EXISTING_DELETING);
+ $html .= $this->backup_detail_select(get_string('restoretocourse', 'backup'), 'targetid', $courses);
+ $html .= $this->backup_detail_pair('', html_writer::empty_tag('input', array('type'=>'submit', 'value'=>get_string('continue'))));
+ $html .= html_writer::end_tag('div');
+ $html .= html_writer::end_tag('form');
+
+ $html .= html_writer::end_tag('div');
+ return $html;
+ }
+
+ protected function backup_detail_pair($label, $value) {
+ static $count= 0;
+ $count++;
+ $html = html_writer::start_tag('div', array('class'=>'detail-pair'));
+ $html .= html_writer::tag('label', $label, array('class'=>'detail-pair-label', 'for'=>'detail-pair-value-'.$count));
+ $html .= html_writer::tag('div', $value, array('class'=>'detail-pair-value', 'name'=>'detail-pair-value-'.$count));
+ $html .= html_writer::end_tag('div');
+ return $html;
+ }
+
+ protected function backup_detail_input($label, $type, $name, $value, array $attributes=array()) {
+ return $this->backup_detail_pair($label, html_writer::empty_tag('input', $attributes+array('name'=>$name, 'type'=>$type, 'value'=>$value)));
+ }
+
+ protected function backup_detail_select($label, $name, $options, $selected='', $nothing=false, array $attributes=array()) {
+ return $this->backup_detail_pair($label, html_writer::select($options, 'targetid', '', false, $attributes));
+ }
+
+ public function precheck_notices($results) {
+ $output = html_writer::start_tag('div', array('class'=>'restore-precheck-notices'));
+ if (array_key_exists('errors', $results)) {
+ foreach ($results['errors'] as $error) {
+ $output .= $this->output->notification($error);
+ }
+ }
+ if (array_key_exists('warnings', $results)) {
+ foreach ($results['warnings'] as $warning) {
+ $output .= $this->output->notification($warning, 'notifywarning notifyproblem');
+ }
+ }
+ return $output.html_writer::end_tag('div');
+ }
+
+ public function continue_button($url) {
+ if (!($url instanceof moodle_url)) {
+ $url = new moodle_url($url);
+ }
+ $url->param('sesskey', sesskey());
+ $button = new single_button($url, get_string('continue'), 'post');
+ $button->class = 'continuebutton';
+ return $this->render($button);
+ }
/**
* Print a backup files tree
* @param file_info $fileinfo
$html .= '</div>';
return $html;
}
+
}
/**
* Data structure representing backup files viewer
$this->tree[] = $fileitem;
}
}
-}
+}
\ No newline at end of file
--- /dev/null
+<?php
+
+require_once($CFG->dirroot.'/backup/util/ui/backup_moodleform.class.php');
+
+class restore_moodleform extends base_moodleform {
+ public function __construct(restore_ui_stage $uistage, $action = null, $customdata = null, $method = 'post', $target = '', $attributes = null, $editable = true) {
+ parent::__construct($uistage, $action, $customdata, $method, $target, $attributes, $editable);
+ }
+}
+
+class restore_settings_form extends restore_moodleform {}
+class restore_schema_form extends restore_moodleform {}
+class restore_review_form extends restore_moodleform {};
\ No newline at end of file
--- /dev/null
+<?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/>.
+
+/**
+ * This file contains the restore user interface class
+ *
+ * @package moodlecore
+ * @copyright 2010 Sam Hemelryk
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * This is the restore user interface class
+ *
+ * The restore user interface class manages the user interface and restore for
+ * Moodle.
+ *
+ * @copyright 2010 Sam Hemelryk
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class restore_ui extends base_ui {
+ /**
+ * The stages of the restore user interface.
+ */
+ const STAGE_CONFIRM = 1;
+ const STAGE_DESTINATION = 2;
+ const STAGE_SETTINGS = 4;
+ const STAGE_SCHEMA = 8;
+ const STAGE_REVIEW = 16;
+ const STAGE_PROCESS = 32;
+ const STAGE_COMPLETE = 64;
+
+ /**
+ *
+ * @var restore_ui_stage
+ */
+ protected $stage = null;
+
+ public static $stages = array(
+ restore_ui::STAGE_CONFIRM => 'confirm',
+ restore_ui::STAGE_DESTINATION => 'destination',
+ restore_ui::STAGE_SETTINGS => 'settings',
+ restore_ui::STAGE_SCHEMA => 'schema',
+ restore_ui::STAGE_REVIEW => 'review',
+ restore_ui::STAGE_PROCESS => 'process',
+ restore_ui::STAGE_COMPLETE => 'complete'
+ );
+ /**
+ * Intialises what ever stage is requested. If none are requested we check
+ * params for 'stage' and default to initial
+ *
+ * @param int|null $stage The desired stage to intialise or null for the default
+ * @return restore_ui_stage_initial|restore_ui_stage_schema|restore_ui_stage_confirmation|restore_ui_stage_final
+ */
+ protected function initialise_stage($stage = null, array $params=null) {
+ if ($stage == null) {
+ $stage = optional_param('stage', self::STAGE_CONFIRM, PARAM_INT);
+ }
+ $class = 'restore_ui_stage_'.self::$stages[$stage];
+ if (!class_exists($class)) {
+ throw new restore_ui_exception('unknownuistage');
+ }
+ $stage = new $class($this, $params);
+ return $stage;
+ }
+ /**
+ * This processes the current stage of the restore
+ * @return bool
+ */
+ public function process() {
+ if ($this->progress >= self::PROGRESS_PROCESSED) {
+ throw new restore_ui_exception('restoreuialreadyprocessed');
+ }
+ $this->progress = self::PROGRESS_PROCESSED;
+
+ if (optional_param('previous', false, PARAM_BOOL) && $this->stage->get_stage() > self::STAGE_CONFIRM) {
+ $this->stage = $this->initialise_stage($this->stage->get_prev_stage(), $this->stage->get_params());
+ return false;
+ }
+
+ // Process the stage
+ $processoutcome = $this->stage->process();
+ if ($processoutcome !== false && !($this->get_stage()==self::STAGE_PROCESS && optional_param('substage', false, PARAM_BOOL))) {
+ $this->stage = $this->initialise_stage($this->stage->get_next_stage(), $this->stage->get_params());
+ }
+
+ // Process UI event after to check changes are valid
+ $this->controller->process_ui_event();
+ return $processoutcome;
+ }
+
+ public function is_independent() {
+ return false;
+ }
+ /**
+ * @return string
+ */
+ public function get_uniqueid() {
+ return $this->get_restoreid();
+ }
+ /**
+ * Gets the restore id from the controller
+ * @return string
+ */
+ public function get_restoreid() {
+ return $this->controller->get_restoreid();
+ }
+ /**
+ * Executes the restore plan
+ * @return bool
+ */
+ public function execute() {
+ if ($this->progress >= self::PROGRESS_EXECUTED) {
+ throw new restore_ui_exception('restoreuialreadyexecuted');
+ }
+ if ($this->stage->get_stage() < self::STAGE_PROCESS) {
+ throw new restore_ui_exception('restoreuifinalisedbeforeexecute');
+ }
+ if ($this->controller->get_target() == backup::TARGET_CURRENT_DELETING || $this->controller->get_target() == backup::TARGET_EXISTING_DELETING) {
+ restore_dbops::delete_course_content($this->controller->get_courseid());
+ }
+ $this->controller->execute_plan();
+ $this->progress = self::PROGRESS_EXECUTED;
+ $this->stage = new restore_ui_stage_complete($this, $this->stage->get_params(), $this->controller->get_results());
+ return true;
+ }
+ /**
+ * Returns true if enforce_dependencies changed any settings
+ * @return bool
+ */
+ public function enforce_changed_dependencies() {
+ return ($this->dependencychanges > 0);
+ }
+ /**
+ * Loads the restore controller if we are tracking one
+ * @return restore_controller|false
+ */
+ final public static function load_controller($restoreid=false) {
+ // Get the restore id optional param
+ if ($restoreid) {
+ try {
+ // Try to load the controller with it.
+ // If it fails at this point it is likely because this is the first load
+ $controller = restore_controller::load_controller($restoreid);
+ return $controller;
+ } catch (Exception $e) {
+ return false;
+ }
+ }
+ return $restoreid;
+ }
+ final public static function engage_independent_stage($stage, $contextid) {
+ if (!($stage & self::STAGE_CONFIRM + self::STAGE_DESTINATION)) {
+ throw new restore_ui_exception('dependentstagerequested');
+ }
+ $class = 'restore_ui_stage_'.self::$stages[$stage];
+ if (!class_exists($class)) {
+ throw new restore_ui_exception('unknownuistage');
+ }
+ return new $class($contextid);
+ }
+ /**
+ * Cancels the current restore and redirects the user back to the relevant place
+ */
+ public function cancel_restore() {
+ global $PAGE;
+ // Determine the approriate URL to redirect the user to
+ if ($PAGE->context->contextlevel == CONTEXT_MODULE && $PAGE->cm !== null) {
+ $relevanturl = new moodle_url('/mod/'.$PAGE->cm->modname.'/view.php', array('id'=>$PAGE->cm->id));
+ } else {
+ $relevanturl = new moodle_url('/course/view.php', array('id'=>$PAGE->course->id));
+ }
+ redirect($relevanturl);
+ }
+ /**
+ * 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 = self::STAGE_COMPLETE;
+ $currentstage = $this->stage->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 < self::STAGE_COMPLETE && $stage > self::STAGE_DESTINATION) {
+ $item['link'] = new moodle_url($PAGE->url, array('restore'=>$this->get_restoreid(), 'stage'=>$stage));
+ }
+ array_unshift($items, $item);
+ $stage = floor($stage/2);
+ }
+ return $items;
+ }
+
+ public function get_name() {
+ return 'restore';
+ }
+
+ public function get_first_stage_id() {
+ return self::STAGE_CONFIRM;
+ }
+
+ public function requires_substage() {
+ return ($this->stage->has_sub_stages() && !$this->stage->process());
+ }
+
+ public function display($renderer) {
+ if ($this->progress < self::PROGRESS_SAVED) {
+ throw new base_ui_exception('backupsavebeforedisplay');
+ }
+ $this->stage->display($renderer);
+ }
+}
+
+/**
+ * restore user interface exception. Modelled off the restore_exception class
+ */
+class restore_ui_exception extends base_ui_exception {}
\ No newline at end of file
--- /dev/null
+<?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 {@see restore_ui} instance.
+ *
+ * @package moodlecore
+ * @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
+ *
+ * @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 {
+ /**
+ *
+ * @param restore_ui $ui
+ */
+ 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();
+ }
+
+ final public function is_independent() {
+ 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');
+ }
+}
+
+abstract class restore_ui_independent_stage {
+ abstract public function __construct($contextid);
+ abstract public function process();
+ abstract public function display($renderer);
+ abstract public function get_stage();
+ /**
+ * 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) {
+ //$item['link'] = new moodle_url($PAGE->url, array('restore'=>$this->get_restoreid(), 'stage'=>$stage));
+ }
+ array_unshift($items, $item);
+ $stage = floor($stage/2);
+ }
+ return $items;
+ }
+ abstract public function get_stage_name();
+ final public function is_independent() {
+ return true;
+ }
+}
+
+class restore_ui_stage_confirm extends restore_ui_independent_stage {
+ protected $contextid;
+ protected $filename = null;
+ protected $filepath = null;
+ protected $details;
+ public function __construct($contextid) {
+ $this->contextid = $contextid;
+ $this->filename = required_param('filename', PARAM_FILE);
+ }
+ public function process() {
+ global $CFG;
+ if (!file_exists("$CFG->dataroot/temp/backup/".$this->filename)) {
+ throw new restore_ui_exception('invalidrestorefile');
+ }
+ return $this->extract_file_to_dir();
+ }
+ protected function extract_file_to_dir() {
+ global $CFG, $USER;
+
+ $this->filepath = restore_controller::get_tempdir_name($this->contextid, $USER->id);
+
+ $fb = get_file_packer();
+ return ($fb->extract_to_pathname("$CFG->dataroot/temp/backup/".$this->filename, "$CFG->dataroot/temp/backup/$this->filepath/"));
+ }
+ public function display($renderer) {
+ $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)));
+ }
+ public function get_stage_name() {
+ return get_string('restorestage'.restore_ui::STAGE_CONFIRM, 'backup');
+ }
+ public function get_stage() {
+ return restore_ui::STAGE_CONFIRM;
+ }
+}
+
+class restore_ui_stage_destination extends restore_ui_independent_stage {
+ protected $contextid;
+ protected $filepath = null;
+ protected $details;
+ protected $courseid = null;
+ public function __construct($contextid) {
+ $this->contextid = $contextid;
+ $this->filepath = required_param('filepath', PARAM_ALPHANUM);
+ }
+ public function process() {
+ global $CFG, $DB;
+ if (!file_exists("$CFG->dataroot/temp/backup/".$this->filepath) || !is_dir("$CFG->dataroot/temp/backup/".$this->filepath)) {
+ throw new restore_ui_exception('invalidrestorepath');
+ }
+ $target = optional_param('target', null, PARAM_INT);
+ if (!is_null($target) && confirm_sesskey()) {
+ $targetid = required_param('targetid', PARAM_INT);
+ if ($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;
+ }
+ /**
+ *
+ * @global moodle_database $DB
+ * @param core_backup_renderer $renderer
+ * @return string
+ */
+ public function display($renderer) {
+ global $DB;
+ $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));
+ $context = get_context_instance_by_id($this->contextid);
+ $currentcourse = ($context->contextlevel == CONTEXT_COURSE)?$context->instanceid:false;
+ $courselist = array();
+ $courses = $DB->get_recordset('course', array(), 'id,fullname,shortname');
+ foreach ($courses as $course) {
+ $courselist[$course->id] = $course->fullname.' ['.$course->shortname.']';
+ }
+ $courses->close();
+ $html = $renderer->course_selector($url, $this->details, make_categories_options(), $courselist, $currentcourse);
+ return $html;
+ }
+ public function get_stage_name() {
+ return get_string('restorestage'.restore_ui::STAGE_DESTINATION, 'backup');
+ }
+ public function get_filepath() {
+ return $this->filepath;
+ }
+ public function get_course_id() {
+ return $this->courseid;
+ }
+ public function get_stage() {
+ return restore_ui::STAGE_DESTINATION;
+ }
+}
+
+class restore_ui_stage_settings extends restore_ui_stage {
+ /**
+ * Initial restore stage constructor
+ * @param restore_ui $ui
+ */
+ public function __construct(restore_ui $ui, array $params=null) {
+ $this->stage = restore_ui::STAGE_SETTINGS;
+ parent::__construct($ui, $params);
+ }
+
+ public function process(base_moodleform $form=null) {
+ $form = $this->initialise_stage_form();
+
+ if ($form->is_cancelled()) {
+ $this->ui->cancel_restore();
+ }
+
+ $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;
+ }
+ }
+
+ 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.
+ *
+ * @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 {
+ /**
+ * Schema stage constructor
+ * @param backup_moodleform $ui
+ */
+ public function __construct(restore_ui $ui, array $params=null) {
+ $this->stage = restore_ui::STAGE_SCHEMA;
+ parent::__construct($ui, $params);
+ }
+ /**
+ * Processes the schema stage
+ *
+ * @param backup_moodleform|null $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_backup();
+ }
+
+ // 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();
+ $content = '';
+ $courseheading = false;
+ foreach ($tasks as $task) {
+ if (!($task instanceof restore_root_task)) {
+ if (!$courseheading) {
+ // If we havn't already display a course heading to group nicely
+ $form->add_heading('coursesettings', get_string('coursesettings', 'backup'));
+ $courseheading = true;
+ }
+ // First add each setting
+ foreach ($task->get_settings() as $setting) {
+ $form->add_setting($setting, $task);
+ }
+ // The add all the dependencies
+ foreach ($task->get_settings() as $setting) {
+ $form->add_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);
+ }
+ }
+ }
+ }
+ $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.
+ *
+ * @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 backup_ui $ui
+ */
+ public function __construct($ui, array $params=null) {
+ $this->stage = restore_ui::STAGE_REVIEW;
+ parent::__construct($ui, $params);
+ }
+ /**
+ * Processes the confirmation stage
+ *
+ * @param backup_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_backup();
+ }
+
+ $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;
+
+ foreach ($this->ui->get_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('rootsettings', 'backup'));
+ } else if (!$courseheading) {
+ // we havn'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);
+ }
+ }
+ $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.
+ *
+ * @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 {
+
+ const SUBSTAGE_NONE = 0;
+ const SUBSTAGE_CONVERT = 1;
+ const SUBSTAGE_PRECHECKS = 2;
+
+ protected $substage = 0;
+
+ /**
+ * Constructs the final stage
+ * @param backup_ui $ui
+ */
+ 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.
+ */
+ public function process(base_moodleform $form=null) {
+ $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_NEED_PRECHECK && !$rc->execute_precheck(true)) {
+ $this->substage = self::SUBSTAGE_PRECHECKS;
+ }
+ }
+ 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');
+ }
+ /**
+ * should NEVER be called... throws an exception
+ */
+ public function display($renderer) {
+ global $PAGE;
+ switch ($this->substage) {
+ case self::SUBSTAGE_CONVERT :
+ echo '<h2>Need to show the conversion screens here</h2>';
+ break;
+ case self::SUBSTAGE_PRECHECKS :
+ $results = $this->ui->get_controller()->get_precheck_results();
+ echo $renderer->precheck_notices($results);
+ break;
+ default:
+ throw new restore_ui_exception('backup_ui_must_execute_first');
+ }
+ echo $renderer->continue_button(new moodle_url($PAGE->url, array('restore'=>$this->get_uniqueid(), 'stage'=>restore_ui::STAGE_PROCESS, 'substage'=>$this->substage)));
+ }
+
+ public function has_sub_stages() {
+ return true;
+ }
+}
+
+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 backup_ui $ui
+ * @param array|null $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.
+ *
+ * @global core_renderer $OUTPUT
+ */
+ public function display($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())));
+ echo $OUTPUT->box_end();
+ }
+}
\ No newline at end of file
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
+$string['backupactivity'] = 'Backup activity: {$a}';
$string['backupcourse'] = 'Backup course: {$a}';
+$string['backupcoursedetails'] = 'Course details';
+$string['backupcoursesection'] = 'Section: {$a}';
+$string['backupcoursesections'] = 'Course sections';
+$string['backupdate'] = 'Date taken';
+$string['backupdetails'] = 'Backup details';
+$string['backupformat'] = 'Format';
+$string['backupformatmoodle2'] = 'Moodle 2';
+$string['backupmode'] = 'Mode';
+$string['backupmode10'] = 'General';
$string['backupsection'] = 'Backup course section: {$a}';
-$string['backupactivity'] = 'Backup activity: {$a}';
+$string['backupsettings'] = 'Backup settings';
+$string['backupsitedetails'] = 'Site details';
+$string['backupstage1action'] = 'Next';
+$string['backupstage2action'] = 'Next';
+$string['backupstage4action'] = 'Perform backup';
+$string['backupstage8action'] = 'Continue';
+$string['backupstage16action'] = 'Continue';
+$string['backuptype'] = 'Type';
+$string['backuptypecourse'] = 'Course';
+$string['backupversion'] = 'Backup version';
$string['cannotfindassignablerole'] = 'The {$a} role in the backup file cannot be mapped to any of the roles that you are allowed to assign.';
$string['choosefile'] = 'Choose an existing backup file';
$string['configgeneralactivities'] = 'Sets the default for including activities in a backup.';
$string['configgeneraluserscompletion'] = 'If enabled user completion information will be included in backups by default.';
$string['configgeneraluserfiles'] = 'Sets the default for whether user files will be included in backups.';
$string['configgeneralusers'] = 'Sets the default for whether to include users in backups.';
+$string['coursecategory'] = 'Category the course will be restored into';
+$string['courseid'] = 'Original ID';
$string['coursesettings'] = 'Course settings';
+$string['coursetitle'] = 'Title';
$string['currentstage1'] = 'Initial settings';
$string['currentstage2'] = 'Schema settings';
$string['currentstage4'] = 'Confirmation and review';
$string['generalcomments'] = 'Include comments';
$string['generalfilters'] = 'Include filters';
$string['generalhistories'] = 'Include histories';
+$string['generalgradehistories'] = 'Include histories';
$string['generallogs'] = 'Include logs';
$string['generalroleassignments'] = 'Include role assignments';
$string['generaluserscompletion'] = 'Include user completion information';
$string['lockedbypermission'] = 'You don\'t have sufficient permissions to change this setting';
$string['lockedbyconfig'] = 'This setting has been locked by the default backup settings';
$string['lockedbyhierarchy'] = 'Locked by dependencies';
-$string['onstage1action'] = 'Next';
-$string['onstage2action'] = 'Next';
-$string['onstage4action'] = 'Perform backup';
-$string['onstage8action'] = 'Continue';
-$string['onstage16action'] = 'Continue';
+$string['moodleversion'] = 'Moodle version';
+$string['originalwwwroot'] = 'URL of backup';
$string['previousstage'] = 'Previous';
$string['restoreactivity'] = 'Restore activity';
$string['restorecourse'] = 'Restore course';
+$string['restorecoursesettings'] = 'Course settings';
+$string['restoreexecutionsuccess'] = 'The course was restored successfully, clicking the continue button below will take you to view the course you restored.';
+$string['restorenewcoursefullname'] = 'New course name';
+$string['restorenewcourseshortname'] = 'New course short name';
+$string['restorenewcoursestartdate'] = 'New start date';
+$string['restorerootsettings'] = 'Restore settings';
$string['restoresection'] = 'Restore section';
+$string['restorestage1'] = 'Confirm';
+$string['restorestage1action'] = 'Next';
+$string['restorestage2'] = 'Destination';
+$string['restorestage2action'] = 'Next';
+$string['restorestage4'] = 'Settings';
+$string['restorestage4action'] = 'Next';
+$string['restorestage8'] = 'Schema';
+$string['restorestage8action'] = 'Next';
+$string['restorestage16'] = 'Review';
+$string['restorestage16action'] = 'Perform restore';
+$string['restorestage32'] = 'Process';
+$string['restorestage32action'] = 'Continue';
+$string['restorestage64'] = 'Complete';
+$string['restorestage64action'] = 'Continue';
+$string['restoretarget'] = 'Restore target';
+$string['restoretocourse'] = 'Restore to course: ';
+$string['restoretocurrentcourse'] = 'Restore into this course';
+$string['restoretocurrentcourseadding'] = 'Merge the backup course into this course';
+$string['restoretocurrentcoursedeleting'] = 'Delete the contents of this course and then restore';
+$string['restoretoexistingcourse'] = 'Restore into an existing course';
+$string['restoretoexistingcourseadding'] = 'Merge the backup course into the existing course';
+$string['restoretoexistingcoursedeleting'] = 'Delete the contents of the existing course and then restore';
+$string['restoretonewcourse'] = 'Restore as a new course';
+$string['restoringcourse'] = 'Course restoration in progress';
+$string['restoringcourseshortname'] = 'restoring';
$string['rootsettings'] = 'Backup settings';
$string['scheduledsettings'] = 'Scheduled backup settings';
+$string['sectionincanduser'] = 'Included in backup along with user information';
+$string['sectioninc'] = 'Included in backup (no user information)';
+$string['sectionactivities'] = 'Activities';
+$string['setting_overwriteconf'] = 'Overwrite course configuration';
+$string['setting_course_fullname'] = 'Course name';
+$string['setting_course_shortname'] = 'Course short name';
+$string['setting_course_startdate'] = 'Course startdate';
// Restore to this course
if (has_capability('moodle/restore:restorecourse', $coursecontext)) {
- $url = new moodle_url('/files/index.php', array('contextid'=>$coursecontext->id, 'itemid'=>0, 'component' => 'backup', 'filearea'=>'course'));
- $url = null; // Disabled until restore is implemented. MDL-21432
+ $url = new moodle_url('/backup/restorefile.php', array('contextid'=>$coursecontext->id));
$coursenode->add(get_string('restore'), $url, self::TYPE_SETTING, null, 'restore', new pix_icon('i/restore', ''));
}
.dir-rtl .loginbox .loginform .form-label {float:right;text-align:left;}
.dir-rtl .loginbox .loginform .form-input {text-align: right;}
+.backup-restore .backup-section {clear:both;border:1px solid #ddd;background-color:#f6f6f6;margin-bottom:1em;}
+.backup-restore .backup-section > h2.header {padding:5px 6px;margin:0;border-bottom:1px solid #ddd;}
+.backup-restore .backup-section .backup-sub-section {margin:0 25px;background-color:#f9f9f9;border:1px solid #f3f3f3;margin-bottom:1em;}
+.backup-restore .backup-section .backup-sub-section h3 {text-align:right;border-bottom:1px solid #DDD;padding:5px 86% 5px 6px;margin:0;background-color:#e9e9e9;}
+.backup-restore .backup-section.settings-section .detail-pair {margin:0;padding:0;width:50%;display:inline-block;}
+.backup-restore .backup-section.settings-section .detail-pair .detail-pair-label {width:65%;}
+.backup-restore .backup-section.settings-section .detail-pair .detail-pair-value {width:25%;}
+.backup-restore .activitytable {width:60%;min-width:500px;}
+.backup-restore .activitytable .modulename {width:100px;}
+.backup-restore .activitytable .moduleincluded {width:50px;}
+.backup-restore .activitytable .userinfoincluded {width:50px;}
+.backup-restore .detail-pair {}
+.backup-restore .detail-pair-label {display:inline-block;width:25%;padding:8px;margin:0;text-align:right;font-weight:bold;color:#444;vertical-align:top;}
+.backup-restore .detail-pair-value {display:inline-block;width:65%;padding:8px;margin:0;}
+.backup-restore .detail-pair-value > .sub-detail {display:block;color:#1580B6;margin-left:2em;font-size:90%;font-style: italic;}
+
.corelightbox {background-color:#CCC;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;}
-.corelightbox img {position:fixed;top:50%;}
\ No newline at end of file
+.corelightbox img {position:fixed;top:50%;}