]> git.mjollnir.org Git - moodle.git/commitdiff
" MDL-16597, ajax file manager element"
authordongsheng <dongsheng>
Thu, 17 Sep 2009 08:47:23 +0000 (08:47 +0000)
committerdongsheng <dongsheng>
Thu, 17 Sep 2009 08:47:23 +0000 (08:47 +0000)
files/files_ajax.php [new file with mode: 0755]
lib/filelib.php
lib/form/filemanager.js
lib/form/filemanager.php
theme/standard/styles_layout.css

diff --git a/files/files_ajax.php b/files/files_ajax.php
new file mode 100755 (executable)
index 0000000..334460c
--- /dev/null
@@ -0,0 +1,197 @@
+<?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/>.
+
+/**
+ * File manager
+ *
+ * @package    moodlecore
+ * @subpackage file
+ * @copyright  1999 onwards Dongsheng Cai <dongsheng@moodle.com>
+ * @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;
+}
index 745c8b3da72ba6bdd7677226a906cbe7df2895a6..dadb5f2e03c9b677313127dfb3377f6f8191aca6 100644 (file)
@@ -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;
 }
index 0fcd96309c54604de989d5c5c5c7c059763f8eae..6db26cf09ca9f66c352316399b42c9c5042034c3 100644 (file)
-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 <dongsheng@moodle.com>
+ * @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 = '<li><a href="'+obj['url']+'"><img src="'+obj['icon']+'" class="icon" /> '+obj['file']+'</a> ';
-    html += '<a href="###" onclick=\'rm_file('+obj['id']+', "'+obj['file']+'", this)\'><img src="'+filemanager.deleteicon+'" class="iconsmall" /></a>';
-    html += '</li>';
-    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 = '<div class="hd">'+mstr.repository.entername+'</div><div class="bd"><input type="text" id="fm-newname" /></div>';
+        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 = '<ul id="draftfiles-'+client_id+'">';
+
+    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 = "<strong>"+list[i].fullname+"</strong> <img src='"+moodle_cfg.wwwroot+"/pix/i/tick_green_small.gif"+"' />";
+        }
+        html = html.replace('___fullname___', '<a href="'+url+'" id="'+fileid+'"><img src="'+list[i].icon+'" /> ' + fullname + '</a>');
+        html = html.replace('___action___', '<a style="display:none" href="###" id="'+action+'"><img alt="▶" src="'+filemanager.fileicon+'" /></a>');
+        html = '<li id="'+htmlid+'">'+html+'</li>';
+        listhtml += html;
+    }
+    container.innerHTML = (listhtml+'</ul>');
+
+    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<fm_cfg[this.client_id].maxfiles) {
+                    var btn = document.getElementById('btnadd-'+this.client_id);
+                    btn.style.display = 'inline';
+                }
+                refresh_filemanager(result.filepath, fm_cfg[this.client_id]);
+            }
+        }
+        dlg.cb.file = this.file;
+        dlg.cb.client_id = obj.client_id;
+    }
+    this.remove.file = file;
+
+    this.rename = function(type, ev, obj) {
+        var file = this.file;
+        var rename_cb = {
+            success: function(o) {
+                var result = json_decode(o.responseText);
+                if (result) {
+                    var el = document.getElementById(file.fileid);
+                    el.innerHTML = this.newfilename;
+                    // update filename
+                    file.fullname = this.newfilename;
+                    file.filepath = result.filepath;
+                    fm_rename_dlg.hide();
+                }
+            }
+        }
+        var perform = function(e) {
+            var newfilename = document.getElementById('fm-rename-input').value;
+            if (!newfilename) {
+                return;
+            }
+
+            var action = '';
+            var params = [];
+            params['itemid'] = obj.itemid;
+            if (file.type == 'folder') {
+                params['filepath']   = file.filepath;
+                params['filename']   = '.';
+                action = 'renamedir';
+            } else {
+                params['filepath']   = file.filepath;
+                params['filename']   = file.fullname;
+                action = 'rename';
+            }
+            params['newfilename'] = newfilename;
+
+            params['sesskey'] = moodle_cfg.sesskey;
+            rename_cb.newfilename = newfilename;
+            var trans = YAHOO.util.Connect.asyncRequest('POST',
+                filemanager.url+'?action='+action, rename_cb, build_querystring(params));
+        }
+
+        var scope = document.getElementById('fm-rename-dlg');
+        if (!scope) {
+            var el = document.createElement('DIV');
+            el.id = 'fm-rename-dlg';
+            el.innerHTML = '<div class="hd">'+mstr.repository.enternewname+'</div><div class="bd"><input type="text" id="fm-rename-input" /></div>';
+            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 = '<strong>"' + this.targetpath + '"</strong> 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 = '<div class="hd"></div><div class="bd"><div id="fm-move-div">'+mstr.repository.nopathselected+'</div><div id="fm-tree"></div></div>';
+
+            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 = '<div class="hd"></div><div class="bd"><div id="fm-move-div">'+mstr.repository.nopathselected+'</div><div id="fm-tree"></div></div>';
+
+    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('<div style="text-align:center"><img alt="'+mstr.repository.loading+'" src="'+moodle_cfg.wwwroot+'/pix/i/progressbar.gif" /></div>');
+    loading.render();
+    loading.show();
+
+    return loading;
+}
index cc847d7e4b04ce78687890e6d6b3a4c9e3f9bb03..6500cdb2a65f61b6a09a2de0fff64723566003f6 100644 (file)
@@ -1,4 +1,27 @@
 <?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/>.
+
+/**
+ * File manager
+ *
+ * @package    moodlecore
+ * @subpackage file
+ * @copyright  1999 onwards Dongsheng Cai <dongsheng@moodle.com>
+ * @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 = '<ul class="file-list" id="draftfiles-'.$suffix.'">';
-
-        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 .= '<li>';
-                $html .= "<a href=\"$viewurl\"><img src=\"" . $OUTPUT->old_icon_url('f/' . $icon) . "\" class=\"icon\" />&nbsp;".s($fullname)." ($filesize)</a> ";
-                // 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 .= "<a href=\"###\" onclick='rm_file(".$file->get_itemid().", \"".addslashes_js($fullname)."\", this)'><img src=\"" . $OUTPUT->old_icon_url('t/delete') . "\" class=\"iconsmall\" /></a>";;
-                $html .= '</li>';
-            }
-        }
-        
-        $html .= '</ul>';
-        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 .= <<<EOD
-<input value="$draftitemid" name="{$this->_attributes['name']}" type="hidden" />
-<a href="###" id="btnadd-{$client_id}" class="btnaddfile" onclick="return callpicker('$id', '$client_id', '$draftitemid')">$straddfile</a>
-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 .= <<<FMHTML
+<div id="fm-tmpl" style="display:none"><div class="fm-file-menu">___action___</div> <div class="fm-file-name">___fullname___</div></div>
+FMHTML;
         }
-        return $str;
+
+        $html .= <<<FMHTML
+<input value="$draftitemid" name="{$elname}" type="hidden" />
+<div id="filemanager-wrapper-{$client_id}" style="display:none">
+    <div class="fm-breadcrumb" id="fm-path-{$client_id}"></div>
+    <div class="filemanager-toolbar">
+        <a href="###" id="btnadd-{$client_id}">{$straddfile}</a>
+        <a href="###" id="btncrt-{$client_id}">{$strmakedir}</a>
+        <a href="###" id="btndwn-{$client_id}">{$strdownload}</a>
+    </div>
+
+    <div class="filemanager-container" id="filemanager-{$client_id}">
+        <ul id="draftfiles-{$client_id}">
+            <li>Loading...</li>
+        </ul>
+    </div>
+</div>
+FMHTML;
+        // non-javascript file manager, will be destroied automatically if javascript is enabled.
+        $html .= '<div id="nonjs-filemanager-'.$client_id.'">';
+        $editorurl = "$CFG->wwwroot/repository/filepicker.php?env=filemanager&amp;action=embedded&amp;itemid=$draftitemid&amp;subdirs=/&amp;maxbytes=$options->maxbytes&amp;ctx_id=".$context->id;
+        $html .= '<object type="text/html" data="'.$editorurl.'" height="160" width="600" style="border:1px solid #000">Error</object>';
+        $html .= '</div>';
+
+        $html .= $PAGE->requires->js_function_call('destroy_item', array("nonjs-filemanager-{$client_id}"))->asap();
+        $html .= $PAGE->requires->js_function_call('show_item', array("filemanager-wrapper-{$client_id}"))->asap();
+        $PAGE->requires->js_function_call('setup_filebrowser', array($client_id, $options))->on_dom_ready();
+
+        return $html;
     }
 
 }
index 3ca592a4f48cc02822c5c4eac47f13d0983f363f..66e1fcf8efa50074c0d06780861ad6f946fce084 100644 (file)
@@ -5843,3 +5843,51 @@ wikiadminactions {
   left:-10px;
   background-position:0px 100%;
 }
+.filemanager-toolbar{
+    margin: 5px 0;
+}
+.filemanager-toolbar a{
+    border: 1px solid grey;
+    padding: 3px;
+}
+.filemanager-toolbar a:hover {
+    background: #CCC;
+}
+.fm-breadcrumb {
+    margin: 6px 0;
+}
+.filemanager-container {
+    padding: 5px;
+    margin: 6px 0;
+}
+.filemanager-container ul{
+    margin:0;
+    padding:0;
+    list-style-type:none;
+}
+.filemanager-container li{
+    clear:both;
+}
+#fm-move-div {
+    margin: 6px;
+}
+#fm-move-div strong{
+    color:red;
+}
+.fm-file-menu {
+    width: 18px;
+    height: 18px;
+    float: left;
+}
+.fm-file-menu img {
+    width: 16px;
+}
+.fm-file-name {
+    float:left;
+}
+.fm-file-entry{
+    border: 1px solid red;
+}
+.fm-operation {
+    font-weight: bold;
+}