diff --git a/lib/editor/tinymce/tinymce.js.php b/lib/editor/tinymce/tinymce.js.php index 8ef02b279c7..eb160e542a6 100644 --- a/lib/editor/tinymce/tinymce.js.php +++ b/lib/editor/tinymce/tinymce.js.php @@ -92,14 +92,14 @@ $output .= <<context; } - $ret = repository_get_client($ctx, array('image', 'video', 'media'), '*'); + $client_id = uniqid(); + $ret = repository_get_client($ctx, $client_id, array('image', 'video', 'media'), '*'); - $suffix = $ret['suffix']; $str .= $ret['css'].$ret['js']; $str .= << -id2suffix['$id']='$suffix'; -id2itemid['$id']='$draftitemid'; +id2clientid['$id'] = '$client_id'; +id2itemid['$id'] = '$draftitemid'; EOD; diff --git a/lib/form/filemanager.php b/lib/form/filemanager.php index 8b547181119..81acd13d4cc 100644 --- a/lib/form/filemanager.php +++ b/lib/form/filemanager.php @@ -171,57 +171,67 @@ class MoodleQuickForm_filemanager extends HTML_QuickForm_element { $context = get_context_instance(CONTEXT_COURSE, $COURSE->id); } - $repo_info = repository_get_client($context, $this->filetypes, $this->returnvalue); - $suffix = $repo_info['suffix']; + $client_id = uniqid(); + $repo_info = repository_get_client($context, $client_id, $this->filetypes, $this->returnvalue); - $html = $this->_get_draftfiles($draftitemid, $suffix); + $html = $this->_get_draftfiles($draftitemid, $client_id); $str = $this->_getTabs(); $str .= $html; $str .= $repo_info['css']; $str .= $repo_info['js']; - $str .= <<filemanagerjsloaded)) { + $str .= << //httpswwwroot}/repository/ws.php?action=delete&itemid='+id, - rm_cb_$suffix, + rm_cb, 'title='+name ); elitem = context.parentNode; } } -function uf_$suffix(obj) { - var list = document.getElementById('draftfiles-$suffix'); +function uf(obj) { + var list = document.getElementById('draftfiles-'+obj.client_id); var html = '
  • '+obj['file']+' '; - html += '';; + html += '';; html += '
  • '; list.innerHTML += html; } -function callpicker_$suffix() { +function callpicker(el_id, client_id, itemid) { document.body.className += ' yui-skin-sam'; var picker = document.createElement('DIV'); - picker.id = 'file-picker-$suffix'; + picker.id = 'file-picker-'+client_id; picker.className = 'file-picker'; document.body.appendChild(picker); - var el=document.getElementById('$id'); - openpicker_$suffix({'env':'filemanager', 'target':el, 'itemid': $draftitemid, 'callback':uf_$suffix}) + var el=document.getElementById(el_id); + var obj = {}; + obj.env = 'filemanager'; + obj.itemid = itemid; + obj.target = el; + obj.callback = uf; + var fp = open_filepicker(client_id, obj); } //]]> +EOD; + $CFG->filemanagerjsloaded = true; + } + $str .= <<
    - +
    EOD; return $str; diff --git a/lib/form/filepicker.php b/lib/form/filepicker.php index c4878311bd8..93f809789ea 100644 --- a/lib/form/filepicker.php +++ b/lib/form/filepicker.php @@ -72,8 +72,8 @@ class MoodleQuickForm_filepicker extends HTML_QuickForm_input { } else { $context = get_context_instance(CONTEXT_COURSE, $COURSE->id); } - $repository_info = repository_get_client($context, $this->filetypes, $this->returnvalue); - $suffix = $repository_info['suffix']; + $client_id = uniqid(); + $repository_info = repository_get_client($context, $client_id, $this->filetypes, $this->returnvalue); $id = $this->_attributes['id']; $elname = $this->_attributes['name']; @@ -83,21 +83,21 @@ class MoodleQuickForm_filepicker extends HTML_QuickForm_input { $str .= << -function updatefile_$suffix(obj) { - document.getElementById('repo_info_$suffix').innerHTML = obj['file']; +function updatefile(client_id, obj) { + document.getElementById('repo_info_'+client_id).innerHTML = obj['file']; } -function callpicker_$suffix() { +function callpicker(client_id, id) { document.body.className += ' yui-skin-sam'; var picker = document.createElement('DIV'); - picker.id = 'file-picker-$suffix'; + picker.id = 'file-picker-'+client_id; picker.className = 'file-picker'; document.body.appendChild(picker); - var el=document.getElementById('$id'); - openpicker_$suffix({'env':'filepicker', 'target':el, 'callback':updatefile_$suffix}) + var el=document.getElementById(id); + open_filepicker({'env':'filepicker', 'target':el, 'callback':updatefile}) } EOD; - $str .= ''.''.$currentfile.''.$repository_info['css'].$repository_info['js']; + $str .= ''.''.$currentfile.''.$repository_info['css'].$repository_info['js']; return $str; } diff --git a/lib/javascript.php b/lib/javascript.php index 776392ce4e3..5c16f7c94f3 100644 --- a/lib/javascript.php +++ b/lib/javascript.php @@ -28,8 +28,8 @@ setTimeout('fix_column_widths()', 20); -EOD; -return array('css'=>$css, 'js'=>$js, 'suffix'=>$suffix); -} diff --git a/repository/lib.php b/repository/lib.php index 28ec806ec61..26ae869d282 100644 --- a/repository/lib.php +++ b/repository/lib.php @@ -42,7 +42,6 @@ require_once(dirname(dirname(__FILE__)) . '/config.php'); require_once(dirname(dirname(__FILE__)) . '/lib/filelib.php'); require_once(dirname(dirname(__FILE__)) . '/lib/formslib.php'); // File picker javascript code -require_once(dirname(dirname(__FILE__)) . '/repository/javascript.php'); /** * A repository_type is a repository plug-in. It can be Box.net, Flick-r, ... @@ -1830,3 +1829,174 @@ function repository_setup_default_plugins() { } return true; } +/** + * Return javascript to create file picker to browse repositories + * @global object $CFG + * @global object $USER + * @param object $context the context + * @param string $id unique id for every file picker + * @param string $accepted_filetypes + * @param string $returnvalue the return value of file picker + * @return array + */ +function repository_get_client($context, $id = '', $accepted_filetypes = '*', $returnvalue = '*') { + global $CFG, $USER; + + $ft = new file_type_to_ext(); + $image_file_ext = json_encode($ft->get_file_ext(array('image'))); + $video_file_ext = json_encode($ft->get_file_ext(array('video'))); + $accepted_file_ext = json_encode($ft->get_file_ext($accepted_filetypes)); + + $css = ''; + $js = ''; + if (!isset($CFG->filepickerjsloaded)) { + $css .= << +@import "$CFG->httpswwwroot/lib/yui/resize/assets/skins/sam/resize.css"; +@import "$CFG->httpswwwroot/lib/yui/container/assets/skins/sam/container.css"; +@import "$CFG->httpswwwroot/lib/yui/layout/assets/skins/sam/layout.css"; +@import "$CFG->httpswwwroot/lib/yui/button/assets/skins/sam/button.css"; +@import "$CFG->httpswwwroot/lib/yui/assets/skins/sam/treeview.css"; + + + + +EOD; + + require_js(array( + 'yui_yahoo', + 'yui_dom', + 'yui_event', + 'yui_element', + 'yui_treeview', + 'yui_dragdrop', + 'yui_container', + 'yui_resize', + 'yui_layout', + 'yui_connection', + 'yui_json', + 'yui_button', + 'yui_selector', + 'repository/repository.js' + )); + $lang = array(); + $lang['title'] = get_string('title', 'repository'); + $lang['preview'] = get_string('preview', 'repository'); + $lang['add'] = get_string('add', 'repository'); + $lang['back'] = get_string('back', 'repository'); + $lang['cancel'] = get_string('cancel'); + $lang['close'] = get_string('close', 'repository'); + $lang['ccache'] = get_string('cleancache', 'repository'); + $lang['copying'] = get_string('copying', 'repository'); + $lang['downbtn'] = get_string('getfile', 'repository'); + $lang['download'] = get_string('downloadsucc', 'repository'); + $lang['date'] = get_string('date', 'repository').': '; + $lang['error'] = get_string('error', 'repository'); + $lang['filenotnull'] = get_string('filenotnull', 'repository'); + $lang['federatedsearch'] = get_string('federatedsearch', 'repository'); + $lang['help'] = get_string('help'); + $lang['refresh'] = get_string('refresh', 'repository'); + $lang['invalidjson'] = get_string('invalidjson', 'repository'); + $lang['listview'] = get_string('listview', 'repository'); + $lang['login'] = get_string('login', 'repository'); + $lang['logout'] = get_string('logout', 'repository'); + $lang['loading'] = get_string('loading', 'repository'); + $lang['thumbview'] = get_string('thumbview', 'repository'); + $lang['title'] = get_string('title', 'repository'); + $lang['noresult'] = get_string('noresult', 'repository'); + $lang['mgr'] = get_string('manageurl', 'repository'); + $lang['noenter'] = get_string('noenter', 'repository'); + $lang['save'] = get_string('save', 'repository'); + $lang['saveas'] = get_string('saveas', 'repository').': '; + $lang['saved'] = get_string('saved', 'repository'); + $lang['saving'] = get_string('saving', 'repository'); + $lang['size'] = get_string('size', 'repository').': '; + $lang['sync'] = get_string('sync', 'repository'); + $lang['search'] = get_string('search', 'repository'); + $lang['searching'] = get_string('searching', 'repository'); + $lang['submit'] = get_string('submit', 'repository'); + $lang['preview'] = get_string('preview', 'repository'); + $lang['popup'] = get_string('popup', 'repository'); + $lang['upload'] = get_string('upload', 'repository').'...'; + $lang['uploading'] = get_string('uploading', 'repository'); + // XXX fp_lang includes language strings + $js .= print_js_config($lang, 'fp_lang', true); + + $options = array(); + $context = get_system_context(); + $options['contextid'] = $context->id; + // XXX fp_config includes filepicker options, including contextid + $js .= print_js_config($options, 'fp_config', true); + + $accepted_file_ext = json_encode($ft->get_file_ext($accepted_filetypes)); + $js .= << + file_extensions.image = $image_file_ext; + file_extensions.media = $video_file_ext; + +EOD; + + $CFG->filepickerjsloaded = true; + } else { + // if yui and repository javascript libs are loaded + $js = ''; + } + + // print instances listing + $user_context = get_context_instance(CONTEXT_USER, $USER->id); + if (is_array($accepted_filetypes) && in_array('*', $accepted_filetypes)) { + $accepted_filetypes = '*'; + } + $repos = repository::get_instances(array($user_context, $context, get_system_context()), null, true, null, $accepted_filetypes, $returnvalue); + $js .= << + repository_listing['$id'] = {}; +EOD; + foreach ($repos as $repo) { + $info = $repo->ajax_info(); + $js .= "\r\n"; + $js .= 'repository_listing[\''.$id.'\'][\''.$info->id.'\']='.json_encode($repo->ajax_info()).';'; + $js .= "\n"; + } + $js .= "\r\n"; + $js .= ""; + + return array('css'=>$css, 'js'=>$js); +} diff --git a/repository/repository.js b/repository/repository.js new file mode 100644 index 00000000000..17c5908b177 --- /dev/null +++ b/repository/repository.js @@ -0,0 +1,974 @@ +// $Id$ +/////////////////////////////////////////////////////////////////////////// +// // +// Don't modify this file unless you know how it works // +// // +/////////////////////////////////////////////////////////////////////////// +/** + * repository_client is a javascript class, it contains several static + * methods you can call it directly without creating an instance. + * If you are going to create a file picker, you need create an instance + * repo = new repository_client(); + + */ + +var repository_listing = {}; +var active_instances = {}; +var file_extensions = {}; +// repository_client has static functions +var repository_client = (function(){ + // private static field + var version = '2.0'; + var PANEL_BODY_PADDING = (10*2); + // private static methods + function help() { + alert(version); + } + // a hack to fix ie6 bug + function ie6_fix_width(id, width) { + if(YAHOO.env.ua.ie == 6){ + var fp_title = document.getElementById('file-picker-'+id); + fp_title.style.width = width; + } + } + function $() { + // public methods of filepicker instance + this.create_filepicker = function(client_id) { + var IE_QUIRKS = (YAHOO.env.ua.ie && document.compatMode == "BackCompat"); + var IE_SYNC = (YAHOO.env.ua.ie == 6 || (YAHOO.env.ua.ie == 7 && IE_QUIRKS)); + var btn_listing = {label: fp_lang.listview, value: 'l', + onclick: {fn: repository_client.view_as_list, obj:client_id}}; + var btn_icons = {label: fp_lang.thumbview, value: 't', + onclick: {fn: repository_client.view_as_icons, obj:client_id}}; + document.body.className += ' yui-skin-sam'; + var el = document.createElement('DIV'); + el.id = 'file-picker-'+client_id; + el.className = 'file-picker'; + this.client_id = client_id; + document.body.appendChild(el); + this.filepicker = new YAHOO.widget.Panel('file-picker-' + client_id, { + draggable: true, + close: true, + underlay: 'none', + zindex: 666666, + xy: [50, YAHOO.util.Dom.getDocumentScrollTop()+20] + }); + var layout = ''; + this.filepicker.client_id = client_id; + this.filepicker.setHeader(fp_lang['title']); + this.filepicker.setBody('
    '); + this.filepicker.beforeRenderEvent.subscribe(function() { + YAHOO.util.Event.onAvailable('layout-'+client_id, function() { + layout = new YAHOO.widget.Layout('layout-'+client_id, { + height: 480, width: 700, + units: [ + {position: 'top', height: 32, resize: false, + body:'
    ', gutter: '2'}, + {position: 'left', width: 200, resize: true, scroll:true, + body:'
      ', gutter: '0 5 0 2', minWidth: 150, maxWidth: 300 }, + {position: 'center', body: '
      ', + scroll: true, gutter: '0 2 0 0' } + ] + }); + layout.render(); + }); + }); + var resize = new YAHOO.util.Resize('file-picker-'+client_id, { + handles: ['br'], + autoRatio: true, + status: true, + minWidth: 680, + minHeight: 400 + }); + ie6_fix_width(client_id, '680px'); + resize.on('resize', function(args) { + var panelHeight = args.height; + var headerHeight = this.header.offsetHeight; // Content + Padding + Border + var bodyHeight = (panelHeight - headerHeight); + var bodyContentHeight = (IE_QUIRKS) ? bodyHeight : bodyHeight - PANEL_BODY_PADDING; + YAHOO.util.Dom.setStyle(this.body, 'height', bodyContentHeight + 'px'); + ie6_fix_width(this.client_id, '680px'); + if (IE_SYNC) { + this.sizeUnderlay(); + this.syncIframe(); + } + layout.set('height', bodyContentHeight); + layout.set('width', (args.width - PANEL_BODY_PADDING)); + layout.resize(); + }, this.filepicker, true); + repository_client.fp[client_id].viewbar = new YAHOO.widget.ButtonGroup({ + id: 'btngroup-'+client_id, + name: 'buttons', + disabled: true, + container: 'repo-viewbar-'+client_id + }); + repository_client.fp[client_id].viewbar.addButtons([btn_icons, btn_listing]); + this.print_listing(); + this.filepicker.render(); + } + this.print_listing = function() { + var container = new YAHOO.util.Element('repo-list-'+this.client_id); + container.set('innerHTML', ''); + container.on('contentReady', function() { + for(var i in repository_listing[this.client_id]) { + var repo = repository_listing[this.client_id][i]; + var support = false; + if(this.env=='editor' && this.accepted_types != '*'){ + if(repo.supported_types!='*'){ + for (var j in repo.supported_types){ + if(mdl_in_array(repo.supported_types[j], this.accepted_types)){ + support = true; + } + } + } + }else{ + support = true; + } + if(repo.supported_types == '*' || support){ + var li = document.createElement('li'); + li.id = 'repo-'+this.client_id+'-'+repo.id; + var icon = document.createElement('img'); + icon.src = repo.icon; + icon.width = '16'; + icon.height = '16'; + var link = document.createElement('a'); + link.href = '###'; + link.id = 'repo-call-'+this.client_id+'-'+repo.id; + link.appendChild(icon); + link.className = 'fp-repo-name'; + link.innerHTML += ' '+repo.name; + link.onclick = function() { + var re = new RegExp("repo-call-(\\w+)-(\\d+)", "i"); + var result = this.id.match(re); + var client_id = result[1]; + var repo_id = result[2]; + // high light currect selected repository + for(var cc in repository_listing[client_id]){ + var tmp_id = 'repo-call-'+client_id+'-'+ cc; + var el = document.getElementById(tmp_id); + if(el){ + el.style.background = 'transparent'; + } + } + this.style.background = '#CCC'; + repository_client.loading(client_id, 'load'); + repository_client.req(client_id, repo_id, ''); + } + li.appendChild(link); + container.appendChild(li); + repo = null; + } + } + }, this, true); + } + this.show = function(){ + this.print_listing(); + var panel = new YAHOO.util.Element('panel-'+this.filepicker.client_id); + panel.get('element').innerHTML = ''; + this.filepicker.show(); + } + this.hide = function(){ + this.filepicker.hide(); + } + } + // all filepicker instances + $.fp = {}; + return $; +})(); +// public static method +// may be called outside yui +repository_client.req = function(client_id, id, path, page) { + this.fp[client_id].viewbar.set('disabled', false); + var r = repository_client.fp[client_id]; + var params = []; + params['p'] = path; + params['env']=r.env; + params['sesskey']=moodle_cfg.sesskey; + params['ctx_id']=fp_config.contextid; + params['client_id'] = client_id; + params['repo_id']=id; + if (!!page) { // convert page to boolean value + params['page']=page; + } + params['accepted_types'] = r.accepted_types; + var trans = YAHOO.util.Connect.asyncRequest('POST', moodle_cfg.wwwroot+'/repository/ws.php?action=list', this.req_cb, this.postdata(params)); +} + +repository_client.req_cb = { + success: function(o){ + try { + var data = YAHOO.lang.JSON.parse(o.responseText); + } catch(e) { + alert(fp_lang.invalidjson+' - |req_cb| -'+repository_client.stripHTML(o.responseText)); + }; + var repo = repository_client.fp[data.client_id]; + var panel = new YAHOO.util.Element('panel-'+data.client_id); + if(data && data.e) { + panel.get('element').innerHTML = data.e; + return; + } + // save data + repo.fs = data; + if(!data) { + return; + }else if(data.msg){ + repository_client.print_msg(data.msg); + }else if(data.iframe) { + repository_client.viewiframe(); + }else if(data.login) { + repository_client.print_login(data.client_id, data); + }else if(data.list) { + if(repo.view_status) { + repository_client.view_as_list(data.client_id, data.list); + } else { + repository_client.view_as_icons(data.client_id, data.list); + } + } + } +} +repository_client.req_search_results = function(client_id, id, path, page) { + this.fp[client_id].viewbar.set('disabled', false); + var r = repository_client.fp[client_id]; + var params = []; + params['p'] = path; + params['env']=r.env; + params['sesskey']=moodle_cfg.sesskey; + params['ctx_id']=fp_config.contextid; + params['client_id'] = client_id; + params['search_paging']='true'; + params['repo_id']=id; + if (!!page) { // convert page to boolean value + params['page']=page; + } + params['accepted_types'] = r.accepted_types; + var trans = YAHOO.util.Connect.asyncRequest('POST', moodle_cfg.wwwroot+'/repository/ws.php?action=search', this.req_cb, this.postdata(params)); +} + +repository_client.print_login = function(id, data) { + var login = data.login; + var panel = new YAHOO.util.Element('panel-'+id); + var str = ''; + panel.get('element').innerHTML = str; +} +repository_client.login = function(id, repo_id) { + var params = []; + var data = this.fp[id].login; + for (var k in data) { + if(data[k].type!='popup') { + var el = document.getElementsByName(data[k].name)[0]; + params[data[k].name] = ''; + if(el.type == 'checkbox') { + params[data[k].name] = el.checked; + } else { + params[data[k].name] = el.value; + } + } + } + params['env'] = this.fp[id].env; + params['repo_id'] = repo_id; + params['client_id'] = id; + params['ctx_id'] = fp_config.contextid; + params['sesskey'] = moodle_cfg.sesskey; + params['accepted_types'] = this.fp[id].accepted_types; + this.loading(id, 'load'); + var trans = YAHOO.util.Connect.asyncRequest('POST', + moodle_cfg.wwwroot+'/repository/ws.php?action=sign', this.req_cb, this.postdata(params)); +} +repository_client.search = function(id, repo_id) { + var params = []; + var data = this.fp[id].login; + for (var k in data) { + if(data[k].type!='popup') { + var el = document.getElementsByName(data[k].name)[0]; + params[data[k].name] = ''; + if(el.type == 'checkbox') { + params[data[k].name] = el.checked; + } else { + params[data[k].name] = el.value; + } + } + } + params['env'] = this.fp[id].env; + params['repo_id'] = repo_id; + params['client_id'] = id; + params['ctx_id'] = fp_config.contextid; + params['sesskey'] = moodle_cfg.sesskey; + params['accepted_types'] = this.fp[id].accepted_types; + this.loading(id, 'load'); + var trans = YAHOO.util.Connect.asyncRequest('POST', + moodle_cfg.wwwroot+'/repository/ws.php?action=search', this.req_cb, this.postdata(params)); +} +repository_client.loading = function(id, type, name) { + var panel = new YAHOO.util.Element('panel-'+id); + panel.get('element').innerHTML = ''; + var content = document.createElement('div'); + content.style.textAlign='center'; + var para = document.createElement('P'); + var img = document.createElement('IMG'); + if(type=='load') { + img.src = moodle_cfg.pixpath+'/i/loading.gif'; + para.innerHTML = fp_lang.loading; + }else{ + img.src = moodle_cfg.pixpath+'/i/progressbar.gif'; + para.innerHTML = fp_lang.copying+' '+name+''; + } + content.appendChild(para); + content.appendChild(img); + panel.get('element').appendChild(content); +} +repository_client.view_as_list = function(client_id, data) { + if (typeof client_id == 'object') { + // click button + client_id = data; + list = repository_client.fp[client_id].fs.list; + } else { + // from callback + list = data; + } + var panel = new YAHOO.util.Element('panel-'+client_id); + var fp = repository_client.fp[client_id]; + fp.view_status = 1; + fp.viewbar.check(1); + repository_client.print_header(client_id); + panel.get('element').innerHTML += '
      '; + var tree = new YAHOO.widget.TreeView('treediv-'+client_id); + tree.dynload = function (node, fnLoadComplete) { + var callback = { + success: function(o) { + try { + var json = YAHOO.lang.JSON.parse(o.responseText); + } catch(e) { + alert(fp_lang.invalidjson+' - |dynload| -'+repository_client.stripHTML(o.responseText)); + return; + } + for(k in json.list) { + repository_client.buildtree(json.client_id, json.list[k], node); + } + o.argument.fnLoadComplete(); + }, + failure:function(oResponse) { + alert(fp_lang.error+' - |dynload| -'); + oResponse.argument.fnLoadComplete(); + }, + argument:{"node":node, "fnLoadComplete": fnLoadComplete} + } + var fp = repository_client.fp[node.client_id]; + var params = []; + params['p']=node.path; + params['env']=fp.env; + params['sesskey']=moodle_cfg.sesskey; + params['ctx_id']=fp_config.contextid; + params['repo_id']=fp.fs.repo_id; + params['client_id']=node.client_id; + params['accepted_types']=fp.accepted_types; + var trans = YAHOO.util.Connect.asyncRequest('POST', + moodle_cfg.wwwroot+'/repository/ws.php?action=list',callback,repository_client.postdata(params)); + } + tree.dynload.client_id = client_id; + if(fp.fs.dynload) { + tree.setDynamicLoad(tree.dynload, 1); + } else { + } + for(k in list) { + repository_client.buildtree(client_id, list[k], tree.getRoot()); + } + tree.draw(); + tree.subscribe('clickEvent', function(e){ + if(e.node.isLeaf){ + repository_client.select_file(e.node.data.filename, e.node.data.value, e.node.data.icon, client_id, e.node.repo_id); + } + }); + repository_client.print_footer(client_id); +} +repository_client.buildtree = function(client_id, node, level) { + var fs = repository_client.fp[client_id].fs; + if(node.children) { + node.title = ''+node.title+''; + } + var info = { + label:node.title, + title:fp_lang.date+' '+node.date+fp_lang.size+' '+node.size, + filename:node.title, + value:node.source, + icon:node.thumbnail, + path:node.path + }; + var tmpNode = new YAHOO.widget.TextNode(info, level, false); + var tooltip = new YAHOO.widget.Tooltip(tmpNode.labelElId, { + context:tmpNode.labelElId, text:info.title}); + if(node.repo_id) { + tmpNode.repo_id=node.repo_id; + }else{ + tmpNode.repo_id=fs.repo_id; + } + if(node.children) { + if(node.expanded) { + tmpNode.expand(); + } + tmpNode.isLeaf = false; + tmpNode.client_id = client_id; + if (node.path) { + tmpNode.path = node.path; + } else { + tmpNode.path = ''; + } + for(var c in node.children) { + this.buildtree(client_id, node.children[c], tmpNode); + } + } else { + tmpNode.isLeaf = true; + } +} +repository_client.select_file = function(oldname, url, icon, client_id, repo_id) { + var thumbnail = document.getElementById('fp-grid-panel-'+client_id); + if(thumbnail){ + thumbnail.style.display = 'none'; + } + var header = document.getElementById('fp-header-'+client_id); + header.style.display = 'none'; + var footer = document.getElementById('fp-footer-'+client_id); + footer.style.display = 'none'; + var panel = new YAHOO.util.Element('panel-'+client_id); + var html = '
      '; + html += '

      '; + html += '

      '; + html += '

      '; + html += '

      '; + html += ''; + html += '

      '; + html += '
      '; + panel.get('element').innerHTML += html; + var tree = document.getElementById('treediv-'+client_id); + if(tree){ + tree.style.display = 'none'; + } +} +repository_client.paging = function(client_id, id) { + var str = ''; + this.fp[client_id].view_staus = 0; + var fs = this.fp[client_id].fs; + if(fs.pages) { + str += '
      '; + if(!fs.search_result){ + var action = 'req'; + } else { + var action = 'req_search_results'; + } + str += this.get_page_btn(client_id, action, 1)+'1'; + + if (fs.page+2>=fs.pages) { + var max = fs.pages; + } else { + var max = fs.page+2; + } + if (fs.page-2 >= 3) { + str += ' ... '; + for(var i=fs.page-2; i'; + } else { + str += repository_client.get_page_btn(client_id, action, max)+max+''; + str += ' ... '+repository_client.get_page_btn(client_id, action, fs.pages)+fs.pages+''; + } + str += '
      '; + } + return str; +} +repository_client.get_page_btn = function(client_id, type, page) { + var fs = this.fp[client_id].fs; + var css = ''; + if (page == fs.page) { + css = 'class="cur_page"'; + } + str = ''; + return str; +} +repository_client.path = function(client_id) { + var fs = this.fp[client_id].fs; + // if this is listing view + if(this.fp[client_id].view_status == 1) { + return; + } + var panel = new YAHOO.util.Element('panel-'+client_id); + var p = fs.path; + if(p && p.length!=0) { + var oDiv = document.createElement('DIV'); + oDiv.id = "path-"+client_id; + oDiv.className = "fp-pathbar"; + panel.get('element').appendChild(oDiv); + for(var i = 0; i < fs.path.length; i++) { + var link = document.createElement('A'); + link.href = "###"; + link.innerHTML = fs.path[i].name; + link.id = 'path-'+i+'-el'; + var sep = document.createElement('SPAN'); + sep.innerHTML = '/'; + oDiv.appendChild(link); + oDiv.appendChild(sep); + var el = new YAHOO.util.Element(link.id); + el.id = fs.repo_id; + el.path = fs.path[i].path; + el.link_id = link.id; + el.client_id = client_id; + el.on('contentReady', function() { + var path_link = document.getElementById(this.link_id); + path_link.id = this.id; + path_link.path = this.path; + path_link.client_id = this.client_id; + path_link.onclick = function() { + alert('test'); + repository_client.req(this.client_id, this.id, this.path); + } + }); + link = null; + } + } +} +repository_client.print_header = function(client_id) { + var panel = new YAHOO.util.Element('panel-'+client_id); + var str = '
      '; + str += '
      '; + if(this.fp[client_id].fs.pages < 8){ + str += this.paging(client_id, 'header'); + } + str += '
      '; + panel.set('innerHTML', str); + this.path(client_id); +} +repository_client.view_as_icons = function(client_id, data) { + var list = null; + if (typeof client_id == 'object') { + // click button + client_id = data; + list = repository_client.fp[client_id].fs.list; + } else { + list = data; + } + var fp = repository_client.fp[client_id]; + fp.view_status = 0; + fp.viewbar.check(0); + var container = document.getElementById('panel-'+client_id); + var panel = document.createElement('DIV'); + panel.id = 'fp-grid-panel-'+client_id; + repository_client.print_header(client_id); + var count = 0; + for(k in list) { + // the container + var el = document.createElement('div'); + el.className='fp-grid'; + // the file name + var title = document.createElement('div'); + title.id = 'grid-title-'+String(count); + title.className = 'label'; + if (list[k].shorttitle) { + list[k].title = list[k].shorttitle; + } + title.innerHTML += '
      '+list[k].title+""; + if(list[k].thumbnail_width){ + el.style.width = list[k].thumbnail_width+'px'; + title.style.width = (list[k].thumbnail_width-10)+'px'; + } else { + el.style.width = title.style.width = '80px'; + } + var frame = document.createElement('DIV'); + frame.style.textAlign='center'; + if(list[k].thumbnail_height){ + frame.style.height = list[k].thumbnail_height+'px'; + } + var img = document.createElement('img'); + img.src = list[k].thumbnail; + if(list[k].thumbnail_alt) { + img.alt = list[k].thumbnail_alt; + } + if(list[k].thumbnail_title) { + img.title = list[k].thumbnail_title; + } + var link = document.createElement('A'); + link.href='###'; + link.id = 'img-id-'+String(count); + if(list[k].url) { + el.innerHTML += '

      '+fp_lang.preview+'

      '; + } + link.appendChild(img); + frame.appendChild(link); + el.appendChild(frame); + el.appendChild(title); + panel.appendChild(el); + if(list[k].children) { + var folder = new YAHOO.util.Element(link.id); + folder.path = list[k].path; + var el_title = new YAHOO.util.Element(title.id); + folder.fs = list[k].children; + folder.on('contentReady', function() { + this.on('click', function() { + if(fp.fs.dynload) { + var fs = repository_client.fp[client_id].fs; + var params = []; + params['p'] = this.path; + params['env'] = repository_client.fp[client_id].env; + params['repo_id'] = fs.repo_id; + params['ctx_id'] = fp_config.contextid; + params['sesskey']= moodle_cfg.sesskey; + params['accepted_types'] = repository_client.fp[client_id].accepted_types; + params['client_id'] = client_id; + repository_client.loading(client_id, 'load'); + var trans = YAHOO.util.Connect.asyncRequest('POST', + moodle_cfg.wwwroot+'/repository/ws.php?action=list', repository_client.req_cb, repository_client.postdata(params)); + }else{ + repository_client.view_as_icons(client_id, this.fs); + } + }); + }); + el_title.on('contentReady', function() { + this.on('click', function(){ + folder.fireEvent('click'); + }); + }); + } else { + var el_title = new YAHOO.util.Element(title.id); + var file = new YAHOO.util.Element(link.id); + el_title.title = file.title = list[k].title; + el_title.value = file.value = list[k].source; + el_title.icon = file.icon = list[k].thumbnail; + if(fp.fs.repo_id) { + el_title.repo_id = file.repo_id = fp.fs.repo_id; + }else{ + el_title.repo_id = file.repo_id = ''; + } + file.on('contentReady', function() { + this.on('click', function() { + repository_client.select_file(this.title, this.value, this.icon, client_id, this.repo_id); + }); + }); + el_title.on('contentReady', function() { + this.on('click', function() { + repository_client.select_file(this.title, this.value, this.icon, client_id, this.repo_id); + }); + }); + } + count++; + } + container.appendChild(panel); + repository_client.print_footer(client_id); +} +repository_client.create_upload_form = function(client_id) { + var str = ''; + var fs = repository_client.fp[client_id].fs; + if(fs.upload) { + str += '
      '; + str += '
      '; + str += ''; + str += ''; + str += '

      '+fp_lang.upload+'

      '; + str += '
      '; + str += '
      '; + } + return str; +} +repository_client.print_footer = function(client_id) { + var fs = this.fp[client_id].fs; + var panel = document.getElementById('panel-'+client_id); + var footer = document.createElement('DIV'); + footer.id = 'fp-footer-'+client_id; + footer.innerHTML += this.create_upload_form(client_id); + footer.innerHTML += this.paging(client_id, 'footer'); + panel.appendChild(footer); + // add repository manage buttons here + var oDiv = document.getElementById('repo-tb-'+client_id); + if(!fs.nosearch) { + var search = document.createElement('A'); + search.href = '###'; + search.innerHTML = ' '+fp_lang.search; + oDiv.appendChild(search); + search.onclick = function() { + repository_client.search_form(client_id,repository_client.repositoryid); + } + } + // weather we use cache for this instance, this button will reload listing anyway + if(!fs.norefresh) { + var ccache = document.createElement('A'); + ccache.href = '###'; + ccache.innerHTML = ' '+fp_lang.refresh; + oDiv.appendChild(ccache); + ccache.onclick = function() { + var params = []; + params['env']=fs.env; + params['sesskey']=moodle_cfg.sesskey; + params['ctx_id']=fp_config.contextid; + params['repo_id']=fs.repo_id; + repository_client.loading(client_id, 'load'); + var trans = YAHOO.util.Connect.asyncRequest('POST', + moodle_cfg.wwwroot+'/repository/ws.php?action=ccache', repository_client.req_cb, repository_client.postdata(params)); + } + } + if(fs.manage) { + var mgr = document.createElement('A'); + mgr.innerHTML = ' '+fp_lang.mgr; + mgr.href = fs.manage; + mgr.target = "_blank"; + oDiv.appendChild(mgr); + } + if(!fs.nologin) { + var logout = document.createElement('A'); + logout.href = '###'; + logout.innerHTML = ' '+fp_lang.logout; + oDiv.appendChild(logout); + logout.onclick = function() { + repository_client.logout(client_id, fs.repo_id); + } + } + if(fs.help) { + var help = document.createElement('A'); + help.href = fs.help; + help.target = "_blank"; + help.innerHTML = ' '+fp_lang['help']; + oDiv.appendChild(help); + } +} + +repository_client.postdata = function(obj) { + var str = ''; + for(k in obj) { + if(obj[k] instanceof Array) { + for(i in obj[k]) { + str += (encodeURIComponent(k) +'[]='+encodeURIComponent(obj[k][i])); + str += '&'; + } + } else { + str += encodeURIComponent(k) +'='+encodeURIComponent(obj[k]); + str += '&'; + } + } + return str; +} + +repository_client.stripHTML = function(str){ + var re= /<\S[^><]*>/g + var ret = str.replace(re, "") + return ret; +} +repository_client.popup = function(client_id, url) { + repository_client.win = window.open(url,'repo_auth', 'location=0,status=0,scrollbars=0,width=500,height=300'); + repository_client.win.client_id = client_id; + return false; +} +function repository_callback(id) { + repository_client.req(repository_client.win.client_id, id, ''); + repository_client.win = null; +} +repository_client.logout = function(client_id, repo_id) { + var params = []; + params['repo_id'] = repo_id; + params['client_id'] = client_id; + var trans = YAHOO.util.Connect.asyncRequest('POST', moodle_cfg.wwwroot+'/repository/ws.php?action=logout', + repository_client.req_cb, repository_client.postdata(params)); +} +repository_client.download = function(client_id, repo_id) { + var fp = repository_client.fp[client_id]; + var title = document.getElementById('newname-'+client_id).value; + var file = document.getElementById('fileurl-'+client_id).value; + repository_client.loading(client_id, 'download', title); + var params = []; + if(fp.itemid){ + params['itemid']=fp.itemid; + } + params['env']=fp.env; + params['file']=file; + params['title']=title; + params['sesskey']=moodle_cfg.sesskey; + params['ctx_id']=fp_config.contextid; + params['repo_id']=repo_id; + params['client_id']=client_id; + var trans = YAHOO.util.Connect.asyncRequest('POST', + moodle_cfg.wwwroot+'/repository/ws.php?action=download', + repository_client.download_cb, + repository_client.postdata(params)); +} +repository_client.download_cb = { + success: function(o) { + try { + var data = YAHOO.lang.JSON.parse(o.responseText); + } catch(e) { + alert(fp_lang.invalidjson+' - |download_cb| -'+repository_client.stripHTML(o.responseText)); + } + var panel = new YAHOO.util.Element('panel-'+data.client_id); + if(data && data.e) { + panel.get('element').innerHTML = data.e; + return; + } + repository_client.end(data.client_id, data); + } +} +repository_client.end = function(client_id, obj) { + var fp = repository_client.fp[client_id]; + if(fp.env=='filepicker') { + fp.target.value = obj['id']; + }else if(fp.env=='editor'){ + fp.target.value = obj['url']; + fp.target.onchange(); + } + fp.formcallback(obj); + fp.hide(); + repository_client.viewfiles(); +} +repository_client.viewfiles = function() { + alert('Not available yet.'); +} +repository_client.search_form = function(client_id, id) { + var fp = repository_client.fp[client_id]; + var params = []; + params['env']=fp.env; + params['sesskey']=moodle_cfg.sesskey; + params['client_id'] = client_id; + params['ctx_id']=fp_config.contextid; + params['repo_id']=fp.fs.id; + var trans = YAHOO.util.Connect.asyncRequest('POST', + moodle_cfg.wwwroot+'/repository/ws.php?action=searchform', + repository_client.search_form_cb, + repository_client.postdata(params)); +} +repository_client.search_form_cb = { +success: function(o) { + var el = document.getElementById('fp-search-dlg'); + var _r = repository_client; + if(el) { + el.innerHTML = ''; + } else { + var el = document.createElement('DIV'); + el.id = 'fp-search-dlg'; + } + var div1 = document.createElement('DIV'); + div1.className = 'hd'; + div1.innerHTML = fp_lang.searching+"\"" + _r.repos[_r.repositoryid].name + '"'; + var div2 = document.createElement('DIV'); + div2.className = 'bd'; + var sform = document.createElement('FORM'); + sform.method = 'POST'; + sform.id = "fp-search-form"; + sform.action = '$CFG->httpswwwroot/repository/ws.php?action=search'; + sform.innerHTML = o.responseText; + div2.appendChild(sform); + el.appendChild(div1); + el.appendChild(div2); + document.body.appendChild(el); + var dlg = new YAHOO.widget.Dialog("fp-search-dlg",{ + postmethod: 'async', + draggable: true, + width : "30em", + fixedcenter : true, + zindex: 766667, + visible : false, + constraintoviewport : true, + buttons : [ + { text:fp_lang.submit,handler: function() { + repository_client.viewbar.set('disabled', false); repository_client.loading('load'); + YAHOO.util.Connect.setForm('fp-search-form', false, false); + this.cancel(); + var trans = YAHOO.util.Connect.asyncRequest('POST', + '$CFG->httpswwwroot/repository/ws.php?action=search&env='+repository_client.env, repository_client.req_cb); + },isDefault:true}, + {text:fp_lang.cancel,handler:function() {this.cancel()}} + ] + }); + dlg.render(); + dlg.show(); +} +} +var mdl_in_array = function(el, arr) { + for(var i = 0, l = arr.length; i < l; i++) { + if(arr[i] == el) { + return true; + } + } + return false; +} + +// will be called by filemanager or htmleditor +function open_filepicker(id, params) { + var r = repository_client.fp[id]; + if(!r) { + // passing parameters + r = new repository_client(); + r.env = params.env; + r.target = params.target; + if(params.itemid){ + r.itemid = params.itemid; + } else if(tinyMCE && id2itemid[tinyMCE.selectedInstance.editorId]){ + r.itemid = id2itemid[tinyMCE.selectedInstance.editorId]; + } + // setup callback function + if(params.callback) { + r.formcallback = params.callback; + } else { + r.formcallback = function() {}; + } + // write back + repository_client.fp[id] = r; + // create file picker (html elements and events) + r.create_filepicker(id); + } else { + r.target = params.target; + r.show(); + } + if(params.filetype) { + if(params.filetype == 'image') { + r.accepted_types = file_extensions.image; + } else if(params.filetype == 'video' || params.filetype== 'media') { + r.accepted_types = file_extensions.media; + } else if(params.filetype == 'file') { + r.accepted_types = '*'; + } + } else { + r.accepted_types = '*'; + } + return r; +} diff --git a/repository/ws.php b/repository/ws.php index b252ff098d9..c856bde3763 100644 --- a/repository/ws.php +++ b/repository/ws.php @@ -8,6 +8,7 @@ /// Parameters $page = optional_param('page', '', PARAM_RAW); // page + $client_id = optional_param('client_id', SITEID, PARAM_RAW); // client ID $env = optional_param('env', 'filepicker', PARAM_ALPHA);// opened in editor or moodleform $file = optional_param('file', '', PARAM_RAW); // file to download $title = optional_param('title', '', PARAM_FILE); // new file name @@ -22,10 +23,11 @@ /// Headers to make it not cacheable header("Cache-Control: no-cache, must-revalidate"); header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); + $err = new stdclass; + $err->client_id = $client_id; /// Check permissions if (! (isloggedin() && repository::check_context($ctx_id)) ) { - $err = new stdclass; $err->e = get_string('nopermissiontoaccess', 'repository'); die(json_encode($err)); } @@ -50,7 +52,6 @@ } exit; } catch (repository_exception $e) { - $err = new stdclass; $err->e = $e->getMessage(); die(json_encode($err)); } @@ -66,17 +67,18 @@ $tmp = array_merge($list, $ret['list']); $list = $tmp; } catch (repository_exception $e) { - $err = new stdclass; $err->e = $e->getMessage(); die(json_encode($err)); } } } - die(json_encode(array('list'=>$list))); + $listing = array('list'=>$list); + $listing['client_id'] = $client_id; + die(json_encode($listing)); break; case 'ccache': // Clean cache - $cache = new curl_cache('repository'); + $cache = new curl_cache; $cache->refresh(); $action = 'list'; break; @@ -86,7 +88,6 @@ $sql = 'SELECT i.name, i.typeid, r.type FROM {repository} r, {repository_instances} i '. 'WHERE i.id=? AND i.typeid=r.id'; if (!$repository = $DB->get_record_sql($sql, array($repo_id))) { - $err = new stdclass; $err->e = get_string('invalidrepositoryid', 'repository'); die(json_encode($err)); } else { @@ -99,12 +100,10 @@ try { $repo = new $classname($repo_id, $ctx_id, array('ajax'=>true, 'name'=>$repository->name)); } catch (repository_exception $e){ - $err = new stdclass; $err->e = $e->getMessage(); die(json_encode($err)); } } else { - $err = new stdclass; $err->e = get_string('invalidplugin', 'repository', $type); die(json_encode($err)); } @@ -114,6 +113,8 @@ // the callback url should be something like this: // http://xx.moodle.com/repository/ws.php?callback=yes&repo_id=1&sid=xxx // sid is the attached auth token from external source + echo_fb($client_id); + echo_fb($repo_id); $js =<<