MDL-22915, restore pre-ui

This commit is contained in:
Dongsheng Cai 2010-07-22 03:14:41 +00:00
parent e8e0d84584
commit 72f38ce751
5 changed files with 423 additions and 1 deletions

106
backup/restorefile.php Executable file
View File

@ -0,0 +1,106 @@
<?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/>.
/**
* Import backup file or select existing backup file from moodle
* @package moodlecore
* @copyright 2010 Dongsheng Cai <dongsheng@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../config.php');
require_once(dirname(__FILE__) . '/restorefile_form.php');
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
$contextid = required_param('contextid', PARAM_INT);
// action
$action = optional_param('action', '', PARAM_ALPHA);
// file parameters
// non js interface may require these parameters
$component = optional_param('component', null, PARAM_ALPHAEXT);
$filearea = optional_param('filearea', null, PARAM_ALPHAEXT);
$itemid = optional_param('itemid', null, PARAM_INT);
$filepath = optional_param('filepath', null, PARAM_PATH);
$filename = optional_param('filename', null, PARAM_FILE);
list($context, $course, $cm) = get_context_info_array($contextid);
$url = new moodle_url('/backup/restorefile.php', array('contextid'=>$contextid));
switch ($context->contextlevel) {
case CONTEXT_COURSE:
$heading = get_string('restorecourse', 'backup');
break;
case CONTEXT_MODULE:
$heading = get_string('restoreactivity', 'backup');
break;
// TODO
}
require_login($course);
require_capability('moodle/restore:restorecourse', $context);
$PAGE->set_url($url);
$PAGE->set_context($context);
$PAGE->set_title(get_string('course') . ': ' . $course->fullname);
$PAGE->set_heading($heading);
$PAGE->set_pagelayout('admin');
// choose the backup file from backup files tree
if ($action == 'choosebackupfile') {
$browser = get_file_browser();
if ($fileinfo = $browser->get_file_info($context, $component, $filearea, $itemid, $filepath, $filename)) {
$filename = restore_controller::get_tempdir_name($course->id, $USER->id);
$pathname = "$CFG->dataroot/temp/backup/".$filename;
$fileinfo->copy_to_pathname($pathname);
$restore_url = new moodle_url('/backup/restore.php', array('contextid'=>$contextid, 'filename'=>$filename));
redirect($restore_url);
} else {
redirect($url, get_string('filenotfound', 'error'));
}
die;
}
$form = new course_restore_form(null, array('contextid'=>$contextid));
$data = $form->get_data();
if ($data) {
$filename = restore_controller::get_tempdir_name($course->id, $USER->id);
$pathname = "$CFG->dataroot/temp/backup/".$filename;
$form->save_file('backupfile', $pathname);
$restore_url = new moodle_url('/backup/restore.php', array('contextid'=>$contextid, 'filename'=>$filename));
redirect($restore_url);
die;
}
$browser = get_file_browser();
$fileinfo = $browser->get_file_info($context, $component, $filearea, $itemid, $filepath, $filename);
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('choosefile', 'backup'));
echo $OUTPUT->container_start();
$renderer = $PAGE->get_renderer('core', 'backup');
echo $renderer->backup_files_viewer($fileinfo, array());
echo $OUTPUT->container_end();
echo $OUTPUT->heading(get_string('importfile', 'backup'));
echo $OUTPUT->container_start();
$form->display();
echo $OUTPUT->container_end();
echo $OUTPUT->footer();

35
backup/restorefile_form.php Executable file
View File

@ -0,0 +1,35 @@
<?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/>.
/**
* Import backup file form
* @package moodlecore
* @copyright 2010 Dongsheng Cai <dongsheng@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once($CFG->libdir.'/formslib.php');
class course_restore_form extends moodleform {
function definition() {
$mform =& $this->_form;
$contextid = $this->_customdata['contextid'];
$mform->addElement('hidden', 'contextid', $contextid);
$mform->addElement('filepicker', 'backupfile', get_string('files'));
$submit_string = get_string('restore');
$this->add_action_buttons(false, $submit_string);
}
}

156
backup/util/ui/module.js Normal file
View File

@ -0,0 +1,156 @@
// backup files tree
// Author: Dongsheng Cai <dongsheng@moodle.com>
M.core_backup_files_tree = {
y3: null,
api: M.cfg.wwwroot+'/files/filebrowser_ajax.php',
request: function(url, node, cb) {
var api = this.api + '?action=getfiletree';
var params = [];
params['contextid'] = this.get_param(url, 'contextid', -1);
params['component'] = this.get_param(url, 'component', null);
params['filearea'] = this.get_param(url, 'filearea', null);
params['itemid'] = this.get_param(url, 'itemid', -1);
params['filepath'] = this.get_param(url, 'filepath', null);
params['filename'] = this.get_param(url, 'filename', null);
var scope = this;
params['sesskey']=M.cfg.sesskey;
var cfg = {
method: 'POST',
on: {
complete: function(id,o,p) {
try {
var data = this.y3.JSON.parse(o.responseText);
} catch(e) {
alert(e.toString());
return;
}
if (data && data.length==0) {
node.isLeaf = true;
} else {
for (i in data) {
if (data[i].isdir) {
var info = {label: data[i].filename, href: data[i].url};
var n = new YAHOO.widget.TextNode(info, node, false);
YAHOO.util.Event.addListener(n.labelElId, "click", function(e) {
YAHOO.util.Event.preventDefault(e);
});
n.isLeaf = false;
} else {
var params = data[i].params;
params.action = 'choosebackupfile';
var restoreurl = M.cfg.wwwroot+'/backup/restorefile.php?'+build_querystring(params);
var info = {label: data[i].filename, 'href': data[i].url, 'restoreurl': restoreurl};
params['filename'] = data[i].filename;
var n = new YAHOO.widget.RestoreNode(info, node, false);
n.isLeaf = true;
}
}
}
cb();
}
},
arguments: {
scope: scope
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
data: build_querystring(params),
context: this
};
this.y3.io(api, cfg);
},
init : function(Y, htmlid){
var tree = new YAHOO.widget.TreeView(htmlid);
tree.setDynamicLoad(this.dynload);
var root = tree.getRoot();
var children = root.children;
tree.subscribe("clickEvent", function(e) {
if(!e.node.isLeaf){
e.node.toggle();
}
});
for (i in children) {
var node = children[i];
if (node.className == 'file-tree-folder') {
node.isLeaf = false;
// prevent link
YAHOO.util.Event.addListener(node.labelElId, "click", function(e) {
YAHOO.util.Event.preventDefault(e);
});
} else {
node.isLeaf = true;
}
}
tree.render();
this.y3 = Y;
},
dynload: function(node, oncompletecb) {
M.core_backup_files_tree.request(node.href, node, oncompletecb);
},
get_param: function(url, name, val) {
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec(url);
if( results == null ) {
return val;
} else {
return unescape(results[1]);
}
}
}
YAHOO.widget.RestoreNode = function(oData, oParent, expanded) {
if (oData) {
if (YAHOO.lang.isString(oData)) {
oData = { label: oData };
}
this.init(oData, oParent, expanded);
this.setUpLabel(oData);
}
};
YAHOO.extend(YAHOO.widget.RestoreNode, YAHOO.widget.TextNode, {
labelStyle: "ygtvlabel",
labelElId: null,
label: null,
title: null,
href: null,
target: "_blank",
_type: "RestoreNode",
setUpLabel: function(oData) {
if (YAHOO.lang.isString(oData)) {
oData = {
label: oData
};
} else {
if (oData.style) {
this.labelStyle = oData.style;
}
}
this.label = oData.label;
this.restoreurl = oData.restoreurl;
this.labelElId = "ygtvlabelel" + this.index;
},
getContentHtml: function() {
var sb = [];
sb[sb.length] = '<a';
sb[sb.length] = ' id="' + this.labelElId + '"';
sb[sb.length] = ' class="' + this.labelStyle + '"';
if (this.href) {
sb[sb.length] = ' href="' + this.href + '"';
sb[sb.length] = ' target="' + this.target + '"';
}
if (this.title) {
sb[sb.length] = ' title="' + this.title + '"';
}
sb[sb.length] = ' >';
sb[sb.length] = this.label;
sb[sb.length] = '</a>';
sb[sb.length] = ' <a href="'+this.restoreurl+'">'+M.str.moodle.restore+'</a>';
return sb.join("");
}
});

View File

@ -63,4 +63,124 @@ class core_backup_renderer extends plugin_renderer_base {
public function dependency_notification($message) {
return html_writer::tag('div', $message, array('class'=>'notification dependencies_enforced'));
}
}
/**
* Print a backup files tree
* @param file_info $fileinfo
* @param array $options
* @return string
*/
public function backup_files_viewer(file_info $fileinfo, array $options = null) {
$tree = new backup_files_viewer($fileinfo, $options);
return $this->render($tree);
}
public function render_backup_files_viewer(backup_files_viewer $tree) {
$module = array('name'=>'backup_files_tree', 'fullpath'=>'/backup/util/ui/module.js', 'requires'=>array('yui2-treeview', 'yui2-json'), 'strings'=>array(array('restore', 'moodle')));
$htmlid = 'backup-treeview-'.uniqid();
$this->page->requires->js_init_call('M.core_backup_files_tree.init', array($htmlid), false, $module);
$html = '<div>';
foreach($tree->path as $path) {
$html .= $path;
$html .= ' / ';
}
$html .= '</div>';
$html .= '<div id="'.$htmlid.'" class="filemanager-container">';
if (empty($tree->tree)) {
$html .= get_string('nofilesavailable', 'repository');
} else {
$html .= '<ul>';
foreach($tree->tree as $node) {
$link_attributes = array();
if (!empty($node['isdir'])) {
$class = ' class="file-tree-folder"';
$restore_link = '';
} else {
$class = ' class="file-tree-file"';
$link_attributes['target'] = '_blank';
$restore_link = html_writer::link($node['restoreurl'], get_string('restore', 'moodle'), $link_attributes);
}
$html .= '<li '.$class.'>';
$html .= html_writer::link($node['url'], $node['filename'], $link_attributes);
// when js is off, use this restore link
// otherwise, yui treeview will generate a restore link in js
$html .= ' '.$restore_link;
$html .= '</li>';
}
$html .= '</ul>';
}
$html .= '</div>';
return $html;
}
}
/**
* Data structure representing backup files viewer
*
* @copyright 2010 Dongsheng Cai
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 2.0
*/
class backup_files_viewer implements renderable {
public $tree;
public $path;
/**
* Constructor of backup_files_viewer class
* @param file_info $file_info
* @param array $options
*/
public function __construct(file_info $file_info, array $options = null) {
global $CFG;
$this->options = (array)$options;
$this->tree = array();
$children = $file_info->get_children();
$parent_info = $file_info->get_parent();
$level = $parent_info;
$this->path = array();
while ($level) {
$params = $level->get_params();
$context = get_context_instance_by_id($params['contextid']);
// lock user in course level
if ($context->contextlevel == CONTEXT_COURSECAT or $context->contextlevel == CONTEXT_SYSTEM) {
break;
}
$url = new moodle_url('/backup/restorefile.php', $params);
$this->path[] = html_writer::link($url->out(false), $level->get_visible_name());
$level = $level->get_parent();
}
$this->path = array_reverse($this->path);
$this->path[] = $file_info->get_visible_name();
foreach ($children as $child) {
$filedate = $child->get_timemodified();
$filesize = $child->get_filesize();
$mimetype = $child->get_mimetype();
$params = $child->get_params();
$fileitem = array(
'params' => $params,
'filename' => $child->get_visible_name(),
'filedate' => $filedate ? userdate($filedate) : '',
'filesize' => $filesize ? display_size($filesize) : ''
);
if ($child->is_directory()) {
// ignore all other fileares except backup_course backup_section and backup_activity
if ($params['component'] != 'backup' or !in_array($params['filearea'], array('course', 'section', 'activity'))) {
continue;
}
$fileitem['isdir'] = true;
// link to this folder
$folderurl = new moodle_url('/backup/restorefile.php', $params);
$fileitem['url'] = $folderurl->out(false);
} else {
$restoreurl = new moodle_url('/backup/restorefile.php', array_merge($params, array('action'=>'choosebackupfile')));
// link to this file
$fileitem['url'] = $child->get_url();
$fileitem['restoreurl'] = $restoreurl->out(false);
}
$this->tree[] = $fileitem;
}
}
}

View File

@ -27,6 +27,7 @@ $string['backupcourse'] = 'Backup course: {$a}';
$string['backupsection'] = 'Backup course section: {$a}';
$string['backupactivity'] = 'Backup activity: {$a}';
$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['configgeneralanonymize'] = 'If enabled all information pertaining to users will be anonymised by default.';
$string['configgeneralblocks'] = 'Sets the default for including blocks in a backup.';
@ -63,6 +64,7 @@ $string['generalroleassignments'] = 'Include role assignments';
$string['generaluserscompletion'] = 'Include user completion information';
$string['generaluserfiles'] = 'Include user files';
$string['generalusers'] = 'Include users';
$string['importfile'] = 'Import a backup file';
$string['includesection'] = 'Include section {$a}';
$string['includeother'] = 'Include {$a}';
$string['includeuserinfo'] = 'Include user information';
@ -76,5 +78,8 @@ $string['onstage4action'] = 'Perform backup';
$string['onstage8action'] = 'Continue';
$string['onstage16action'] = 'Continue';
$string['previousstage'] = 'Previous';
$string['restoreactivity'] = 'Restore activity';
$string['restorecourse'] = 'Restore course';
$string['restoresection'] = 'Restore section';
$string['rootsettings'] = 'Backup settings';
$string['scheduledsettings'] = 'Scheduled backup settings';