From fb2fb46e5bdc4614ff49979cf5783c8c70dbf8b8 Mon Sep 17 00:00:00 2001 From: Dongsheng Cai Date: Wed, 16 Jun 2010 08:07:42 +0000 Subject: [PATCH] MDL-22805, new renderer component moodle_file_tree_viewer, remove file_tree_viewer to area_file_tree_viewer, the legecy files/index.php has be replaced with the moodle_file_tree_viewer, it is readonly --- files/files_ajax.php | 38 +++++ files/index.php | 284 +++------------------------------- files/module.js | 76 +++++++++ lang/en/repository.php | 1 + lib/outputcomponents.php | 70 ++++++++- lib/outputrenderers.php | 64 +++++++- lib/outputrequirementslib.php | 5 + mod/folder/view.php | 2 +- 8 files changed, 261 insertions(+), 279 deletions(-) create mode 100644 files/module.js diff --git a/files/files_ajax.php b/files/files_ajax.php index bfa318cbdcb..146f1e66009 100755 --- a/files/files_ajax.php +++ b/files/files_ajax.php @@ -43,6 +43,7 @@ if (!confirm_sesskey()) { } $action = optional_param('action', 'list', PARAM_ALPHA); +$fileurl = optional_param('fileurl', '', PARAM_URL); $filename = optional_param('filename', '', PARAM_FILE); $filearea = optional_param('filearea', 'user_draft', PARAM_ALPHAEXT); $filepath = optional_param('filepath', '/', PARAM_PATH); @@ -54,6 +55,43 @@ $newfilename = optional_param('newfilename', '', PARAM_FILE); $user_context = get_context_instance(CONTEXT_USER, $USER->id); switch ($action) { +// used by course file tree viewer +case 'getfiletree': + $browser = get_file_browser(); + $url = new moodle_url($fileurl); + $params = $url->params(); + // fix empty value + foreach ($params as $key=>$value) { + if ($value==='') { + $params[$key] = null; + } + } + $fileinfo = $browser->get_file_info(get_context_instance_by_id($params['contextid']), $params['filearea'], $params['itemid'], $params['filepath']); + $children = $fileinfo->get_children(); + $tree = array(); + foreach ($children as $child) { + $filedate = $child->get_timemodified(); + $filesize = $child->get_filesize(); + $mimetype = $child->get_mimetype(); + $params = $child->get_params(); + $url = new moodle_url('/files/index.php', $params); + $fileitem = array( + 'params'=>$params, + 'filename'=>$child->get_visible_name(), + 'filedate'=>$filedate ? userdate($filedate) : '', + 'filesize'=>$filesize ? display_size($filesize) : '', + ); + if ($child->is_directory()) { + $fileitem['isdir'] = true; + $fileitem['url'] = $url->out(); + } else { + $fileitem['url'] = $child->get_url(); + } + $tree[] = $fileitem; + } + echo json_encode($tree); + + break; case 'dir': $data = new stdclass; file_get_user_area_folders($itemid, $filepath, $data, $filearea); diff --git a/files/index.php b/files/index.php index ef45bf8c4df..ff342761687 100644 --- a/files/index.php +++ b/files/index.php @@ -16,17 +16,15 @@ // along with Moodle. If not, see . /** - * Temporary file manager for all moodle files. To be replaced by something much better. + * Moodle file tree viewer based on YUI2 Treeview * * @package moodlecore * @subpackage file - * @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com) + * @copyright 2010 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'); $courseid = optional_param('id', 0, PARAM_INT); @@ -36,9 +34,6 @@ $itemid = optional_param('itemid', -1, PARAM_INT); $filepath = optional_param('filepath', '', PARAM_PATH); $filename = optional_param('filename', '', PARAM_FILE); -$newdirname = optional_param('newdirname', '', PARAM_FILE); -$delete = optional_param('delete', 0, PARAM_BOOL); - if ($courseid) { $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST); $context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST); @@ -75,270 +70,27 @@ if ($filename === '') { $filename = null; } -$error = ''; - $browser = get_file_browser(); $file_info = $browser->get_file_info($context, $filearea, $itemid, $filepath, $filename); -/// process actions -if ($file_info and $file_info->is_directory() and $file_info->is_writable() and $newdirname !== '' and data_submitted() and confirm_sesskey()) { - if ($newdir_info = $file_info->create_directory($newdirname, $USER->id)) { - $params = $newdir_info->get_params(); - redirect(new moodle_url('index.php', $params)); - } else { - $error = "Could not create new dir"; // TODO: localise - } +$strfiles = get_string("files"); +if ($context->contextlevel == CONTEXT_MODULE) { + $PAGE->set_pagelayout('incourse'); +} else if ($context->contextlevel == CONTEXT_COURSE) { + $PAGE->set_pagelayout('course'); +} else { + $PAGE->set_pagelayout('admin'); } -if ($file_info and $file_info->is_directory() and $file_info->is_writable() and isset($_FILES['newfile']) and data_submitted() and confirm_sesskey()) { - $file = $_FILES['newfile']; - $newfilename = clean_param($file['name'], PARAM_FILE); - if (is_uploaded_file($_FILES['newfile']['tmp_name'])) { - try { - if ($newfile = $file_info->create_file_from_pathname($newfilename, $_FILES['newfile']['tmp_name'], $USER->id)) { - $params = $file_info->get_params(); - redirect(new moodle_url('index.php', $params)); +$PAGE->navbar->add($strfiles); +$PAGE->set_url("/files/index.php", $file_info->get_params()); +$PAGE->set_title("$SITE->shortname: $strfiles"); +$PAGE->set_heading($SITE->fullname); +echo $OUTPUT->header(); - } else { - $error = "Could not create upload file"; // TODO: localise - } - } catch (file_exception $e) { - $error = "Exception: Could not create upload file"; // TODO: localise - } - } -} +echo $OUTPUT->box_start(); +echo $OUTPUT->moodle_file_tree_viewer($context->id, $filearea, $itemid, $filepath); +echo $OUTPUT->box_end(); -if ($file_info and $delete) { - if (!data_submitted() or !confirm_sesskey()) { - $params = $file_info->get_params(); - $params = array_merge($params, array('delete'=>1)); - $PAGE->set_url("/files/index.php", $params); - $PAGE->set_title("$SITE->shortname: " .get_string('files')); - $PAGE->set_heading($SITE->fullname); - echo $OUTPUT->header(); - echo $OUTPUT->notification(get_string('deletecheckwarning').': '.$file_info->get_visible_name()); - $parent_info = $file_info->get_parent(); - - $optionsno = $parent_info->get_params(); - $optionsyes = $file_info->get_params(); - $optionsyes['delete'] = 1; - $optionsyes['sesskey'] = sesskey(); - - echo $OUTPUT->confirm(get_string('deletecheckfiles'), new moodle_url( 'index.php', $optionsyes), new moodle_url('index.php', $optionsno)); - echo $OUTPUT->footer(); - die; - } - - if ($parent_info = $file_info->get_parent() and $parent_info->is_writable()) { - if (!$file_info->delete()) { - $error = "Could not delete file!"; // TODO: localise - } - $params = $parent_info->get_params(); - redirect(new moodle_url('index.php', $params)); - } -} - - -/// print dir listing -html_header($context, $file_info); - -if ($error !== '') { - echo $OUTPUT->notification($error); -} - -displaydir($file_info); - -if ($file_info and $file_info->is_directory() and $file_info->is_writable()) { - echo '
'; - - echo '
'; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo '
'; - - echo '
'; - - echo '
'; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo '
'; -} - -html_footer(); - -/// UI functions ///////////////////////// - -function html_footer() { - global $OUTPUT; - echo ''; - echo $OUTPUT->footer(); -} - -function html_header($context, $file_info){ - global $CFG, $SITE, $PAGE, $OUTPUT; - - $strfiles = get_string("files"); - if ($context->contextlevel == CONTEXT_MODULE) { - $PAGE->set_pagelayout('incourse'); - } else if ($context->contextlevel == CONTEXT_COURSE) { - $PAGE->set_pagelayout('course'); - } else { - $PAGE->set_pagelayout('admin'); - } - $PAGE->navbar->add($strfiles); - $PAGE->set_url("/files/index.php", $file_info->get_params()); - $PAGE->set_title("$SITE->shortname: $strfiles"); - $PAGE->set_heading($SITE->fullname); - echo $OUTPUT->header(); - - echo ""; - echo ""; - echo "'; -} - -function displaydir($file_info) { - global $CFG, $OUTPUT; - - $children = $file_info->get_children(); - $parent_info = $file_info->get_parent(); - - $strname = get_string('name'); - $strsize = get_string('size'); - $strmodified = get_string('modified'); - $strfolder = get_string('folder'); - $strfile = get_string('file'); - $strdownload = get_string('download'); - $strdelete = get_string('delete'); - $straction = get_string('action'); - - $path = array(); - $params = $file_info->get_params_rawencoded(); - $params = implode('&', $params); - $path[] = $file_info->get_visible_name(); - - $level = $parent_info; - while ($level) { - $params = $level->get_params_rawencoded(); - $params = implode('&', $params); - $path[] = ''.$level->get_visible_name().''; - $level = $level->get_parent(); - } - - $path = array_reverse($path); - - $path = implode (' / ', $path); - echo $path. ' /'; - - echo "
"; - echo "
"; - echo "
"; -} - -/// FILE FUNCTIONS /////////////////////////////////////////////////////////// - -function print_cell($alignment='center', $text=' ', $class='') { - if ($class) { - $class = ' class="'.$class.'"'; - } - echo ''.$text.'
"; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo "\n"; - - $parentwritable = $file_info->is_writable(); - - if ($parent_info) { - $params = $parent_info->get_params_rawencoded(); - $params = implode('&', $params); - - echo ""; - print_cell(); - print_cell('left', ' '.get_string('parentfolder').'', 'name'); - print_cell(); - print_cell(); - print_cell(); - - echo ""; - } - - if ($children) { - foreach ($children as $child_info) { - $filename = $child_info->get_visible_name(); - $filesize = $child_info->get_filesize(); - $filesize = $filesize ? display_size($filesize) : ''; - $filedate = $child_info->get_timemodified(); - $filedate = $filedate ? userdate($filedate) : ''; - - $mimetype = $child_info->get_mimetype(); - - $params = $child_info->get_params_rawencoded(); - $params = implode('&', $params); - - if ($child_info->is_directory()) { - - echo ""; - print_cell(); - print_cell("left", "pix_url('f/folder') . "\" class=\"icon\" alt=\"$strfolder\" /> ".s($filename)."", 'name'); - print_cell("right", $filesize, 'size'); - print_cell("right", $filedate, 'date'); - if ($parentwritable) { - print_cell("right", "pix_url('t/delete') . "\" class=\"iconsmall\" alt=\"$strdelete\" />", 'command'); - } else { - print_cell(); - } - echo ""; - - } else { - - if ($downloadurl = $child_info->get_url(true)) { - $downloadurl = " pix_url('t/down') . "\" class=\"iconsmall\" alt=\"$strdownload\" />"; - } else { - $downloadurl = ''; - } - - if ($viewurl = $child_info->get_url()) { - $viewurl = " ".$OUTPUT->action_link($viewurl, "pix_url('t/preview') . "\" class=\"iconsmall\" alt=\"$strfile\" /> ", - new popup_action('click', $viewurl, 'display', array('height' => 480, 'width' => 640))); - } else { - $viewurl = ''; - } - - - - echo ""; - print_cell(); - print_cell("left", "pix_url(file_mimetype_icon($mimetype)) . "\" class=\"icon\" alt=\"$strfile\" /> ".s($filename).$downloadurl.$viewurl, 'name'); - print_cell("right", $filesize, 'size'); - print_cell("right", $filedate, 'date'); - if ($parentwritable) { - print_cell("right", "pix_url('t/delete') . "\" class=\"iconsmall\" alt=\"$strdelete\" />", 'command'); - } else { - print_cell(); - } - echo ""; - } - } - } - - echo "
$strname$strsize$strmodified$straction
"; - echo ""; - echo "
"; - -} +echo $OUTPUT->footer(); diff --git a/files/module.js b/files/module.js new file mode 100644 index 00000000000..8ffc89ee1f0 --- /dev/null +++ b/files/module.js @@ -0,0 +1,76 @@ +// File Tree Viewer +// Author: Dongsheng Cai +M.core_filetree = { + y3: null, + api: M.cfg.wwwroot+'/files/files_ajax.php', + request: function(url, node, cb) { + var api = this.api + '?action=getfiletree'; + var params = []; + params['fileurl'] = url; + var scope = this; + params['sesskey']=M.cfg.sesskey; + var cfg = { + method: 'POST', + on: { + complete: function(id,o,p) { + try { + var data = this.y3.JSON.parse(o.responseText); + } catch(e) { + alert(e.toString()); + return; + } + console.info(data); + if (data && data.length==0) { + node.isLeaf = true; + } else { + for (i in data) { + var mynode = { + label: data[i].filename, + href: data[i].url + }; + var tmp = new YAHOO.widget.TextNode(mynode, node, false); + if (data[i].isdir) { + tmp.isLeaf = false; + } else { + tmp.isLeaf = true; + tmp.target = '_blank'; + } + } + } + cb(); + } + }, + arguments: { + scope: scope + }, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + }, + data: build_querystring(params), + context: this + }; + this.y3.io(api, cfg); + }, + init : function(Y, options){ + var tree = new YAHOO.widget.TreeView('course-file-tree-view'); + tree.setDynamicLoad(this.dynload); + tree.subscribe("clickEvent", this.onclick); + var root = tree.getRoot(); + var children = root.children; + for (i in children) { + if (children[i].className == 'file-tree-folder') { + children[i].isLeaf = false; + } else { + children[i].isLeaf = true; + } + } + tree.render(); + this.y3 = Y; + }, + dynload: function(node, oncompletecb) { + M.core_filetree.request(node.href, node, oncompletecb); + }, + onclick: function(e) { + YAHOO.util.Event.preventDefault(e); + } +} diff --git a/lang/en/repository.php b/lang/en/repository.php index e7e05272979..61b636578ed 100644 --- a/lang/en/repository.php +++ b/lang/en/repository.php @@ -114,6 +114,7 @@ $string['manageurl'] = 'Manage'; $string['manageuserrepository'] = 'Manage individual repository'; $string['noenter'] = 'Nothing entered'; $string['nofilesattached'] = 'No files attached'; +$string['nofilesavailable'] = 'No files available'; $string['nomorefiles'] = 'No more attachments allowed'; $string['nopathselected'] = 'No destination path select yet (double click tree node to select)'; $string['nopermissiontoaccess'] = 'No permission to access this repository'; diff --git a/lib/outputcomponents.php b/lib/outputcomponents.php index 8c900f2e651..5d0e247112a 100644 --- a/lib/outputcomponents.php +++ b/lib/outputcomponents.php @@ -36,18 +36,18 @@ interface renderable { } /** - * Data structure representing a file tree viewer + * Data structure representing a area file tree viewer * * @copyright 2010 Dongsheng Cai * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since Moodle 2.0 */ -class file_tree_viewer implements renderable { +class area_file_tree_viewer implements renderable { public $dir; public $result; public $filearea; /** - * Constructor of file_tree_viewer class + * Constructor of area_file_tree_viewer class * @param int $contextid * @param string $area, file area * @param int $itemid @@ -86,6 +86,66 @@ class file_tree_viewer implements renderable { } } +/** + * Data structure representing a general moodle file tree viewer + * + * @copyright 2010 Dongsheng Cai + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class moodle_file_tree_viewer implements renderable { + public $tree; + public $path; + /** + * Constructor of moodle_file_tree_viewer class + * @param int $contextid + * @param string $area, file area + * @param int $itemid + * @param string $urlbase, file serving url base + */ + public function __construct($contextid, $filearea, $itemid, $filepath) { + global $CFG, $OUTPUT; + $this->tree = array(); + $browser = get_file_browser(); + $fileinfo = $browser->get_file_info(get_context_instance_by_id($contextid), $filearea, $itemid, $filepath); + $children = $fileinfo->get_children(); + $parent_info = $fileinfo->get_parent(); + + $level = $parent_info; + $this->path = array(); + while ($level) { + $params = $level->get_params(); + $url = new moodle_url('/files/index.php', $params); + $this->path[] = html_writer::link($url->out(false), $level->get_visible_name()); + $level = $level->get_parent(); + } + $this->path = array_reverse($this->path); + $this->path[] = $fileinfo->get_visible_name(); + + foreach ($children as $child) { + $filedate = $child->get_timemodified(); + $filesize = $child->get_filesize(); + $mimetype = $child->get_mimetype(); + $params = $child->get_params(); + $url = new moodle_url('/files/index.php', $params); + $fileitem = array( + 'params'=>$params, + 'filename'=>$child->get_visible_name(), + 'filedate'=>$filedate ? userdate($filedate) : '', + 'filesize'=>$filesize ? display_size($filesize) : '' + ); + if ($child->is_directory()) { + $fileitem['isdir'] = true; + $fileitem['url'] = $url->out(false); + } else { + $fileitem['url'] = $child->get_url(); + } + $this->tree[] = $fileitem; + } + + } +} + /** * Data structure representing a file picker. * @@ -2467,10 +2527,10 @@ class image_gallery implements renderable { if ($this->grouping !== null) { $image->link['rel'] .= "[{$this->grouping}]"; } - + $image->thumb['src'] = new moodle_url($thumburl); $image->thumb['alt'] = $alt; - + $this->images[] = $image; } } diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php index fd4088e858f..8de63e2baaa 100644 --- a/lib/outputrenderers.php +++ b/lib/outputrenderers.php @@ -1769,11 +1769,61 @@ class core_renderer extends renderer_base { return html_writer::tag('a', $output, $attributes); } + /** - * Print the file tree viewer + * General moodle file tree viwer * *
-     * $OUTPUT->file_tree_viewer($contextid, $filearea, $itemid, $urlbase);
+     * $OUTPUT->moodle_file_tree_viewer($contextid, $filearea, $itemid, $filepath);
+     * 
+ * + * @param int $contextid + * @param string $area + * @param int $itemid + * @param string $filepath + * @return string HTML fragment + */ + public function moodle_file_tree_viewer($contextid, $filearea, $itemid, $filepath) { + $tree = new moodle_file_tree_viewer($contextid, $filearea, $itemid, $filepath); + return $this->render($tree); + } + public function render_moodle_file_tree_viewer(moodle_file_tree_viewer $tree) { + $html = '
'; + foreach($tree->path as $path) { + $html .= $path; + $html .= ' / '; + } + $html .= '
'; + + $html .= '
'; + if (empty($tree->tree)) { + $html .= get_string('nofilesavailable', 'repository'); + } else { + $this->page->requires->js_init_call('M.core_filetree.init'); + $html .= '
    '; + foreach($tree->tree as $node) { + $link_attributes = array(); + if (!empty($node['isdir'])) { + $class = ' class="file-tree-folder"'; + } else { + $class = ' class="file-tree-file"'; + $link_attributes['target'] = '_blank'; + } + $html .= '
  • '; + $html .= html_writer::link($node['url'], $node['filename'], $link_attributes); + $html .= '
  • '; + } + $html .= '
'; + } + $html .= '
'; + return $html; + } + + /** + * Print the area file tree viewer + * + *
+     * $OUTPUT->area_file_tree_viewer($contextid, $filearea, $itemid, $urlbase);
      * 
* * @param int $contextid @@ -1782,17 +1832,17 @@ class core_renderer extends renderer_base { * @param string $urlbase * @return string HTML fragment */ - public function file_tree_viewer($contextid, $area, $itemid, $urlbase='') { - $tree = new file_tree_viewer($contextid, $area, $itemid, $urlbase); + public function area_file_tree_viewer($contextid, $area, $itemid, $urlbase='') { + $tree = new area_file_tree_viewer($contextid, $area, $itemid, $urlbase); return $this->render($tree); } /** - * Internal implementation of file tree viewer rendering. - * @param file_tree_viewer $tree + * Internal implementation of area file tree viewer rendering. + * @param area_file_tree_viewer $tree * @return string */ - public function render_file_tree_viewer(file_tree_viewer $tree) { + public function render_area_file_tree_viewer(area_file_tree_viewer $tree) { $this->page->requires->js_init_call('M.mod_folder.init_tree', array(true)); $html = ''; $html .= '
'; diff --git a/lib/outputrequirementslib.php b/lib/outputrequirementslib.php index cce683a96da..49c9873ff8c 100644 --- a/lib/outputrequirementslib.php +++ b/lib/outputrequirementslib.php @@ -427,6 +427,11 @@ class page_requirements_manager { 'fullpath' => '/rating/module.js', 'requires' => array('node', 'event', 'overlay', 'io', 'json')); break; + case 'core_filetree': + $module = array('name' => 'core_filetree', + 'fullpath' => '/files/module.js', + 'requires' => array('node', 'event', 'overlay', 'io', 'json', 'yui2-treeview')); + break; } } else { diff --git a/mod/folder/view.php b/mod/folder/view.php index 0523916d11e..c826f7c49e4 100644 --- a/mod/folder/view.php +++ b/mod/folder/view.php @@ -65,6 +65,6 @@ if (trim(strip_tags($folder->intro))) { } echo $OUTPUT->box_start('generalbox foldertree'); -echo $OUTPUT->file_tree_viewer($context->id, 'folder_content', 0); +echo $OUTPUT->area_file_tree_viewer($context->id, 'folder_content', 0); echo $OUTPUT->box_end(); echo $OUTPUT->footer();