From 56a7bf6837dd245b71abcb9f06b6270faaa5c235 Mon Sep 17 00:00:00 2001 From: dongsheng Date: Thu, 17 Sep 2009 08:47:23 +0000 Subject: [PATCH] " MDL-16597, ajax file manager element" --- files/files_ajax.php | 197 +++++++++ lib/filelib.php | 7 +- lib/form/filemanager.js | 709 +++++++++++++++++++++++++++++-- lib/form/filemanager.php | 167 +++++--- theme/standard/styles_layout.css | 48 +++ 5 files changed, 1034 insertions(+), 94 deletions(-) create mode 100755 files/files_ajax.php diff --git a/files/files_ajax.php b/files/files_ajax.php new file mode 100755 index 0000000000..334460c7c8 --- /dev/null +++ b/files/files_ajax.php @@ -0,0 +1,197 @@ +. + +/** + * File manager + * + * @package moodlecore + * @subpackage file + * @copyright 1999 onwards Dongsheng Cai + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require('../config.php'); +require_once($CFG->libdir.'/filelib.php'); +require_once($CFG->libdir.'/adminlib.php'); + +require_login(); + +$err = new stdclass; + +if (isguestuser()) { + $err->error = get_string('noguest'); + die(json_encode($err)); +} + +if (!confirm_sesskey()) { + $err->error = get_string('invalidsesskey'); + die(json_encode($err)); +} + +$action = optional_param('action', 'list', PARAM_ALPHA); +$filename = optional_param('filename', '', PARAM_FILE); +$filearea = optional_param('filearea', '', PARAM_ALPHAEXT); +$filepath = optional_param('filepath', '/', PARAM_PATH); +$itemid = optional_param('itemid', -1, PARAM_INT); +$newfilepath = optional_param('newfilepath', '/', PARAM_PATH); +$newdirname = optional_param('newdirname', '', PARAM_FILE); +$newfilename = optional_param('newfilename', '', PARAM_FILE); + +$user_context = get_context_instance(CONTEXT_USER, $USER->id); + +switch ($action) { +case 'dir': + $data = new stdclass; + file_get_draft_area_folders($itemid, $filepath, $data); + echo json_encode($data); + break; + +case 'list': + $data = file_get_draft_area_files($itemid, $filepath); + echo json_encode($data); + break; + +case 'mkdir': + $fs = get_file_storage(); + $fs->create_directory($user_context->id, 'user_draft', $itemid, file_correct_filepath(file_correct_filepath($filepath).$newdirname)); + $return = new stdclass; + $return->filepath = $filepath; + echo json_encode($return); + break; + +case 'delete': + $fs = get_file_storage(); + $filepath = file_correct_filepath($filepath); + $return = new stdclass; + if ($file = $fs->get_file($user_context->id, 'user_draft', $itemid, $filepath, $filename)) { + $parent_path = $file->get_parent_directory()->get_filepath(); + if($result = $file->delete()) { + $return->filepath = $parent_path; + echo json_encode($return); + } else { + echo json_encode(false); + } + } else { + echo json_encode(false); + } + break; + +case 'renamedir': + $fs = get_file_storage(); + $fb = get_file_browser(); + $file = $fb->get_file_info($user_context, 'user_draft', $itemid, $filepath, '.'); + if ($result = $file->delete()) { + $fs->create_directory($user_context->id, 'user_draft', $itemid, file_correct_filepath($newfilename)); + $return = new stdclass; + $return->filepath = file_correct_filepath($newfilename); + echo json_encode($return); + } else { + echo json_encode(false); + } + break; + +case 'rename': + $fb = get_file_browser(); + $file = $fb->get_file_info($user_context, 'user_draft', $itemid, $filepath, $filename); + $file->copy_to_storage($user_context->id, 'user_draft', $itemid, $filepath, $newfilename); + if ($file->delete()) { + $return = new stdclass; + $return->filepath = $filepath; + echo json_encode($return); + } else { + echo json_encode(false); + } + break; + +case 'movefile': +case 'movedir': + $fb = get_file_browser(); + $return = new stdclass; + if ($filepath != $newfilepath) { + $file = $fb->get_file_info($user_context, 'user_draft', $itemid, $filepath, $filename); + $file->copy_to_storage($user_context->id, 'user_draft', $itemid, $newfilepath, $filename); + if ($file->delete()) { + $return->filepath = $newfilepath; + } + } + if (!isset($return->filepath)) { + $return->filepath = '/'; + } + echo json_encode($return); + break; + +case 'zip': + $zipper = new zip_packer(); + $fs = get_file_storage(); + + $file = $fs->get_file($user_context->id, 'user_draft', $itemid, $filepath, '.'); + + $parent_path = $file->get_parent_directory()->get_filepath(); + + if ($newfile = $zipper->archive_to_storage(array($file), $user_context->id, 'user_draft', $itemid, $parent_path, $filepath.'.zip', $USER->id)) { + $return = new stdclass; + $return->filepath = $parent_path; + echo json_encode($return); + } else { + echo json_encode(false); + } + break; + +case 'downloaddir': + $zipper = new zip_packer(); + $fs = get_file_storage(); + + $file = $fs->get_file($user_context->id, 'user_draft', $itemid, $filepath, '.'); + if ($file->get_parent_directory()) { + $parent_path = $file->get_parent_directory()->get_filepath(); + $filename = trim($filepath, '/').'.zip'; + } else { + $parent_path = '/'; + $filename = get_string('files').'.zip'; + } + + // archive compressed file to an unused draft area + $newdraftitemid = file_get_unused_draft_itemid(); + if ($newfile = $zipper->archive_to_storage(array($file), $user_context->id, 'user_draft', $newdraftitemid, '/', $filename, $USER->id)) { + $return = new stdclass; + $return->fileurl = $CFG->wwwroot . '/draftfile.php/' . $user_context->id .'/user_draft/'.$newdraftitemid.'/'.$filename; + $return->filepath = $parent_path; + echo json_encode($return); + } else { + echo json_encode(false); + } + break; + +case 'unzip': + $zipper = new zip_packer(); + + $fs = get_file_storage(); + + $file = $fs->get_file($user_context->id, 'user_draft', $itemid, $filepath, $filename); + + if ($newfile = $file->extract_to_storage($zipper, $user_context->id, 'user_draft', $itemid, $filepath, $USER->id)) { + $return = new stdclass; + $return->filepath = $filepath; + echo json_encode($return); + } else { + echo json_encode(false); + } + break; + +default: + break; +} diff --git a/lib/filelib.php b/lib/filelib.php index 745c8b3da7..dadb5f2e03 100644 --- a/lib/filelib.php +++ b/lib/filelib.php @@ -603,7 +603,12 @@ function file_get_submitted_draft_itemid($elname) { confirm_sesskey(); } if (is_array($param)) { - $param = $param['itemid']; + if (!empty($param['itemid'])) { + $param = $param['itemid']; + } else { + debugging('Missing itemid, maybe caused by unset maxfiles option', DEBUG_DEVELOPER); + return false; + } } return $param; } diff --git a/lib/form/filemanager.js b/lib/form/filemanager.js index 0fcd96309c..6db26cf09c 100644 --- a/lib/form/filemanager.js +++ b/lib/form/filemanager.js @@ -1,47 +1,690 @@ -var selected_file = null; -var rm_cb = { - success: function(o) { - if(o.responseText){ - repository_client.files[o.responseText]--; - selected_file.parentNode.removeChild(selected_file); +/** + * This file is part of Moodle - http://moodle.org/ + * File manager + * @copyright 1999 onwards Dongsheng Cai + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +var fm_cfg = {}; +var fm_move_dlg = null; +var fm_rename_dlg = null; +var fm_mkdir_dlg = null; + +// initialize file manager +var filemanager = (function(){ + function _filemanager() { + this.init = function(client_id, options) { + this.client_id = client_id; + var container = document.getElementById('filemanager-' + client_id); + fm_cfg[client_id] = {}; + fm_cfg[client_id] = options; + fm_cfg[client_id].mainfile = options.mainfile; + fm_cfg[client_id].currentpath = '/'; + html_compiler(client_id, options); } } -} -function rm_file(id, name, context) { - if (confirm(filemanager.strdelete)) { - var trans = YAHOO.util.Connect.asyncRequest('POST', - moodle_cfg.wwwroot+'/repository/ws.php?action=delete&itemid='+id, - rm_cb, - 'title='+name+'&client_id='+filemanager.clientid - ); - selected_file = context.parentNode; - } -} -function fp_callback(obj) { - var list = document.getElementById('draftfiles-'+obj.client_id); - var html = '
  • '+obj['file']+' '; - html += ''; - html += '
  • '; - if(obj.maxfileslimit){ + return _filemanager; +})(); + +filemanager.url = moodle_cfg.wwwroot + '/files/files_ajax.php'; +filemanager.fileicon = moodle_cfg.wwwroot + '/pix/i/settings.gif'; + +// callback function for file picker +function filemanager_callback(obj) { + refresh_filemanager(obj.filepath, fm_cfg[obj.client_id]); + fm_cfg[obj.client_id].currentfiles++; + + if (fm_cfg[obj.client_id].currentfiles>=fm_cfg[obj.client_id].maxfiles) { var btn = document.getElementById('btnadd-'+obj.client_id); - btn.onclick = function(){return false;}; - btn.innerHTML = mstr.repository.nomorefiles; + btn.style.display = 'none'; } - list.innerHTML += html; } -function callpicker(el_id, client_id, itemid) { + +// setup options for file picker +function fm_launch_filepicker(el_id, options) { var picker = document.createElement('DIV'); - picker.id = 'file-picker-'+client_id; + picker.id = 'file-picker-'+options.client_id; picker.className = 'file-picker'; document.body.appendChild(picker); var el=document.getElementById(el_id); var params = {}; params.env = 'filemanager'; - params.maxbytes = filemanager.maxbytes; - params.maxfiles = filemanager.maxfiles; - params.itemid = itemid; + params.itemid = options.itemid; + params.maxfiles = options.maxfiles; + params.maxbytes = options.maxbytes; + params.savepath = options.savepath; params.target = el; - params.callback = fp_callback; - var fp = open_filepicker(client_id, params); + params.callback = filemanager_callback; + var fp = open_filepicker(options.client_id, params); return false; } + +// create a new folder in draft area +function mkdir(client_id, itemid) { + var mkdir_cb = { + success: function(o) { + var result = json_decode(o.responseText); + fm_mkdir_dlg.hide(); + refresh_filemanager(result.filepath, fm_cfg[client_id]); + } + } + var perform = function(e) { + var foldername = document.getElementById('fm-newname').value; + if (!foldername) { + return; + } + var params = []; + params['itemid'] = itemid; + params['newdirname'] = foldername; + params['sesskey'] = moodle_cfg.sesskey; + params['filepath'] = fm_cfg[client_id].currentpath; + var trans = YAHOO.util.Connect.asyncRequest('POST', + filemanager.url+'?action=mkdir', mkdir_cb, build_querystring(params)); + YAHOO.util.Event.preventDefault(e); + } + if (!document.getElementById('fm-mkdir-dlg')) { + var el = document.createElement('DIV'); + el.id = 'fm-mkdir-dlg'; + el.innerHTML = '
    '+mstr.repository.entername+'
    '; + document.body.appendChild(el); + fm_mkdir_dlg = new YAHOO.widget.Dialog("fm-mkdir-dlg", { + width: "300px", + fixedcenter: true, + visible: true, + constraintoviewport : true + }); + + } + var buttons = [ { text:mstr.moodle.ok, handler:perform, isDefault:true }, + { text:mstr.moodle.cancel, handler:function(){this.cancel();}}]; + + fm_mkdir_dlg.cfg.queueProperty("buttons", buttons); + fm_mkdir_dlg.render(); + fm_mkdir_dlg.show(); + + var k1 = new YAHOO.util.KeyListener(document.getElementById('fm-mkdir-dlg'), {keys:13}, {fn:function(){perform();}, correctScope: true}); + k1.enable(); + + document.getElementById('fm-newname').value = ''; +} + +// generate html +function html_compiler(client_id, options) { + var list = options.list; + var breadcrumb = document.getElementById('fm-path-'+client_id); + var count = 0; + if (options.path) { + breadcrumb.innerHTML = ''; + var count = 0; + for(var p in options.path) { + count++; + var pathid = 'fm-path-node-'+client_id; + pathid += ('-'+count); + + var el = document.createElement('A'); + el.id = pathid; + el.innerHTML = options.path[p].name; + el.href = '###'; + var sep = document.createElement('SPAN'); + sep.innerHTML = ' ▶ '; + breadcrumb.appendChild(sep); + breadcrumb.appendChild(el); + + var args = {}; + args.itemid = options.itemid; + args.requestpath = options.path[p].path; + args.client_id = client_id; + + YAHOO.util.Event.addListener(pathid, 'click', click_breadcrumb, args); + } + } + var template = document.getElementById('fm-tmpl'); + var container = document.getElementById('filemanager-' + client_id); + var listhtml = '
      '; + + var folder_ids = []; + + var file_ids = []; + var file_data = {}; + var folder_data = {}; + var html_ids = []; + var html_data = {}; + var zip_data = {}; + file_data.itemid = folder_data.itemid = zip_data.itemid = options.itemid; + file_data.client_id = folder_data.client_id = zip_data.client_id = options.client_id; + + var zip_ids = []; + var foldername_ids = []; + if (list.length == 0) { + // hide file browser and breadcrumb + container.style.display='none'; + if (options.path.length <= 1) { + breadcrumb.style.display='none'; + } + return; + } else { + container.style.display='block'; + breadcrumb.style.display='block'; + } + count = 0; + for(var i in list) { + count++; + var htmlid = 'fileitem-'+client_id+'-'+count; + var fileid = 'filename-'+client_id+'-'+count; + var action = 'action-' +client_id+'-'+count; + var html = template.innerHTML; + + html_ids.push(htmlid); + html_data[htmlid] = action; + + list[i].htmlid = htmlid; + list[i].fileid = fileid; + list[i].action = action; + var url = "###"; + var ismainfile = false; + if (fm_cfg[client_id].mainfilename && (fm_cfg[client_id].mainfilename == list[i].fullname)) { + ismainfile = true; + } + switch (list[i].type) { + case 'folder': + foldername_ids.push(fileid); + folder_ids.push(action); + folder_data[action] = list[i]; + folder_data[fileid] = list[i]; + break; + case 'file': + file_ids.push(action); + file_data[action] = list[i]; + if (list[i].url) { + url = list[i].url; + } + break; + case 'zip': + zip_ids.push(action); + zip_data[action] = list[i]; + if (list[i].url) { + url = list[i].url; + } + break; + } + var fullname = list[i].fullname; + if (ismainfile) { + fullname = ""+list[i].fullname+" "; + } + html = html.replace('___fullname___', ' ' + fullname + ''); + html = html.replace('___action___', ''); + html = '
    • '+html+'
    • '; + listhtml += html; + } + container.innerHTML = (listhtml+'
    '); + + options.client_id=client_id; + + YAHOO.util.Event.addListener(file_ids, 'click', create_filemenu, file_data); + YAHOO.util.Event.addListener(folder_ids, 'click', create_foldermenu, folder_data); + YAHOO.util.Event.addListener(zip_ids, 'click', create_zipmenu, zip_data); + YAHOO.util.Event.addListener(html_ids, 'mouseover', fm_mouseover_menu, html_data); + YAHOO.util.Event.addListener(html_ids, 'mouseout', fm_mouseout_menu, html_data); + + YAHOO.util.Event.addListener(foldername_ids,'click', click_folder, folder_data); +} + +function fm_mouseover_menu(ev, args) { + this.style.backgroundColor = '#0066EE'; + var menu = args[this.id]; + menu = document.getElementById(menu); + menu.style.display = 'inline'; +} + +function fm_mouseout_menu(ev, args) { + this.style.backgroundColor = 'transparent'; + var menu = args[this.id]; + menu = document.getElementById(menu); + menu.style.display = 'none'; +} + +function click_breadcrumb(ev, args) { + var params = []; + params['itemid'] = args.itemid; + params['sesskey'] = moodle_cfg.sesskey; + params['filepath'] = args.requestpath; + this.cb = { + success: function(o) { + var data = json_decode(o.responseText); + for(var key in data) { + this.options[key] = data[key]; + } + html_compiler(this.client_id, this.options); + } + } + this.cb.options = args; + this.cb.client_id = args.client_id; + + fm_cfg[args.client_id].currentpath = args.requestpath; + fm_loading('filemanager-'+args.client_id, 'fm-prgressbar'); + var trans = YAHOO.util.Connect.asyncRequest('POST', + filemanager.url+'?action=list', this.cb, build_querystring(params)); +} + +function click_folder(ev, args) { + var file = args[this.id]; + refresh_filemanager(file.filepath, args); +} + +function refresh_filemanager(path, args) { + var params = []; + params['itemid'] = args.itemid; + params['filepath'] = path; + params['sesskey'] = moodle_cfg.sesskey; + this.cb = { + success: function(o) { + var data = json_decode(o.responseText); + for(var key in data) { + this.options[key] = data[key]; + } + html_compiler(this.client_id, this.options); + } + } + this.cb.options = args; + this.cb.client_id = args.client_id; + + fm_cfg[args.client_id].currentpath = params['filepath']; + fm_loading('filemanager-'+args.client_id, 'fm-prgressbar'); + var trans = YAHOO.util.Connect.asyncRequest('POST', + filemanager.url+'?action=list', this.cb, build_querystring(params)); +} + +function create_foldermenu(e, data) { + var file = data[this.id]; + this.zip = function(type, ev, obj) { + this.cb = { + success: function(o) { + var result = json_decode(o.responseText); + if (result) { + refresh_filemanager(result.filepath, fm_cfg[this.client_id]); + } + } + } + this.cb.client_id = obj.client_id; + this.cb.file = this.file; + var params = []; + params['itemid'] = obj.itemid; + params['filepath'] = this.file.filepath; + params['filename'] = '.'; + params['sesskey'] = moodle_cfg.sesskey; + fm_loading('filemanager-'+obj.client_id, 'fm-prgressbar'); + var trans = YAHOO.util.Connect.asyncRequest('POST', + filemanager.url+'?action=zip', this.cb, build_querystring(params)); + } + this.zip.file = file; + var menuitems = [ + {text: mstr.editor.zip, onclick: {fn: this.zip, obj: data, scope: this.zip}}, + ]; + create_menu(e, 'foldermenu', menuitems, file, data); +} + +function create_filemenu(e, data) { + var file = data[this.id]; + + var menuitems = [ + {text: mstr.moodle.download, url:file.url} + ]; + create_menu(e, 'filemenu', menuitems, file, data); +} + +function create_zipmenu(e, data) { + var file = data[this.id]; + this.unzip = function(type, ev, obj) { + this.cb = { + success:function(o) { + var result = json_decode(o.responseText); + if (result) { + refresh_filemanager(result.filepath, fm_cfg[this.client_id]); + } + } + } + this.cb.client_id = obj.client_id; + var params = []; + params['itemid'] = obj.itemid; + params['filepath'] = this.file.filepath; + params['filename'] = this.file.fullname; + params['sesskey'] = moodle_cfg.sesskey; + fm_loading('filemanager-'+obj.client_id, 'fm-prgressbar'); + var trans = YAHOO.util.Connect.asyncRequest('POST', + filemanager.url+'?action=unzip', this.cb, build_querystring(params)); + } + this.unzip.file = file; + + var menuitems = [ + {text: mstr.moodle.download, url:file.url}, + {text: mstr.moodle.unzip, onclick: {fn: this.unzip, obj: data, scope: this.unzip}} + ]; + create_menu(e, 'zipmenu', menuitems, file, data); +} + +function create_menu(ev, menuid, menuitems, file, options) { + var position = YAHOO.util.Event.getXY(ev); + var el = document.getElementById(menuid); + var menu = new YAHOO.widget.Menu(menuid, {xy:position}); + + this.remove = function(type, ev, obj) { + var args = {}; + args.message = mstr.repository.confirmdeletefile; + args.callback = function() { + var params = {}; + if (this.file.type == 'folder') { + params['filename'] = '.'; + params['filepath'] = this.file.fullname; + } else { + params['filename'] = this.file.fullname; + params['filepath'] = fm_cfg[this.client_id].currentpath; + } + params['itemid'] = this.itemid; + params['sesskey'] = moodle_cfg.sesskey; + fm_loading('filemanager-'+this.client_id, 'fm-prgressbar'); + var trans = YAHOO.util.Connect.asyncRequest('POST', + filemanager.url+'?action=delete', this.cb, build_querystring(params)); + } + var dlg = confirm_dialog(ev, args); + dlg.file = file; + dlg.client_id = obj.client_id; + dlg.itemid = obj.itemid; + dlg.cb = { + success: function(o) { + var result = json_decode(o.responseText); + if (!result) { + alert(mstr.error.cannotdeletefile); + } + fm_cfg[this.client_id].currentfiles--; + if (fm_cfg[this.client_id].currentfiles
    '; + document.body.appendChild(el); + fm_rename_dlg = new YAHOO.widget.Dialog("fm-rename-dlg", { + width: "300px", + fixedcenter: true, + visible: true, + constraintoviewport : true + }); + + } + var buttons = [ { text:mstr.moodle.rename, handler:perform, isDefault:true }, + { text:mstr.moodle.cancel, handler:function(){this.cancel();}}]; + + fm_rename_dlg.cfg.queueProperty("buttons", buttons); + fm_rename_dlg.render(); + fm_rename_dlg.show(); + + var k1 = new YAHOO.util.KeyListener(scope, {keys:13}, {fn:function(){perform();}, correctScope: true}); + k1.enable(); + + document.getElementById('fm-rename-input').value = file.fullname; + } + this.rename.file = file; + + this.move = function(type, ev, obj) { + var tree = new YAHOO.widget.TreeView("fm-tree"); + var file = this.file; + + this.asyncMove = function(e) { + if (!tree.targetpath) { + return; + } + var cb = { + success : function(o) { + var result = json_decode(o.responseText); + var p = '/'; + if (result) { + p = result.filepath; + } + refresh_filemanager(result.filepath, fm_cfg[obj.client_id]); + this.dlg.cancel(); + } + } + cb.dlg = this; + var params = {}; + if (file.type == 'folder') { + alert('Moving folder is not supported yet'); + return; + action = 'movedir'; + } else { + action = 'movefile'; + } + params['filepath'] = file.filepath; + params['filename'] = file.fullname; + params['itemid'] = obj.itemid; + params['sesskey'] = moodle_cfg.sesskey; + params['newfilepath'] = tree.targetpath; + fm_loading('filemanager-'+obj.client_id, 'fm-prgressbar'); + var trans = YAHOO.util.Connect.asyncRequest('POST', + filemanager.url+'?action='+action, cb, build_querystring(params)); + } + + var buttons = [ { text:mstr.moodle.move, handler:this.asyncMove, isDefault:true }, + { text:mstr.moodle.cancel, handler:function(){this.cancel();}}]; + + fm_move_dlg.cfg.queueProperty("buttons", buttons); + + + tree.subscribe("dblClickEvent", function(e) { + // update destidatoin folder + this.targetpath = e.node.data.path; + var el = document.getElementById('fm-move-div'); + el.innerHTML = '"' + this.targetpath + '" has been selected.'; + YAHOO.util.Event.preventDefault(e); + }); + + this.loadDataForNode = function(node, onCompleteCallback) { + this.cb = { + success: function(o) { + var data = json_decode(o.responseText); + data = data.children; + if (data.length == 0) { + // so it is empty + } else { + for (var i in data) { + var textnode = {label: data[i].fullname, path: data[i].filepath, itemid: this.itemid}; + var tmpNode = new YAHOO.widget.TextNode(textnode, node, false); + } + } + this.complete(); + } + } + var params = {}; + params['itemid'] = node.data.itemid; + params['filepath'] = node.data.path; + params['sesskey'] = moodle_cfg.sesskey; + var trans = YAHOO.util.Connect.asyncRequest('POST', + filemanager.url+'?action=dir', this.cb, build_querystring(params)); + this.cb.complete = onCompleteCallback; + this.cb.itemid = node.data.itemid; + } + this.loadDataForNode.itemid = obj.itemid; + + fm_move_dlg.subscribe('show', function(){ + + var el = document.getElementById('fm-move-div'); + el.innerHTML = '
    '+mstr.repository.nopathselected+'
    '; + + var rootNode = tree.getRoot(); + tree.setDynamicLoad(this.loadDataForNode); + tree.removeChildren(rootNode); + var textnode = {label: "Files", path: '/', itemid: obj.itemid}; + var tmpNode = new YAHOO.widget.TextNode(textnode, rootNode, true); + tree.draw(); + + }, this, true); + + fm_move_dlg.render(); + fm_move_dlg.show(); + } + this.move.file = file; + var shared_items = [ + {text: mstr.moodle.rename+'...', onclick: {fn: this.rename, obj: options, scope: this.rename}}, + {text: mstr.moodle.move+'...', onclick: {fn: this.move, obj: options, scope: this.move}}, + {text: mstr.moodle['delete']+'...', onclick: {fn: this.remove, obj: options, scope: this.remove}} + ]; + menu.addItems(menuitems); + menu.addItems(shared_items); + if (fm_cfg[options.client_id].mainfile && (file.type!='folder')) { + this.set_mainfile = function(type, ev, obj) { + if (fm_cfg[obj.client_id].mainfile) { + var mainfile = document.getElementById(fm_cfg[obj.client_id].mainfile); + mainfile.value = this.file.filepath+this.file.fullname; + //mainfile.disabled = true; + } + fm_cfg[obj.client_id].mainfilename = this.file.fullname; + refresh_filemanager(fm_cfg[obj.client_id].currentpath, fm_cfg[obj.client_id]); + } + this.set_mainfile.file = file; + menu.addItem({text: mstr.resource.setmainfile, onclick: {fn: this.set_mainfile, obj: options, scope: this.set_mainfile}}); + } + menu.render(document.body); + menu.show(); + menu.subscribe('hide', function(){ + this.destroy(); + }); +} + +function setup_filebrowser(client_id, options) { + if (!options) { + options = {}; + } + var fm = new filemanager(); + fm.init(client_id, options); + // XXX: When editing existing folder, currentfiles shouldn't + // be 0 + fm_cfg[client_id].currentfiles = 0; + fm_cfg[client_id].maxfiles = options.maxfiles; + setup_buttons(client_id, options); +} + +function setup_buttons(client_id, options) { + //var fileadd = new YAHOO.widget.Button("btnadd-"+client_id); + var fileadd = document.getElementById("btnadd-"+client_id);; + var foldercreate = document.getElementById("btncrt-"+client_id); + var folderdownload = document.getElementById("btndwn-"+client_id); + + var el = null; + if (!fm_move_dlg) { + el = document.createElement('DIV'); + el.id = 'fm-move-dlg'; + document.body.appendChild(el); + fm_move_dlg = new YAHOO.widget.Dialog("fm-move-dlg", { + width : "600px", + fixedcenter : true, + visible : false, + constraintoviewport : true + }); + } else { + el = document.getElementById('fm-move-div'); + } + + el.innerHTML = '
    '+mstr.repository.nopathselected+'
    '; + + fm_move_dlg.render(); + + fileadd.onclick = function(e) { + this.options.savepath = this.options.currentpath; + fm_launch_filepicker(this.options.target, this.options); + } + fileadd.options = fm_cfg[client_id]; + foldercreate.onclick = function() { + mkdir(this.options.client_id, this.options.itemid); + } + foldercreate.options = fm_cfg[client_id]; + folderdownload.onclick = function() { + var cb = { + success:function(o) { + var result = json_decode(o.responseText); + refresh_filemanager(result.filepath, fm_cfg[this.client_id]); + var win = window.open(result.fileurl, 'fm-download-folder'); + if (!win) { + alert(mstr.repository.popupblockeddownload); + } + } + }; + cb.client_id = this.options.client_id; + var params = []; + params['itemid'] = this.options.itemid; + params['sesskey'] = moodle_cfg.sesskey; + params['filepath'] = this.options.currentpath; + var trans = YAHOO.util.Connect.asyncRequest('POST', + filemanager.url+'?action=downloaddir', cb, build_querystring(params)); + } + folderdownload.options = fm_cfg[client_id]; +} + +function fm_loading(container, id) { + + if (!document.getElementById(id)) { + var el = document.createElement('DIV'); + el.id = id; + el.style.backgroundColor = "white"; + var container = document.getElementById(container); + container.innerHTML = ''; + container.appendChild(el); + } + + var loading = new YAHOO.widget.Module(id, {visible:false}); + loading.setBody('
    '+mstr.repository.loading+'
    '); + loading.render(); + loading.show(); + + return loading; +} diff --git a/lib/form/filemanager.php b/lib/form/filemanager.php index cc847d7e4b..6500cdb2a6 100644 --- a/lib/form/filemanager.php +++ b/lib/form/filemanager.php @@ -1,4 +1,27 @@ . + +/** + * File manager + * + * @package moodlecore + * @subpackage file + * @copyright 1999 onwards Dongsheng Cai + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ global $CFG; @@ -7,12 +30,17 @@ require_once($CFG->dirroot.'/lib/filelib.php'); class MoodleQuickForm_filemanager extends HTML_QuickForm_element { public $_helpbutton = ''; - protected $_options = array('subdirs'=>0, 'maxbytes'=>0, 'maxfiles'=>-1, 'filetypes'=>'*', 'returnvalue'=>'*'); + protected $_options = array('mainfile'=>'', 'subdirs'=>0, 'maxbytes'=>0, 'maxfiles'=>-1, 'filetypes'=>'*', 'returnvalue'=>'*'); function MoodleQuickForm_filemanager($elementName=null, $elementLabel=null, $attributes=null, $options=null) { - global $CFG; + global $CFG, $PAGE; require_once("$CFG->dirroot/repository/lib.php"); + // has to require these js files before head + $PAGE->requires->yui_lib('menu'); + $PAGE->requires->yui_lib('connection'); + $PAGE->requires->yui_lib('json'); + $options = (array)$options; foreach ($options as $name=>$value) { if (array_key_exists($name, $this->_options)) { @@ -22,6 +50,8 @@ class MoodleQuickForm_filemanager extends HTML_QuickForm_element { if (!empty($options['maxbytes'])) { $this->_options['maxbytes'] = get_max_upload_file_size($CFG->maxbytes, $options['maxbytes']); } + // XXX: hide element lable + $elementLabel = ''; parent::HTML_QuickForm_element($elementName, $elementLabel, $attributes); repository_head_setup(); @@ -95,47 +125,10 @@ class MoodleQuickForm_filemanager extends HTML_QuickForm_element { } } - function _get_draftfiles($draftid, $suffix) { - global $USER, $OUTPUT, $CFG; - - $context = get_context_instance(CONTEXT_USER, $USER->id); - $fs = get_file_storage(); - - $html = '
      '; - - if ($files = $fs->get_directory_files($context->id, 'user_draft', $draftid, '/', true)) { - foreach ($files as $file) { - if ($file->is_directory()) { - continue; - } - $filename = $file->get_filename(); - $filepath = $file->get_filepath(); - $fullname = ltrim($filepath.$filename, '/'); - $filesize = $file->get_filesize(); - $filesize = $filesize ? display_size($filesize) : ''; - $icon = mimeinfo_from_type('icon', $file->get_mimetype()); - $icon = str_replace('.gif', '', $icon); //TODO: temp icon fix - $viewurl = file_encode_url("$CFG->wwwroot/draftfile.php", "/$context->id/user_draft/$draftid/".$fullname, false, false); - $html .= '
    • '; - $html .= "old_icon_url('f/' . $icon) . "\" class=\"icon\" /> ".s($fullname)." ($filesize) "; - // TODO: maybe better use file->id here - but then make 100% it is from my own draftfiles ;-) - // anyway this does not work for subdirectories - $html .= "old_icon_url('t/delete') . "\" class=\"iconsmall\" />";; - $html .= '
    • '; - } - } - - $html .= '
    '; - return $html; - } - function toHtml() { global $CFG, $USER, $COURSE, $PAGE, $OUTPUT; require_once("$CFG->dirroot/repository/lib.php"); - $strdelete = get_string('confirmdeletefile', 'repository'); - $straddfile = get_string('add', 'repository'); - // security - never ever allow guest/not logged in user to upload anything or use this element! if (isguestuser() or !isloggedin()) { print_error('noguest'); @@ -151,6 +144,33 @@ class MoodleQuickForm_filemanager extends HTML_QuickForm_element { $maxbytes = $this->_options['maxbytes']; $draftitemid = $this->getValue(); + // language strings + $straddfile = get_string('add', 'repository') . '...'; + $strmakedir = get_string('makeafolder', 'moodle'); + $strdownload = get_string('downloadfolder', 'repository'); + + $PAGE->requires->string_for_js('loading', 'repository'); + $PAGE->requires->string_for_js('nomorefiles', 'repository'); + $PAGE->requires->string_for_js('confirmdeletefile', 'repository'); + $PAGE->requires->string_for_js('add', 'repository'); + $PAGE->requires->string_for_js('accessiblefilepicker', 'repository'); + $PAGE->requires->string_for_js('move', 'moodle'); + $PAGE->requires->string_for_js('cancel', 'moodle'); + $PAGE->requires->string_for_js('download', 'moodle'); + $PAGE->requires->string_for_js('ok', 'moodle'); + $PAGE->requires->string_for_js('emptylist', 'repository'); + $PAGE->requires->string_for_js('entername', 'repository'); + $PAGE->requires->string_for_js('enternewname', 'repository'); + $PAGE->requires->string_for_js('zip', 'editor'); + $PAGE->requires->string_for_js('unzip', 'moodle'); + $PAGE->requires->string_for_js('rename', 'moodle'); + $PAGE->requires->string_for_js('delete', 'moodle'); + $PAGE->requires->string_for_js('setmainfile', 'resource'); + $PAGE->requires->string_for_js('cannotdeletefile', 'error'); + $PAGE->requires->string_for_js('confirmdeletefile', 'repository'); + $PAGE->requires->string_for_js('nopathselected', 'repository'); + $PAGE->requires->string_for_js('popupblockdownload', 'repository'); + if (empty($draftitemid)) { // no existing area info provided - let's use fresh new draft area require_once("$CFG->libdir/filelib.php"); @@ -165,32 +185,59 @@ class MoodleQuickForm_filemanager extends HTML_QuickForm_element { } $client_id = uniqid(); + + // Generate file picker $repojs = repository_get_client($context, $client_id, $this->_options['filetypes'], $this->_options['returnvalue']); + $result = new stdclass; + + $options = file_get_draft_area_files($draftitemid); + $options->mainfile = $this->_options['mainfile']; + $options->maxbytes = $this->getMaxbytes(); + $options->maxfiles = $this->getMaxfiles(); + $options->client_id = $client_id; + $options->itemid = $draftitemid; + $options->target = $id; + + $html = $this->_getTabs(); + $html .= $repojs; - $html = $this->_get_draftfiles($draftitemid, $client_id); - $accessiblefp = get_string('accessiblefilepicker', 'repository'); - - $str = $this->_getTabs(); - $str .= $html; - $str .= $repojs; - $str .= << -$straddfile -EOD; - $PAGE->requires->yui_lib('dom'); - $PAGE->requires->string_for_js('nomorefiles', 'repository'); - $PAGE->requires->js_function_call('YAHOO.util.Dom.setStyle', Array("btnadd-{$client_id}", 'display', 'inline')); if (empty($CFG->filemanagerjsloaded)) { - $jsvars = Array('clientid' => $client_id, - 'strdelete' => $strdelete, - 'maxbytes' => $this->_options['maxbytes'], - 'maxfiles' => $this->_options['maxfiles'], - 'deleteicon' => $OUTPUT->old_icon_url('t/delete')); - $str .= $PAGE->requires->data_for_js('filemanager', $jsvars)->asap(); - $str .= $PAGE->requires->js('lib/form/filemanager.js')->asap(); + $PAGE->requires->js('lib/form/filemanager.js'); $CFG->filemanagerjsloaded = true; + // print html template + $html .= <<