]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-20066 new folder module, includes migrate from old mod/resource; remaining issues...
authorskodak <skodak>
Thu, 13 Aug 2009 20:47:43 +0000 (20:47 +0000)
committerskodak <skodak>
Thu, 13 Aug 2009 20:47:43 +0000 (20:47 +0000)
16 files changed:
lang/en_utf8/folder.php [new file with mode: 0644]
mod/folder/db/access.php [new file with mode: 0644]
mod/folder/db/install.php [new file with mode: 0644]
mod/folder/db/install.xml [new file with mode: 0644]
mod/folder/db/upgrade.php [new file with mode: 0644]
mod/folder/db/upgradelib.php [new file with mode: 0644]
mod/folder/functions.js [new file with mode: 0644]
mod/folder/icon.gif [new file with mode: 0644]
mod/folder/index.php [new file with mode: 0644]
mod/folder/lib.php [new file with mode: 0644]
mod/folder/locallib.php [new file with mode: 0644]
mod/folder/mod_form.php [new file with mode: 0644]
mod/folder/readme.txt [new file with mode: 0644]
mod/folder/settings.php [new file with mode: 0644]
mod/folder/version.php [new file with mode: 0644]
mod/folder/view.php [new file with mode: 0644]

diff --git a/lang/en_utf8/folder.php b/lang/en_utf8/folder.php
new file mode 100644 (file)
index 0000000..842a765
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$string['contentheader'] = 'Content';
+$string['foldercontent'] = 'Files and subfolders';
+$string['modulename'] = 'Folder';
+$string['modulenameplural'] = 'Folders';
+$string['neverseen'] = 'Never seen';
diff --git a/mod/folder/db/access.php b/mod/folder/db/access.php
new file mode 100644 (file)
index 0000000..5fdd8ea
--- /dev/null
@@ -0,0 +1,39 @@
+<?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/>.
+
+/**
+ * Capability definitions for the folder module.
+ *
+ * @package   mod-folder
+ * @copyright 2009 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$mod_folder_capabilities = array(
+/* TODO: review public portfolio API first!
+    'mod/folder:portfolioexport' => array(
+
+        'captype' => 'read',
+        'contextlevel' => CONTEXT_MODULE,
+        'legacy' => array(
+            'teacher' => CAP_ALLOW,
+            'editingteacher' => CAP_ALLOW,
+        )
+    ),*/
+
+);
+
diff --git a/mod/folder/db/install.php b/mod/folder/db/install.php
new file mode 100644 (file)
index 0000000..b5c9c9e
--- /dev/null
@@ -0,0 +1,50 @@
+<?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/>.
+
+/**
+ * Post installation and migration code.
+ *
+ * This file replaces:
+ *   - STATEMENTS section in db/install.xml
+ *   - lib.php/modulename_install() post installation hook
+ *   - partially defaults.php
+ *
+ * @package   mod-folder
+ * @copyright 2009 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+function xmldb_folder_install() {
+    global $CFG;
+
+    // Install logging support
+    update_log_display_entry('folder', 'view', 'folder', 'name');
+    update_log_display_entry('folder', 'view all', 'folder', 'name');
+    update_log_display_entry('folder', 'update', 'folder', 'name');
+    update_log_display_entry('folder', 'add', 'folder', 'name');
+
+    // Upgrade from old resource module type if needed
+    require_once("$CFG->dirroot/mod/folder/db/upgradelib.php");
+    folder_20_migrate();
+}
+
+function xmldb_folder_install_recovery() {
+    global $CFG;
+
+    require_once("$CFG->dirroot/mod/folder/db/upgradelib.php");
+    folder_20_migrate();
+}
\ No newline at end of file
diff --git a/mod/folder/db/install.xml b/mod/folder/db/install.xml
new file mode 100644 (file)
index 0000000..79ed132
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<XMLDB PATH="mod/folder/db" VERSION="20090722" COMMENT="XMLDB file for Folder module"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
+>
+  <TABLES>
+    <TABLE NAME="folder" COMMENT="each record is one folder resource">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="course"/>
+        <FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="name"/>
+        <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" PREVIOUS="course" NEXT="intro"/>
+        <FIELD NAME="intro" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" PREVIOUS="name" NEXT="introformat"/>
+        <FIELD NAME="introformat" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="intro" NEXT="revision"/>
+        <FIELD NAME="revision" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="incremented when after each file changes, solves browser caching issues" PREVIOUS="introformat" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="revision"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="course" UNIQUE="false" FIELDS="course"/>
+      </INDEXES>
+    </TABLE>
+  </TABLES>
+</XMLDB>
\ No newline at end of file
diff --git a/mod/folder/db/upgrade.php b/mod/folder/db/upgrade.php
new file mode 100644 (file)
index 0000000..27833ec
--- /dev/null
@@ -0,0 +1,54 @@
+<?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/>.
+
+/**
+ * Folder module upgrade code
+ *
+ * This file keeps track of upgrades to
+ * the resource module
+ *
+ * Sometimes, changes between versions involve
+ * alterations to database structures and other
+ * major things that may break installations.
+ *
+ * The upgrade function in this file will attempt
+ * to perform all the necessary actions to upgrade
+ * your older installtion to the current version.
+ *
+ * If there's something it cannot do itself, it
+ * will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral,
+ * using the methods of database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @package   mod-folder
+ * @copyright 2009 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+function xmldb_folder_upgrade($oldversion) {
+    global $CFG, $DB;
+
+    $dbman = $DB->get_manager();
+    $result = true;
+
+
+    return $result;
+}
diff --git a/mod/folder/db/upgradelib.php b/mod/folder/db/upgradelib.php
new file mode 100644 (file)
index 0000000..1d0c1bd
--- /dev/null
@@ -0,0 +1,93 @@
+<?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/>.
+
+/**
+ * Folder module upgrade related helper functions
+ *
+ * @package   mod-folder
+ * @copyright 2009 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Migrate folder module data from 1.9 resource_old table to new older table
+ * @return void
+ */
+function folder_20_migrate() {
+    global $CFG, $DB;
+    require_once("$CFG->libdir/filelib.php");
+    require_once("$CFG->dirroot/course/lib.php");
+
+    if (!file_exists("$CFG->dirroot/mod/resource/db/upgradelib.php")) {
+        // bad luck, somebody deleted resource module
+        return;
+    }
+
+    require_once("$CFG->dirroot/mod/resource/db/upgradelib.php");
+
+    // create resource_old table and copy resource table there if needed
+    if (!resource_20_prepare_migration()) {
+        // no modules or fresh install
+        return;
+    }
+
+    if (!$candidates = $DB->get_recordset('resource_old', array('type'=>'directory', 'migrated'=>0))) {
+        return;
+    }
+
+    $fs = get_file_storage();
+
+    foreach ($candidates as $candidate) {
+        upgrade_set_timeout();
+
+        $directory = '/'.trim($candidate->reference, '/').'/';
+        $directory = str_replace('//', '/', $directory);
+
+        $folder = new object();
+        $folder->course       = $candidate->course;
+        $folder->name         = $candidate->name;
+        $folder->intro        = $candidate->intro;
+        $folder->introformat  = $candidate->introformat;
+        $folder->revision     = 1;
+        $folder->timemodified = time();
+
+        if (!$folder = resource_migrate_to_module('folder', $candidate, $folder)) {
+            continue;
+        }
+
+        // copy files in given directory, skip moddata and backups!
+        $context       = get_context_instance(CONTEXT_MODULE, $candidate->cmid);
+        $coursecontext = get_context_instance(CONTEXT_COURSE, $candidate->course);
+        $files = $fs->get_directory_files($coursecontext->id, 'course_content', 0, $directory, true, true);
+        $file_record = array('contextid'=>$context->id, 'filearea'=>'folder_content', 'itemid'=>0);
+        foreach ($files as $file) {
+            $path = $file->get_filepath();
+            if (stripos($path, '/backupdata/') === 0 or stripos($path, '/moddata/') === 0) {
+                // do not publish protected data!
+                continue;
+            }
+            $relpath = substr($path, strlen($directory) - 1); // keep only subfolder paths
+            $file_record['filepath'] = $relpath;
+            $fs->create_file_from_storedfile($file_record, $file);
+        }
+    }
+
+    $candidates->close();
+
+    // clear all course modinfo caches
+    rebuild_course_cache(0, true);
+}
\ No newline at end of file
diff --git a/mod/folder/functions.js b/mod/folder/functions.js
new file mode 100644 (file)
index 0000000..c808561
--- /dev/null
@@ -0,0 +1,37 @@
+// 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/>.
+
+/**
+ * Javascript helper function for Folder module
+ *
+ * @package   mod-folder
+ * @copyright 2009 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+function folder_tree_init(expand_all) {
+    var tree = new YAHOO.widget.TreeView("folder_tree");
+
+    tree.subscribe("clickEvent", function(node, event) {
+        // we want normal clicking which redirects to url
+        return false;
+    });
+
+    if (expand_all) {
+        tree.expandAll();
+    }
+
+    tree.render();
+}
diff --git a/mod/folder/icon.gif b/mod/folder/icon.gif
new file mode 100644 (file)
index 0000000..11a7199
Binary files /dev/null and b/mod/folder/icon.gif differ
diff --git a/mod/folder/index.php b/mod/folder/index.php
new file mode 100644 (file)
index 0000000..a7d9f1e
--- /dev/null
@@ -0,0 +1,97 @@
+<?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/>.
+
+/**
+ * List of file folders in course
+ *
+ * @package   mod-folder
+ * @copyright 2009 onwards Martin Dougiamas (http://dougiamas.com)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require('../../config.php');
+
+$id = required_param('id', PARAM_INT); // course id
+
+$course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST);
+
+require_course_login($course, true);
+
+add_to_log($course->id, 'folder', 'view all', "index.php?id=$course->id", '');
+
+$strfolder       = get_string('modulename', 'folder');
+$strfolders      = get_string('modulenameplural', 'folder');
+$strweek         = get_string('week');
+$strtopic        = get_string('topic');
+$strname         = get_string('name');
+$strintro        = get_string('moduleintro');
+$strlastmodified = get_string('lastmodified');
+
+$PAGE->set_url('mod/folder/index.php', array('id' => $course->id));
+$PAGE->set_title($course->shortname.': '.$strfolders);
+$PAGE->set_heading($course->fullname);
+$navlinks = array(array('name' => $strfolders, 'link' => '', 'type' => 'activityinstance'));
+echo $OUTPUT->header(build_navigation($navlinks), navmenu($course));
+
+if (!$folders = get_all_instances_in_course('folder', $course)) {
+    notice(get_string('thereareno', 'moodle', $strfolders), "$CFG->wwwroot/course/view.php?id=$course->id");
+    exit;
+}
+
+$table = new html_table();
+$table->set_classes(array('generaltable', 'mod_index'));
+
+if ($course->format == 'weeks') {
+    $table->head  = array ($strweek, $strname, $strintro);
+    $table->align = array ('center', 'left', 'left');
+} else if ($course->format == 'topics') {
+    $table->head  = array ($strtopic, $strname, $strintro);
+    $table->align = array ('center', 'left', 'left');
+} else {
+    $table->head  = array ($strlastmodified, $strname, $strintro);
+    $table->align = array ('left', 'left', 'left');
+}
+
+$modinfo = get_fast_modinfo($course);
+$currentsection = '';
+foreach ($folders as $folder) {
+    $cm = $modinfo->cms[$folder->coursemodule];
+    if ($course->format == 'weeks' or $course->format == 'topics') {
+        $printsection = '';
+        if ($folder->section !== $currentsection) {
+            if ($folder->section) {
+                $printsection = $folder->section;
+            }
+            if ($currentsection !== '') {
+                $table->data[] = 'hr';
+            }
+            $currentsection = $folder->section;
+        }
+    } else {
+        $printsection = '<span class="smallinfo">'.userdate($folder->timemodified)."</span>";
+    }
+
+    $class = $folder->visible ? '' : 'class="dimmed"'; // hidden modules are dimmed
+    $table->data[] = array (
+        $printsection,
+        "<a $class href=\"view.php?id=$cm->id\">".format_string($folder->name)."</a>",
+        format_module_intro('folder', $folder, $cm->id));
+}
+
+echo $OUTPUT->table($table);
+
+echo $OUTPUT->footer();
diff --git a/mod/folder/lib.php b/mod/folder/lib.php
new file mode 100644 (file)
index 0000000..4842edc
--- /dev/null
@@ -0,0 +1,308 @@
+<?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/>.
+
+/**
+ * Mandatory public API of folder module
+ *
+ * @package   mod-folder
+ * @copyright 2009 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * List of features supported in Folder module
+ * @param string $feature FEATURE_xx constant for requested feature
+ * @return mixed True if module supports feature, false if not, null if doesn't know
+ */
+function folder_supports($feature) {
+    switch($feature) {
+        case FEATURE_MOD_ARCHETYPE:           return MOD_ARCHETYPE_RESOURCE;
+        case FEATURE_GROUPS:                  return false;
+        case FEATURE_GROUPINGS:               return false;
+        case FEATURE_GROUPMEMBERSONLY:        return true;
+        case FEATURE_MOD_INTRO:               return true;
+        case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
+        case FEATURE_GRADE_HAS_GRADE:         return false;
+        case FEATURE_GRADE_OUTCOMES:          return false;
+
+        default: return null;
+    }
+}
+
+/**
+ * Returns all other caps used in module
+ * @return array
+ */
+function folder_get_extra_capabilities() {
+    return array('moodle/site:accessallgroups');
+}
+
+/**
+ * This function is used by the reset_course_userdata function in moodlelib.
+ * @param $data the data submitted from the reset course.
+ * @return array status array
+ */
+function folder_reset_userdata($data) {
+    return array();
+}
+
+/**
+ * List of view style log actions
+ * @return array
+ */
+function folder_get_view_actions() {
+    return array('view', 'view all');
+}
+
+/**
+ * List of update style log actions
+ * @return array
+ */
+function folder_get_post_actions() {
+    return array('update', 'add');
+}
+
+/**
+ * Add folder instance.
+ * @param object $data
+ * @param object $mform
+ * @return int new folder instance id
+ */
+function folder_add_instance($data, $mform) {
+    global $DB;
+
+    $cmid        = $data->coursemodule;
+    $draftitemid = $data->files;
+
+    $data->timemodified = time();
+    $data->id = $DB->insert_record('folder', $data);
+
+    // we need to use context now, so we need to make sure all needed info is already in db
+    $DB->set_field('course_modules', 'instance', $data->id, array('id'=>$cmid));
+    $context = get_context_instance(CONTEXT_MODULE, $cmid);
+
+    if ($draftitemid) {
+        file_save_draft_area_files($draftitemid, $context->id, 'folder_content', 0, array('subdirs'=>true));
+    }
+
+    return $data->id;
+}
+
+/**
+ * Update folder instance.
+ * @param object $data
+ * @param object $mform
+ * @return bool true
+ */
+function folder_update_instance($data, $mform) {
+    global $CFG, $DB;
+
+    $cmid        = $data->coursemodule;
+    $draftitemid = $data->files;
+
+    $data->timemodified = time();
+    $data->id           = $data->instance;
+    $data->revision++;
+
+    $DB->update_record('folder', $data);
+
+    $context = get_context_instance(CONTEXT_MODULE, $cmid);
+    if ($draftitemid = file_get_submitted_draft_itemid('files')) {
+        file_save_draft_area_files($draftitemid, $context->id, 'folder_content', 0, array('subdirs'=>true));
+    }
+
+    return true;
+}
+
+/**
+ * Delete folder instance.
+ * @param int $id
+ * @return bool true
+ */
+function folder_delete_instance($id) {
+    global $DB;
+
+    if (!$folder = $DB->get_record('folder', array('id'=>$id))) {
+        return false;
+    }
+
+    // note: all context files are deleted automatically
+
+    $DB->delete_records('folder', array('id'=>$folder->id));
+
+    return true;
+}
+
+/**
+ * Return use outline
+ * @param object $course
+ * @param object $user
+ * @param object $mod
+ * @param object $folder
+ * @return object|null
+ */
+function folder_user_outline($course, $user, $mod, $folder) {
+    global $DB;
+
+    if ($logs = $DB->get_records('log', array('userid'=>$user->id, 'module'=>'folder',
+                                              'action'=>'view', 'info'=>$folder->id), 'time ASC')) {
+
+        $numviews = count($logs);
+        $lastlog = array_pop($logs);
+
+        $result = new object();
+        $result->info = get_string('numviews', '', $numviews);
+        $result->time = $lastlog->time;
+
+        return $result;
+    }
+    return NULL;
+}
+
+/**
+ * Return use complete
+ * @param object $course
+ * @param object $user
+ * @param object $mod
+ * @param object $folder
+ */
+function folder_user_complete($course, $user, $mod, $folder) {
+    global $CFG, $DB;
+
+    if ($logs = $DB->get_records('log', array('userid'=>$user->id, 'module'=>'folder',
+                                              'action'=>'view', 'info'=>$folder->id), 'time ASC')) {
+        $numviews = count($logs);
+        $lastlog = array_pop($logs);
+
+        $strmostrecently = get_string('mostrecently');
+        $strnumviews = get_string('numviews', '', $numviews);
+
+        echo "$strnumviews - $strmostrecently ".userdate($lastlog->time);
+
+    } else {
+        print_string('neverseen', 'folder');
+    }
+}
+
+/**
+ * Returns the users with data in one folder
+ *
+ * @param int $folderid
+ * @return bool false
+ */
+function folder_get_participants($folderid) {
+    return false;
+}
+
+/**
+ * Lists all browsable file areas
+ * @param object $course
+ * @param object $cm
+ * @param object $context
+ * @return array
+ */
+function folder_get_file_areas($course, $cm, $context) {
+    $areas = array();
+    if (has_capability('moodle/course:managefiles', $context)) {
+        $areas['folder_content'] = get_string('foldercontent', 'folder');
+    }
+    return $areas;
+}
+
+/**
+ * File browsing support for folder module ontent area.
+ * @param object $browser
+ * @param object $areas
+ * @param object $course
+ * @param object $cm
+ * @param object $context
+ * @param string $filearea
+ * @param int $itemid
+ * @param string $filepath
+ * @param string $filename
+ * @return object file_info instance or null if not found
+ */
+function folder_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
+    global $CFG;
+
+    $canwrite = has_capability('moodle/course:managefiles', $context);
+
+    $fs = get_file_storage();
+
+    if ($filearea === 'folder_content') {
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+
+        $urlbase = $CFG->wwwroot.'/pluginfile.php';
+        if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($context->id, $filearea, 0);
+            } else {
+                // not found
+                return null;
+            }
+        }
+        require_once("$CFG->dirroot/mod/folder/locallib.php");
+        return new folder_content_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, $canwrite, false);
+    }
+
+    // note: folder_intro handled in file_browser automatically
+
+    return null;
+}
+
+/**
+ * Serves the folder files.
+ *
+ * @param object $course
+ * @param object $cminfo
+ * @param object $context
+ * @param string $filearea
+ * @param array $args
+ * @param bool $forcedownload
+ * @return bool false if file not found, does not return if found - justsend the file
+ */
+function folder_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) {
+    global $CFG, $DB;
+
+    if (!$cminfo->uservisible) {
+        return false;
+    }
+
+    if ($filearea !== 'folder_content') {
+        // intro is handled automatically in pluginfile.php
+        return false;
+    }
+
+    if (!$cm = get_coursemodule_from_instance('folder', $cminfo->instance, $course->id)) {
+        return false;
+    }
+
+    require_course_login($course, true, $cm);
+
+    array_shift($args); // ignore revision - designed to prevent caching problems only
+
+    $fs = get_file_storage();
+    $relativepath = '/'.implode('/', $args);
+    $fullpath = $context->id.$filearea.'0'.$relativepath;
+    if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
+        return false;
+    }
+
+    // finally send the file
+    send_stored_file($file, 86400, 0, $forcedownload);
+}
diff --git a/mod/folder/locallib.php b/mod/folder/locallib.php
new file mode 100644 (file)
index 0000000..2d40259
--- /dev/null
@@ -0,0 +1,105 @@
+<?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/>.
+
+/**
+ * Private folder module utility functions
+ *
+ * @package   mod-folder
+ * @copyright 2009 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once("$CFG->dirroot/mod/folder/lib.php");
+require_once("$CFG->libdir/file/file_browser.php");
+require_once("$CFG->libdir/filelib.php");
+
+/**
+ * Prints file folder tree view
+ * @param object $folder instance
+ * @param object $cm instance
+ * @param object $course
+ * @return void
+ */
+function folder_print_tree($folder, $cm, $course) {
+    global $PAGE;
+
+    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
+    $fs = get_file_storage();
+    $dir = $fs->get_area_tree($context->id, 'folder_content', 0);
+    echo '<div id="folder_tree">';
+    echo folder_htmllize_tree($dir, $folder, $context);
+    echo '</div>';
+    $PAGE->requires->js_function_call('folder_tree_init', array(true));
+}
+
+/**
+ * Internal function - creates htmls structure suitable for YUI tree.
+ */
+function folder_htmllize_tree($dir, $folder, $context) {
+    if (empty($dir['subdirs']) and empty($dir['files'])) {
+        return '';
+    }
+    $result = '<ul>';
+    foreach ($dir['subdirs'] as $subdir) {
+        $result .= '<li>'.s($subdir['dirname']).' '.folder_htmllize_tree($subdir, $folder, $context).'</li>';
+    }
+    foreach ($dir['files'] as $file) {
+        $result .= '<li><span>'.folder_get_file_link($file, $folder, $context).'</span></li>';
+    }
+    $result .= '</ul>';
+
+    return $result;
+}
+
+/**
+ * Returns file link
+ * @param object $file
+ * @param object $folder
+ * @param object $context
+ * @return string html link
+ */
+function folder_get_file_link($file, $folder, $context) {
+    global $CFG;
+
+    $strfile     = get_string('file');
+    $strdownload = get_string('download');
+    $icon        = mimeinfo_from_type("icon", $file->get_mimetype());
+    $urlbase     = "$CFG->wwwroot/pluginfile.php";
+    $path        = '/'.$context->id.'/folder_content/'.$folder->revision.$file->get_filepath().$file->get_filename();
+    $viewurl     = file_encode_url($urlbase, $path, false);
+    $downloadurl = file_encode_url($urlbase, $path, true);
+    $downloadurl = "&nbsp;<a href=\"$downloadurl\" title=\"" . get_string('downloadfile') . "\"><img src=\"$CFG->pixpath/t/down.gif\" class=\"iconsmall\" alt=\"$strdownload\" /></a>";
+    return "<a href=\"$viewurl\" title=\"\"><img src=\"$CFG->pixpath/f/$icon\" class=\"icon\" alt=\"$strfile\" />&nbsp;".s($file->get_filename()).'</a>'.$downloadurl;
+}
+
+/**
+ * File browsing support class
+ */
+class folder_content_file_info extends file_info_stored {
+    public function get_parent() {
+        if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') {
+            return $this->browser->get_file_info($this->context);
+        }
+        return parent::get_parent();
+    }
+    public function get_visible_name() {
+        if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') {
+            return $this->topvisiblename;
+        }
+        return parent::get_visible_name();
+    }
+}
diff --git a/mod/folder/mod_form.php b/mod/folder/mod_form.php
new file mode 100644 (file)
index 0000000..706fd94
--- /dev/null
@@ -0,0 +1,71 @@
+<?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/>.
+
+/**
+ * Folder configuration form
+ *
+ * @package   mod-folder
+ * @copyright 2009 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once ($CFG->dirroot.'/course/moodleform_mod.php');
+
+class mod_folder_mod_form extends moodleform_mod {
+    function definition() {
+        global $CFG;
+        $mform = $this->_form;
+
+        $config = get_config('folder');
+
+        //-------------------------------------------------------
+        $mform->addElement('header', 'general', get_string('general', 'form'));
+        $mform->addElement('text', 'name', get_string('name'), array('size'=>'48'));
+        if (!empty($CFG->formatstringstriptags)) {
+            $mform->setType('name', PARAM_TEXT);
+        } else {
+            $mform->setType('name', PARAM_CLEAN);
+        }
+        $mform->addRule('name', null, 'required', null, 'client');
+        $this->add_intro_editor($config->requiremodintro);
+
+        //-------------------------------------------------------
+        $mform->addElement('header', 'content', get_string('contentheader', 'folder'));
+        $mform->addElement('static', 'note', '', '<i>(TODO: This filemanager does not support subdirectories yet, sorry...)</i>');
+        $mform->addElement('filemanager', 'files', get_string('files'));
+
+        //-------------------------------------------------------
+        $this->standard_coursemodule_elements();
+
+        //-------------------------------------------------------
+        $this->add_action_buttons();
+
+        //-------------------------------------------------------
+        $mform->addElement('hidden', 'revision');
+        $mform->setType('revision', PARAM_INT);
+        $mform->setDefault('revision', 1);
+    }
+
+    function data_preprocessing(&$default_values) {
+        if ($this->current->instance) {
+            // editing existing instance - copy existing files into draft area
+            $draftitemid = file_get_submitted_draft_itemid('files');
+            file_prepare_draft_area($draftitemid, $this->context->id, 'folder_content', 0, array('subdirs'=>true));
+            $default_values['files'] = $draftitemid;
+        }
+    }
+}
diff --git a/mod/folder/readme.txt b/mod/folder/readme.txt
new file mode 100644 (file)
index 0000000..f66f0f1
--- /dev/null
@@ -0,0 +1,33 @@
+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/>.
+
+copyright 2009 Petr Skoda (http://skodak.org)
+license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+
+
+Folder module
+=============
+
+Folder module is a successor to original 'directory' type plugin of Resource module.
+
+This module is intended for distribution of large number of documents.
+
+TODO:
+ * reimplement portfolio support (?)
+ * implement subdirectory support in File picker (Dongsheng)
+ * new backup/restore (Eloy)
+ * old restore support (Eloy)
+ * improve folder view UI (skodak)
+
diff --git a/mod/folder/settings.php b/mod/folder/settings.php
new file mode 100644 (file)
index 0000000..0d4e41d
--- /dev/null
@@ -0,0 +1,30 @@
+<?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/>.
+
+/**
+ * Folder module admin settings and defaults
+ *
+ * @package   mod-folder
+ * @copyright 2009 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+if ($ADMIN->fulltree) {
+    //--- general settings -----------------------------------------------------------------------------------
+    $settings->add(new admin_setting_configcheckbox('folder/requiremodintro',
+        get_string('requiremodintro', 'admin'), get_string('configrequiremodintro', 'admin'), 1));
+}
diff --git a/mod/folder/version.php b/mod/folder/version.php
new file mode 100644 (file)
index 0000000..3203170
--- /dev/null
@@ -0,0 +1,29 @@
+<?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/>.
+
+/**
+ * Folder module version information
+ *
+ * @package   mod-folder
+ * @copyright 2009 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$module->version  = 2009080500;
+$module->requires = 2009073101;  // Requires this Moodle version
+$module->cron     = 0;
+
diff --git a/mod/folder/view.php b/mod/folder/view.php
new file mode 100644 (file)
index 0000000..e316cb6
--- /dev/null
@@ -0,0 +1,71 @@
+<?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/>.
+
+/**
+ * Folder module main user interface
+ *
+ * @package   mod-folder
+ * @copyright 2009 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require('../../config.php');
+require_once("$CFG->dirroot/mod/folder/locallib.php");
+
+$id = optional_param('id', 0, PARAM_INT);  // Course module ID
+$f  = optional_param('f', 0, PARAM_INT);   // Folder instance id
+
+if ($f) {  // Two ways to specify the module
+    $folder = $DB->get_record('folder', array('id'=>$f), '*', MUST_EXIST);
+    $cm = get_coursemodule_from_instance('folder', $folder->id, $folder->course, false, MUST_EXIST);
+
+} else {
+    $cm = get_coursemodule_from_id('folder', $id, 0, false, MUST_EXIST);
+    $folder = $DB->get_record('folder', array('id'=>$cm->instance), '*', MUST_EXIST);
+}
+
+$course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST);
+
+require_course_login($course, true, $cm);
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+
+add_to_log($course->id, 'folder', 'view', 'view.php?id='.$cm->id, $folder->id, $cm->id);
+
+$PAGE->set_url('mod/folder/view.php', array('id' => $cm->id));
+$PAGE->requires->yui_lib('json');
+$PAGE->requires->yui_lib('treeview');
+$PAGE->requires->js('mod/folder/functions.js');
+
+$PAGE->set_title($course->shortname.': '.$folder->name);
+$PAGE->set_heading($course->fullname);
+$PAGE->set_activity_record($folder);
+$PAGE->set_button(update_module_button($cm->id, '', get_string('modulename', 'folder')));
+echo $OUTPUT->header(build_navigation('', $cm), navmenu($course, $cm));
+
+echo $OUTPUT->heading(format_string($folder->name), 2);
+
+if (trim(strip_tags($folder->intro))) {
+    echo $OUTPUT->box_start('mod_introbox', 'pageintro');
+    echo format_module_intro('folder', $folder, $cm->id);
+    echo $OUTPUT->box_end();
+}
+
+echo $OUTPUT->box_start('generalbox foldertree');
+folder_print_tree($folder, $cm, $course);
+echo $OUTPUT->box_end();
+
+echo $OUTPUT->footer();