MDL-22950 adding new component column to the files table, unfortunately this change...
authorPetr Skoda <skodak@moodle.org>
Sat, 3 Jul 2010 13:37:13 +0000 (13:37 +0000)
committerPetr Skoda <skodak@moodle.org>
Sat, 3 Jul 2010 13:37:13 +0000 (13:37 +0000)
220 files changed:
admin/bloglevelupgrade.php
admin/settings/grades.php
backup/backup_execute.html
backup/backuplib.php
backup/moodle2/backup_stepslib.php
backup/util/dbops/backup_structure_dbops.class.php
backup/util/helper/backup_helper.class.php
backup/util/structure/backup_nested_element.class.php
backup/util/structure/backup_structure_processor.class.php
backup/util/structure/simpletest/testbackupstructures.php
backup/util/ui/backup_ui_stage.class.php
blocks/community/locallib.php
blocks/course_summary/block_course_summary.php
blocks/html/block_html.php
blocks/html/edit_form.php
blocks/html/lib.php [new file with mode: 0644]
blocks/private_files/block_private_files.php
blocks/private_files/edit.php [new file with mode: 0644]
blocks/private_files/edit_form.php [new file with mode: 0644]
blog/edit.php
blog/locallib.php
calendar/lib.php
course/category.php
course/edit.php
course/editcategory.php
course/editsection.php
course/format/topics/format.php
course/format/weeks/format.php
course/info.php
course/lib.php
course/modedit.php
course/publish/metadata.php
course/scales.php
draftfile.php
file.php
files/draftfiles.php [deleted file]
files/externallib.php
files/filebrowser_ajax.php [new file with mode: 0755]
files/files_ajax.php [deleted file]
files/index.php
files/module.js
files/renderer.php [new file with mode: 0644]
grade/edit/outcome/edit.php
grade/edit/scale/edit.php
grade/edit/tree/grade_form.php
group/group.php
group/grouping.php
group/lib.php
group/overview.php
index.php
lang/en/error.php
lang/en/portfolio.php
lib/db/install.xml
lib/db/upgrade.php
lib/db/upgradelib.php
lib/file/file_browser.php [deleted file]
lib/file/file_info_course.php [deleted file]
lib/file/file_info_coursefile.php [deleted file]
lib/file/file_info_coursesection.php [deleted file]
lib/file/file_info_coursesectionbackup.php [deleted file]
lib/file/file_info_module.php [deleted file]
lib/file/file_info_user.php [deleted file]
lib/filebrowser/file_browser.php [new file with mode: 0644]
lib/filebrowser/file_info.php [moved from lib/file/file_info.php with 87% similarity]
lib/filebrowser/file_info_context_course.php [new file with mode: 0644]
lib/filebrowser/file_info_context_coursecat.php [moved from lib/file/file_info_coursecat.php with 51% similarity]
lib/filebrowser/file_info_context_module.php [new file with mode: 0644]
lib/filebrowser/file_info_context_system.php [moved from lib/file/file_info_system.php with 74% similarity]
lib/filebrowser/file_info_context_user.php [new file with mode: 0644]
lib/filebrowser/file_info_stored.php [moved from lib/file/file_info_stored.php with 80% similarity]
lib/filebrowser/virtual_root_file.php [moved from lib/file/virtual_root_file.php with 82% similarity]
lib/filelib.php
lib/filestorage/file_archive.php [moved from lib/packer/file_archive.php with 94% similarity]
lib/filestorage/file_exceptions.php [moved from lib/file/file_exceptions.php with 61% similarity]
lib/filestorage/file_packer.php [moved from lib/packer/file_packer.php with 85% similarity]
lib/filestorage/file_storage.php [moved from lib/file/file_storage.php with 87% similarity]
lib/filestorage/file_types.mm [moved from lib/file/file_types.mm with 100% similarity]
lib/filestorage/stored_file.php [moved from lib/file/stored_file.php with 92% similarity]
lib/filestorage/zip_archive.php [moved from lib/packer/zip_archive.php with 96% similarity]
lib/filestorage/zip_packer.php [moved from lib/packer/zip_packer.php with 91% similarity]
lib/form/filemanager.js
lib/form/filemanager.php
lib/form/filepicker.php
lib/form/htmleditor.php
lib/formslib.php
lib/grade/grade_outcome.php
lib/grade/grade_scale.php
lib/moodlelib.php
lib/navigationlib.php
lib/outputcomponents.php
lib/outputrenderers.php
lib/portfolio/caller.php
lib/portfolio/exporter.php
lib/portfoliolib.php
lib/resourcelib.php
lib/setuplib.php
lib/simpletest/broken_testfilelib.php
lib/weblib.php
mod/assignment/backup/moodle2/backup_assignment_stepslib.php
mod/assignment/db/upgrade.php
mod/assignment/lib.php
mod/assignment/locallib.php
mod/assignment/type/online/assignment.class.php
mod/assignment/type/online/file.php
mod/assignment/type/upload/assignment.class.php
mod/assignment/type/uploadsingle/assignment.class.php
mod/chat/backup/moodle2/backup_chat_stepslib.php
mod/choice/backup/moodle2/backup_choice_stepslib.php
mod/data/db/upgrade.php
mod/data/field/file/field.class.php
mod/data/field/picture/field.class.php
mod/data/lib.php
mod/feedback/backup/moodle2/backup_feedback_stepslib.php
mod/feedback/item/label/lib.php
mod/feedback/lib.php
mod/folder/backup/moodle2/backup_folder_stepslib.php
mod/folder/db/upgradelib.php
mod/folder/edit.php
mod/folder/edit_form.php
mod/folder/lib.php
mod/folder/locallib.php
mod/folder/mod_form.php
mod/folder/renderer.php [new file with mode: 0644]
mod/folder/view.php
mod/forum/backup/moodle2/backup_forum_stepslib.php
mod/forum/db/upgrade.php
mod/forum/lib.php
mod/forum/locallib.php
mod/forum/post.php
mod/glossary/backup/moodle2/backup_glossary_stepslib.php
mod/glossary/db/upgrade.php
mod/glossary/deleteentry.php
mod/glossary/edit.php
mod/glossary/exportentry.php
mod/glossary/lib.php
mod/glossary/locallib.php
mod/imscp/backup/moodle2/backup_imscp_stepslib.php
mod/imscp/db/upgradelib.php
mod/imscp/lib.php
mod/imscp/locallib.php
mod/imscp/mod_form.php
mod/label/backup/moodle2/backup_label_stepslib.php
mod/lesson/backup/moodle2/backup_lesson_stepslib.php
mod/lesson/db/upgrade.php
mod/lesson/importppt.php
mod/lesson/lib.php
mod/lesson/locallib.php
mod/lesson/mod_form.php
mod/lesson/pagetypes/endofbranch.php
mod/lesson/pagetypes/endofcluster.php
mod/lesson/pagetypes/essay.php
mod/lesson/pagetypes/matching.php
mod/page/backup/moodle2/backup_page_stepslib.php
mod/page/db/upgradelib.php
mod/page/lib.php
mod/page/mod_form.php
mod/page/view.php
mod/resource/backup/moodle2/backup_resource_stepslib.php
mod/resource/db/upgrade.php
mod/resource/db/upgradelib.php
mod/resource/lib.php
mod/resource/locallib.php
mod/resource/mod_form.php
mod/resource/view.php
mod/scorm/backup/moodle2/backup_scorm_stepslib.php
mod/scorm/datamodels/aicclib.php
mod/scorm/db/install.xml
mod/scorm/db/upgrade.php
mod/scorm/lib.php
mod/scorm/loadSCO.php
mod/scorm/locallib.php
mod/survey/backup/moodle2/backup_survey_stepslib.php
mod/url/backup/moodle2/backup_url_stepslib.php
mod/url/db/upgradelib.php
mod/url/locallib.php
mod/wiki/backup/moodle2/backup_wiki_stepslib.php
mod/wiki/db/upgrade.php
mod/wiki/edit_form.php
mod/wiki/editors/wikifiletable.php
mod/wiki/lib.php
mod/wiki/locallib.php
mod/wiki/pagelib.php
mod/wiki/renderer.php
mod/workshop/db/upgrade.php
mod/workshop/exsubmission.php
mod/workshop/fileinfolib.php
mod/workshop/form/accumulative/lib.php
mod/workshop/form/comments/lib.php
mod/workshop/form/numerrors/lib.php
mod/workshop/form/rubric/lib.php
mod/workshop/lib.php
mod/workshop/mod_form.php
mod/workshop/renderer.php
mod/workshop/submission.php
mod/workshop/view.php
pluginfile.php
repository/draftfiles_ajax.php [new file with mode: 0755]
repository/dropbox/repository.class.php
repository/filepicker.js
repository/filepicker.php
repository/flickr/repository.class.php
repository/googledocs/repository.class.php
repository/lib.php
repository/local/repository.class.php
repository/picasa/repository.class.php
repository/recent/repository.class.php
repository/repository_ajax.php
repository/repository_callback.php [new file with mode: 0755]
repository/upload/repository.class.php
repository/user/repository.class.php
tag/edit.php
tag/lib.php
tag/locallib.php
user/edit.php
user/editadvanced.php
user/index.php
user/profile.php
user/view.php
userfile.php [deleted file]
version.php

index b04d1dc..07eec72 100644 (file)
@@ -103,24 +103,26 @@ function bloglevelupgrade_entries($blogentries, $forum, $cm, $groupid=-1) {
 
         // Copy file attachment records
         $fs = get_file_storage();
-        $files = $fs->get_area_files($sitecontext->id, 'blog_attachment', $blogentry->id);
+        $files = $fs->get_area_files($sitecontext->id, 'blog', 'attachment', $blogentry->id);
 
         if (!empty($files)) {
             foreach ($files as $storedfile) {
                 $newfile = new object();
-                $newfile->filearea = 'forum_attachment';
+                $newfile->component = 'mod_forum';
+                $newfile->filearea = 'attachment';
                 $newfile->itemid = $discussion->firstpost;
                 $newfile->contextid = $forumcontext->id;
                 $fs->create_file_from_storedfile($newfile, $storedfile->get_id());
             }
         }
 
-        $files = $fs->get_area_files($sitecontext->id, 'blog_post', $blogentry->id);
+        $files = $fs->get_area_files($sitecontext->id, 'blog', 'post', $blogentry->id);
 
         if (!empty($files)) {
             foreach ($files as $storedfile) {
                 $newfile = new object();
-                $newfile->filearea = 'forum_post';
+                $newfile->component = 'mod_forum';
+                $newfile->filearea = 'post';
                 $newfile->itemid = $discussion->firstpost;
                 $newfile->contextid = $forumcontext->id;
                 $fs->create_file_from_storedfile($newfile, $storedfile->get_id());
index d2680ab..65457c6 100644 (file)
@@ -26,8 +26,7 @@ if (has_capability('moodle/grade:manage', $systemcontext)
         // new CFG variable for gradebook (what roles to display)
         $temp->add(new admin_setting_special_gradebookroles());
 
-        // enable outcomes checkbox
-        $temp->add(new admin_setting_configcheckbox('enableoutcomes', get_string('enableoutcomes', 'grades'), get_string('enableoutcomes_help', 'grades'), 0));
+        // enable outcomes checkbox now in subsystems area
 
         $temp->add(new admin_setting_grade_profilereport());
 
index ebc76b5..5edf378 100644 (file)
@@ -76,7 +76,7 @@
         //Print final message
         echo $OUTPUT->box(get_string("backupfinished"));
         $context = get_context_instance(CONTEXT_COURSE, $course->id);
-        echo $OUTPUT->continue_button("$CFG->wwwroot/files/index.php?contextid=".$context->id."&filearea=course_backup&itemid=0");
+        echo $OUTPUT->continue_button("$CFG->wwwroot/files/index.php?contextid=".$context->id."&component=backup&filearea=course&itemid=0");
     } else {
         echo $OUTPUT->box(get_string('importdataexported'));
         if (!empty($preferences->backup_destination)) {
index 0a4c3f5..7ea5225 100644 (file)
             //Define zip destination (course dir)
             $context = get_context_instance(CONTEXT_COURSE, $preferences->backup_course);
             $fs = get_file_storage();
-            $file_record = array('contextid'=>$context->id, 'filearea'=>'course_backup',
+            $file_record = array('contextid'=>$context->id, 'component'=>'backup', 'filearea'=>'course',
                     'itemid'=>0, 'filepath'=>'/', 'filename'=>$preferences->backup_name,
                     'timecreated'=>time(), 'timemodified'=>time());
             $fs->create_file_from_pathname($file_record, $from_zip_file);
index e9631b3..422a79f 100644 (file)
@@ -232,7 +232,7 @@ class backup_section_structure_step extends backup_structure_step {
         $section->set_source_alias('section', 'number');
 
         // Set annotations
-        $section->annotate_files(array('course_section'), 'id');
+        $section->annotate_files('course', 'section', 'id');
 
         return $section;
     }
@@ -311,7 +311,8 @@ class backup_course_structure_step extends backup_structure_step {
 
         $course->annotate_ids('grouping', 'defaultgroupingid');
 
-        $course->annotate_files(array('course_summary', 'course_content'), null);
+        $course->annotate_files('course', 'summary', null);
+        $course->annotate_files('course', 'legacy', null);
 
         // Return root element ($course)
 
@@ -656,8 +657,9 @@ class backup_groups_structure_step extends backup_structure_step {
 
         // Define file annotations
 
-        // TODO: Change "course_group_image" file area to the one finally used for group images
-        $group->annotate_files(array('course_group_description', 'course_group_image'), 'id');
+        //TODO: not implemented yet
+        $group->annotate_files('group', 'description', 'id');
+        $group->annotate_files('group', 'image', 'id');
 
         // Return the root element (groups)
         return $groups;
@@ -980,7 +982,7 @@ class backup_final_files_structure_step extends backup_structure_step {
         $files = new backup_nested_element('files');
 
         $file = new file_nested_element('file', array('id'), array(
-            'contenthash', 'contextid', 'filearea', 'itemid',
+            'contenthash', 'contextid', 'component', 'filearea', 'itemid',
             'filepath', 'filename', 'userid', 'filesize',
             'mimetype', 'status', 'timecreated', 'timemodified',
             'source', 'author', 'license', 'sortorder'));
@@ -1238,9 +1240,8 @@ class backup_annotate_all_user_files extends backup_execution_step {
         global $DB;
 
         // List of fileareas we are going to annotate
-        // TODO: Change "user_image" file area to the one finally used for user images
-        $fileareas = array(
-            'user_private', 'user_profile', 'user_image');
+        // TODO: user image not implemented yet
+        $fileareas = array('private', 'profile', 'image');
 
         // Fetch all annotated (final) users
         $rs = $DB->get_recordset('backup_ids_temp', array(
@@ -1252,7 +1253,7 @@ class backup_annotate_all_user_files extends backup_execution_step {
             foreach ($fileareas as $filearea) {
                 // We don't need to specify itemid ($userid - 4th param) as far as by
                 // context we can get all the associated files. See MDL-22092
-                backup_structure_dbops::annotate_files($this->get_backupid(), $userctxid, $filearea, null);
+                backup_structure_dbops::annotate_files($this->get_backupid(), $userctxid, 'user', $filearea, null);
             }
         }
         $rs->close();
index 4621385..ee2cdd1 100644 (file)
@@ -103,13 +103,14 @@ abstract class backup_structure_dbops extends backup_dbops {
         }
     }
 
-    public static function annotate_files($backupid, $contextid, $filearea, $itemid) {
+    public static function annotate_files($backupid, $contextid, $component, $filearea, $itemid) {
         global $DB;
         $sql = 'SELECT id
                   FROM {files}
                  WHERE contextid = ?
+                   AND component = ?
                    AND filearea = ?';
-        $params = array($contextid, $filearea);
+        $params = array($contextid, $component, $filearea);
 
         if (!is_null($itemid)) { // Add itemid to query and params if necessary
             $sql .= ' AND itemid = ?';
index dca3778..9247356 100644 (file)
@@ -182,7 +182,7 @@ abstract class backup_helper {
 
         // Extract useful information to decide
         $hasusers  = (bool)$sinfo['users']->value;     // Backup has users
-        $isannon   = (bool)$sinfo['anonymize']->value; // Backup is annonymzed
+        $isannon   = (bool)$sinfo['anonymize']->value; // Backup is anonymised
         $filename  = $sinfo['filename']->value;        // Backup filename
         $backupmode= $dinfo[0]->mode;                  // Backup mode backup::MODE_GENERAL/IMPORT/HUB
         $backuptype= $dinfo[0]->type;                  // Backup type backup::TYPE_1ACTIVITY/SECTION/COURSE
@@ -203,24 +203,28 @@ abstract class backup_helper {
         }
 
         // Calculate file storage options of id being backup
-        $ctxid    = 0;
-        $filearea = '';
-        $itemid   = 0;
+        $ctxid     = 0;
+        $filearea  = '';
+        $component = '';
+        $itemid    = 0;
         switch ($backuptype) {
             case backup::TYPE_1ACTIVITY:
-                $ctxid    = get_context_instance(CONTEXT_MODULE, $id)->id;
-                $filearea = 'activity_backup';
-                $itemid   = 0;
+                $ctxid     = get_context_instance(CONTEXT_MODULE, $id)->id;
+                $component = 'backup';
+                $filearea  = 'activity';
+                $itemid    = 0;
                 break;
             case backup::TYPE_1SECTION:
-                $ctxid    = get_context_instance(CONTEXT_COURSE, $courseid)->id;
-                $filearea = 'section_backup';
-                $itemid   = $id;
+                $ctxid     = get_context_instance(CONTEXT_COURSE, $courseid)->id;
+                $component = 'backup';
+                $filearea  = 'section';
+                $itemid    = $id;
                 break;
             case backup::TYPE_1COURSE:
-                $ctxid    = get_context_instance(CONTEXT_COURSE, $courseid)->id;
-                $filearea = 'course_backup';
-                $itemid   = 0;
+                $ctxid     = get_context_instance(CONTEXT_COURSE, $courseid)->id;
+                $component = 'backup';
+                $filearea  = 'course';
+                $itemid    = 0;
                 break;
         }
 
@@ -228,25 +232,28 @@ abstract class backup_helper {
         // are sent to user's "user_tohub" file area. The upload process
         // will be responsible for cleaning that filearea once finished
         if ($backupmode == backup::MODE_HUB) {
-            $ctxid = get_context_instance(CONTEXT_USER, $userid)->id;
-            $filearea = 'user_tohub';
-            $itemid   = 0;
+            $ctxid     = get_context_instance(CONTEXT_USER, $userid)->id;
+            $component = 'user';
+            $filearea  = 'tohub';
+            $itemid    = 0;
         }
 
-        // Backups without user info or withe the anoymise functionality
+        // Backups without user info or with the anonymise functionality
         // enabled are sent to user's "user_backup"
         // file area. Maintenance of such area is responsibility of
         // the user via corresponding file manager frontend
         if ($backupmode == backup::MODE_GENERAL && (!$hasusers || $isannon)) {
-            $ctxid = get_context_instance(CONTEXT_USER, $userid)->id;
-            $filearea = 'user_backup';
-            $itemid   = 0;
+            $ctxid     = get_context_instance(CONTEXT_USER, $userid)->id;
+            $component = 'user';
+            $filearea  = 'backup';
+            $itemid    = 0;
         }
 
         // Let's send the file to file storage, everything already defined
         $fs = get_file_storage();
         $fr = array(
             'contextid'   => $ctxid,
+            'component'   => $component,
             'filearea'    => $filearea,
             'itemid'      => $itemid,
             'filepath'    => '/',
@@ -257,8 +264,8 @@ abstract class backup_helper {
         // If file already exists, delete if before
         // creating it again. This is BC behaviour - copy()
         // overwrites by default
-        if ($fs->file_exists($fr['contextid'], $fr['filearea'], $fr['itemid'], $fr['filepath'], $fr['filename'])) {
-            $pathnamehash = $fs->get_pathname_hash($fr['contextid'], $fr['filearea'], $fr['itemid'], $fr['filepath'], $fr['filename']);
+        if ($fs->file_exists($fr['contextid'], $fr['component'], $fr['filearea'], $fr['itemid'], $fr['filepath'], $fr['filename'])) {
+            $pathnamehash = $fs->get_pathname_hash($fr['contextid'], $fr['component'], $fr['filearea'], $fr['itemid'], $fr['filepath'], $fr['filename']);
             $sf = $fs->get_file_by_hash($pathnamehash);
             $sf->delete();
         }
index 274b6e6..b69b21d 100644 (file)
@@ -35,8 +35,7 @@ class backup_nested_element extends base_nested_element implements processable {
     protected $params;    // Unprocessed params as specified in the set_source() call
     protected $procparams;// Processed (path resolved) params array
     protected $aliases;   // Define DB->final element aliases
-    protected $fileannotelement; // Element to be used as itemid for file annotations
-    protected $fileannotareas;   // array of file areas to be searched by file annotations
+    protected $fileannotations;   // array of file areas to be searched by file annotations
     protected $counter;   // Number of instances of this element that have been processed
 
     /**
@@ -54,8 +53,7 @@ class backup_nested_element extends base_nested_element implements processable {
         $this->params    = null;
         $this->procparams= null;
         $this->aliases   = array();
-        $this->fileannotelement = null;
-        $this->fileannotareas   = array();
+        $this->fileannotations = array();
         $this->counter   = 0;
     }
 
@@ -148,21 +146,21 @@ class backup_nested_element extends base_nested_element implements processable {
         }
     }
 
-    public function annotate_files($areas, $elementname) {
-        if (!is_array($areas)) { // Check we are passing array
-            throw new base_element_struct_exception('annotate_files_requires_array_of_areas', $areas);
-        }
-        $annotations = $this->get_file_annotations();
-        if (!empty($annotations[0])) { // Check we haven't defined file annotations already
-            throw new base_element_struct_exception('annotate_files_already_defined', $this->get_name());
+    public function annotate_files($component, $filearea, $elementname) {
+        // note: it is possible to annotate areas ONLY in current context, ie modules may backup only from module context
+        if (!array_key_exists($component, $this->fileannotations)) {
+            $this->fileannotations[$component] = array();
         }
+
         if ($elementname !== null) { // Check elementname is valid
-            $element = $this->find_element($elementname);
-            // Annotate the element
-            $this->fileannotelement= $element;
+            $elementname = $this->find_element($elementname); //TODO: no warning here? (skodak)
+        }
+
+        if (array_key_exists($filearea, $this->fileannotations[$component])) {
+            throw new base_element_struct_exception('annotate_files_duplicate_annotation', "$component/$filearea/$elementname");
         }
-        // Annotate the areas
-        $this->fileannotareas  = $areas;
+
+        $this->fileannotations[$component][$filearea] = $elementname;
     }
 
     public function annotate_ids($itemname, $elementname) {
@@ -175,10 +173,7 @@ class backup_nested_element extends base_nested_element implements processable {
      * @backup_structure and the areas to be searched
      */
     public function get_file_annotations() {
-        if (empty($this->fileannotareas)) {
-            return array(null, null);
-        }
-        return array($this->fileannotareas, $this->fileannotelement);
+        return $this->fileannotations;
     }
 
     public function get_source_array() {
index 3504d91..6d3e2f6 100644 (file)
@@ -67,13 +67,15 @@ class backup_structure_processor extends base_processor {
 
     public function process_nested_element(base_nested_element $nested) {
         // Proceed with all the file annotations for this element
-        list($fileareas, $element) = $nested->get_file_annotations();
-        if ($fileareas) { // If there are areas to search
-            $backupid = $this->get_var(backup::VAR_BACKUPID);
-            $contextid= $this->get_var(backup::VAR_CONTEXTID);
-            $itemid   = !is_null($element) ? $element->get_value() : null;
-            foreach ($fileareas as $filearea) {
-                backup_structure_dbops::annotate_files($backupid, $contextid, $filearea, $itemid);
+        $fileannotations = $nested->get_file_annotations();
+        if ($fileannotations) { // If there are areas to search
+            $backupid  = $this->get_var(backup::VAR_BACKUPID);
+            $contextid = $this->get_var(backup::VAR_CONTEXTID);
+            foreach ($fileannotations as $component=>$area) {
+                foreach ($area as $filearea=>$element) {
+                    $itemid = !is_null($element) ? $element->get_value() : null;
+                    backup_structure_dbops::annotate_files($backupid, $contextid, $component, $filearea, $itemid);
+                }
             }
         }
     }
index 5a1f63f..e9cb102 100644 (file)
@@ -82,14 +82,14 @@ class backup_structure_test extends UnitTestCaseUsingDatabase {
         // With two related file
         $f1_forum_data = (object)array(
                                      'contenthash' => 'testf1', 'contextid' => $this->contextid,
-                                     'filearea' => 'forum_intro', 'filename' => 'tf1', 'itemid' => 0,
+                                     'component'=>'mod_forum', 'filearea' => 'intro', 'filename' => 'tf1', 'itemid' => 0,
                                      'filesize' => 123, 'timecreated' => 0, 'timemodified' => 0,
                                      'pathnamehash' => 'testf1'
                                  );
         $DB->insert_record('files', $f1_forum_data);
         $f2_forum_data = (object)array(
                                      'contenthash' => 'tesft2', 'contextid' => $this->contextid,
-                                     'filearea' => 'forum_intro', 'filename' => 'tf2', 'itemid' => 0,
+                                     'component'=>'mod_forum', 'filearea' => 'intro', 'filename' => 'tf2', 'itemid' => 0,
                                      'filesize' => 123, 'timecreated' => 0, 'timemodified' => 0,
                                      'pathnamehash' => 'testf2'
                                  );
@@ -112,15 +112,15 @@ class backup_structure_test extends UnitTestCaseUsingDatabase {
         $p4id = $DB->insert_record('forum_posts', $post4);
         // With two related file
         $f1_post1 = (object)array(
-                                'contenthash' => 'testp1', 'contextid' => $this->contextid,
-                                'filearea' => 'forum_post', 'filename' => 'tp1', 'itemid' => $p1id,
+                                'contenthash' => 'testp1', 'contextid' => $this->contextid, 'component'=>'mod_forum',
+                                'filearea' => 'post', 'filename' => 'tp1', 'itemid' => $p1id,
                                 'filesize' => 123, 'timecreated' => 0, 'timemodified' => 0,
                                 'pathnamehash' => 'testp1'
                             );
         $DB->insert_record('files', $f1_post1);
         $f1_post2 = (object)array(
-                                'contenthash' => 'testp2', 'contextid' => $this->contextid,
-                                'filearea' => 'forum_attachment', 'filename' => 'tp2', 'itemid' => $p2id,
+                                'contenthash' => 'testp2', 'contextid' => $this->contextid, 'component'=>'mod_forum',
+                                'filearea' => 'attachment', 'filename' => 'tp2', 'itemid' => $p2id,
                                 'filesize' => 123, 'timecreated' => 0, 'timemodified' => 0,
                                 'pathnamehash' => 'testp2'
                             );
@@ -293,10 +293,11 @@ class backup_structure_test extends UnitTestCaseUsingDatabase {
         $rating->set_source_alias('rating', 'post_rating'); // Map the 'rating' value from DB to 'post_rating' final element
 
         // Mark to detect files of type 'forum_intro' in forum (and not item id)
-        $forum->annotate_files(array('forum_intro'), null);
+        $forum->annotate_files('mod_forum', 'intro', null);
 
         // Mark to detect file of type 'forum_post' and 'forum_attachment' in post (with itemid being post->id)
-        $post->annotate_files(array('forum_post', 'forum_attachment'), 'id');
+        $post->annotate_files('mod_forun', 'post', 'id');
+        $post->annotate_files('mod_forum', 'attachment', 'id');
 
         // Mark various elements to be annotated
         $discussion->annotate_ids('user1', 'userid');
@@ -569,30 +570,21 @@ class backup_structure_test extends UnitTestCaseUsingDatabase {
         }
 
         // Try various incorrect file annotations
-        $ne = new backup_nested_element('test', 'one', 'two', 'three');
-        try {
-            $ne->annotate_files('notanarray', null); // Incorrect first param
-            $this->assertTrue(false, 'base_element_struct_exception expected');
-        } catch (exception $e) {
-            $this->assertTrue($e instanceof base_element_struct_exception);
-            $this->assertEqual($e->errorcode, 'annotate_files_requires_array_of_areas');
-            $this->assertEqual($e->a, 'notanarray');
-        }
 
         $ne = new backup_nested_element('test', 'one', 'two', 'three');
-        $ne->annotate_files(array('test_filearea'), null);
+        $ne->annotate_files('test', 'filearea', null);
         try {
-            $ne->annotate_files(array('test_filearea'), null); // Try to add annotations twice
+            $ne->annotate_files('test', 'filearea', null); // Try to add annotations twice
             $this->assertTrue(false, 'base_element_struct_exception expected');
         } catch (exception $e) {
             $this->assertTrue($e instanceof base_element_struct_exception);
-            $this->assertEqual($e->errorcode, 'annotate_files_already_defined');
+            $this->assertEqual($e->errorcode, 'annotate_files_duplicate_annotation');
             $this->assertEqual($e->a, 'test');
         }
 
         $ne = new backup_nested_element('test', 'one', 'two', 'three');
         try {
-            $ne->annotate_files(array('test_filearea'), 'four'); // Incorrect element
+            $ne->annotate_files('test', 'filearea', 'four'); // Incorrect element
             $this->assertTrue(false, 'base_element_struct_exception expected');
         } catch (exception $e) {
             $this->assertTrue($e instanceof base_element_struct_exception);
index 37fb704..ed49c1a 100644 (file)
@@ -140,7 +140,7 @@ abstract class backup_ui_stage {
 
 /**
  * Class representing the initial stage of a backup.
- * 
+ *
  * In this stage the user is required to set the root level settings.
  *
  * @copyright 2010 Sam Hemelryk
@@ -243,7 +243,7 @@ class backup_ui_stage_initial extends backup_ui_stage {
  *
  * During the schema stage the user is required to set the settings that relate
  * to the area that they are backing up as well as its children.
- * 
+ *
  * @copyright 2010 Sam Hemelryk
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -298,7 +298,7 @@ class backup_ui_stage_schema extends backup_ui_stage {
             return $changes;
         } else {
             return false;
-        }        
+        }
     }
     /**
      * Creates the backup_schema_form instance for this stage
@@ -439,7 +439,7 @@ class backup_ui_stage_confirmation extends backup_ui_stage {
                 foreach ($task->get_settings() as $setting) {
                     // For this stage only the filename setting should be editable
                     if ($setting->get_name() != 'filename') {
-                        $form->add_fixed_setting($setting);   
+                        $form->add_fixed_setting($setting);
                     }
                 }
             }
@@ -534,12 +534,13 @@ class backup_ui_stage_complete extends backup_ui_stage_final {
      */
     public function display() {
         global $OUTPUT;
-        
+
         // Get the resulting stored_file record
         $file = $this->results['backup_destination'];
         // Turn it into a url for the file browser
         $fileurl = new moodle_url('/files/index.php', array(
             'contextid' => $file->get_contextid(),
+            'component' => $file->get_component(),
             'filearea' => $file->get_filearea(),
             'itemid' => $file->get_itemid(),
             'filepath' => $file->get_filepath()
index d6e75e2..2f843d1 100644 (file)
@@ -98,11 +98,12 @@ class block_community_manager {
 
         $fs = get_file_storage();
         $record->contextid = get_context_instance(CONTEXT_USER, $USER->id)->id;
-        $record->filearea = 'user_backup';
+        $record->component = 'user';
+        $record->filearea = 'backup';
         $record->itemid = 0;
         $record->filename = 'backup_'.$course->fullname."_".$course->id.".zip";
         $record->filepath = '/';
-        if (!$fs->file_exists($record->contextid, $record->filearea, 0, $record->filepath, $record->filename)) {
+        if (!$fs->file_exists($record->contextid, $record->component, $record->filearea, 0, $record->filepath, $record->filename)) {
             $fs->create_file_from_pathname($record, $CFG->dataroot.'/temp/communitydownload/'.'backup_'.$course->fullname."_".$course->id.".zip");
         }
         //delete temp file
index 94d7431..e223ca2 100644 (file)
@@ -27,7 +27,7 @@ class block_course_summary extends block_base {
         $options = new object();
         $options->noclean = true;    // Don't clean Javascripts etc
         $context = get_context_instance(CONTEXT_COURSE, $this->page->course->id);
-        $this->page->course->summary = file_rewrite_pluginfile_urls($this->page->course->summary, 'pluginfile.php', $context->id, 'course_summary', NULL);
+        $this->page->course->summary = file_rewrite_pluginfile_urls($this->page->course->summary, 'pluginfile.php', $context->id, 'course', 'summary', NULL);
         $this->content->text = format_text($this->page->course->summary, $this->page->course->summaryformat, $options);
         if ($this->page->user_is_editing()) {
             if($this->page->course->id == SITEID) {
index 5e43ced..91910a0 100755 (executable)
@@ -1,5 +1,28 @@
 <?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/>.
+
+/**
+ * Form for editing HTML block instances.
+ *
+ * @package   block_html
+ * @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
 class block_html extends block_base {
 
     function init() {
@@ -36,7 +59,7 @@ class block_html extends block_base {
         $this->content->footer = '';
         if (isset($this->config->text)) {
             // rewrite url
-            $this->config->text['text'] = file_rewrite_pluginfile_urls($this->config->text['text'], 'pluginfile.php', $this->context->id, 'block_html', $this->instance->id);
+            $this->config->text['text'] = file_rewrite_pluginfile_urls($this->config->text['text'], 'pluginfile.php', $this->context->id, 'block_html', 'content', NULL);
             $this->content->text = format_text($this->config->text['text'], $this->config->text['format'], $filteropt);
         } else {
             $this->content->text = '';
@@ -55,7 +78,7 @@ class block_html extends block_base {
         global $DB;
 
         // Move embedded files into a proper filearea and adjust HTML links to match
-        $data->text['text'] = file_save_draft_area_files($data->text['itemid'], $this->context->id, 'block_html', $this->instance->id, array('subdirs'=>true), $data->text['text']);
+        $data->text['text'] = file_save_draft_area_files($data->text['itemid'], $this->context->id, 'block_html', 'content', 0, array('subdirs'=>true), $data->text['text']);
 
         parent::instance_config_save($data, $nolongerused);
     }
@@ -63,7 +86,7 @@ class block_html extends block_base {
     function instance_delete() {
         global $DB;
         $fs = get_file_storage();
-        $fs->delete_area_files($this->context->id, 'block_html', $this->instance->id);
+        $fs->delete_area_files($this->context->id, 'block_html');
         return true;
     }
 
@@ -121,16 +144,4 @@ class block_html extends block_base {
 
         return true;
     }
-
-    function send_file($context, $filearea, $itemid, $filepath, $filename) {
-        $fs = get_file_storage();
-        $fullpath = $context->id.'block_html'.$itemid.$filepath.$filename;
-
-        if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
-            send_file_not_found();
-        }
-
-        session_get_instance()->write_close();
-        send_stored_file($file, 60*60, 0, false);
-    }
 }
index ece488b..e8ef73a 100644 (file)
@@ -18,7 +18,7 @@
 /**
  * Form for editing HTML block instances.
  *
- * @package   moodlecore
+ * @package   block_html
  * @copyright 2009 Tim Hunt
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -50,7 +50,7 @@ class block_html_edit_form extends block_edit_form {
         } else {
             $currenttext = $block->config->text['text'];
         }
-        $block->config->text['text'] = file_prepare_draft_area($draftid_editor, $block->context->id, 'block_html', $block->instance->id, array('subdirs'=>true), $currenttext);
+        $block->config->text['text'] = file_prepare_draft_area($draftid_editor, $block->context->id, 'block_html', 'content', 0, array('subdirs'=>true), $currenttext);
         $block->config->text['itemid'] = $draftid_editor;
         parent::set_data($defaults);
     }
diff --git a/blocks/html/lib.php b/blocks/html/lib.php
new file mode 100644 (file)
index 0000000..009eeaf
--- /dev/null
@@ -0,0 +1,49 @@
+<?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/>.
+
+/**
+ * Form for editing HTML block instances.
+ *
+ * @package   block_html
+ * @copyright 2010 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+function block_html_pluginfile($course, $birecord_or_cm, $context, $filearea, $args, $forcedownload) {
+
+    if ($context->contextlevel != CONTEXT_BLOCK) {
+        send_file_not_found();
+    }
+
+    require_course_login($course);
+
+    if ($filearea !== 'content') {
+        send_file_not_found();
+    }
+
+    $fs = get_file_storage();
+
+    $filename = array_pop($args);
+    $filepath = '/'.implode('/', $args);
+
+    if (!$file = $fs->get_file($context->id, 'block_html', 'content', 0, $filepath, $filename) or $file->is_directory()) {
+        send_file_not_found();
+    }
+
+    session_get_instance()->write_close();
+    send_stored_file($file, 60*60, 0, $forcedownload);
+}
index bbd6b58..7f69be0 100755 (executable)
@@ -19,8 +19,7 @@
 /**
  * Manage user private area files
  *
- * @package    moodlecore
- * @subpackage repository
+ * @package    block_private_files
  * @copyright  2010 Dongsheng Cai <dongsheng@moodle.com>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -47,12 +46,14 @@ class block_private_files extends block_base {
 
     function get_content() {
         global $CFG, $USER, $PAGE, $OUTPUT;
+
         if ($this->content !== NULL) {
             return $this->content;
         }
         if (empty($this->instance)) {
             return null;
         }
+
         $this->content->text = '';
         $this->content->footer = '';
         if (isloggedin() && !isguestuser()) {   // Show the block
@@ -60,16 +61,18 @@ class block_private_files extends block_base {
             $options = new stdclass;
             $options->maxbytes  = -1;
             $options->maxfiles  = -1;
-            $options->filearea  = 'user_private';
-            $options->itemid    = 0;
             $options->subdirs   = true;
             $options->accepted_types = '*';
             $options->return_types = FILE_INTERNAL;
             $options->context   = $PAGE->context;
             $options->disable_types = array('user');
 
-            $this->content = new stdClass;
-            $this->content->text = $OUTPUT->file_manager($options);
+            $this->content = new object();
+
+            //TODO: add capability check here!
+
+            //TODO: add list of available files here
+            $this->content->text = $OUTPUT->single_button(new moodle_url('/blocks/private_files/edit.php'), get_string('edit'), 'get');
 ;
             $this->content->footer = '';
 
diff --git a/blocks/private_files/edit.php b/blocks/private_files/edit.php
new file mode 100644 (file)
index 0000000..687f927
--- /dev/null
@@ -0,0 +1,58 @@
+<?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/>.
+
+/**
+ * Manage files in folder in private area - to be replaced by something better hopefully....
+ *
+ * @package   block_private_files
+ * @copyright 2010 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/blocks/private_files/edit_form.php");
+require_once("$CFG->dirroot/repository/lib.php");
+
+require_login();
+if (isguestuser()) {
+    die();
+}
+//TODO: add capability check here!
+
+$context = get_context_instance(CONTEXT_USER, $USER->id);
+
+$PAGE->set_url('/blocks/private/edit.php');
+
+$data = new object();
+$options = array('subdirs'=>1, 'maxbytes'=>$CFG->userquota, 'maxfiles'=>-1, 'accepted_types'=>'*', 'return_types'=>FILE_INTERNAL);
+file_prepare_standard_filemanager($data, 'files', $options, $context, 'user', 'private', 0);
+
+$mform = new block_private_files_form(null, array('data'=>$data, 'options'=>$options));
+
+if ($mform->is_cancelled()) {
+    redirect(new moodle_url('/my/'));
+
+} else if ($formdata = $mform->get_data()) {
+    $formdata = file_postupdate_standard_filemanager($formdata, 'files', $options, $context, 'user', 'private', 0);
+    redirect(new moodle_url('/my/'));
+}
+
+echo $OUTPUT->header();
+echo $OUTPUT->box_start('generalbox');
+$mform->display();
+echo $OUTPUT->box_end();
+echo $OUTPUT->footer();
diff --git a/blocks/private_files/edit_form.php b/blocks/private_files/edit_form.php
new file mode 100644 (file)
index 0000000..81accb5
--- /dev/null
@@ -0,0 +1,43 @@
+<?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/>.
+
+/**
+ * minimalistic edit form
+ *
+ * @package   block_private_files
+ * @copyright 2010 Petr Skoda (http://skodak.org)
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once("$CFG->libdir/formslib.php");
+
+class block_private_files_form extends moodleform {
+    function definition() {
+        $mform = $this->_form;
+
+        $data    = $this->_customdata['data'];
+        $options = $this->_customdata['options'];
+
+        $mform->addElement('filemanager', 'files_filemanager', get_string('files'), null, $options);
+
+        $this->add_action_buttons(true, get_string('submit'));
+
+        $this->set_data($data);
+    }
+}
index a4e0257..ba5bdfc 100755 (executable)
@@ -94,7 +94,7 @@ if ($id) {
     $userid = $entry->userid;
     $entry->subject      = clean_text($entry->subject);
     $entry->summary      = clean_text($entry->summary, $entry->format);
-    
+
 } else {
     if (!has_capability('moodle/blog:create', $sitecontext)) {
         print_error('noentry', 'blog'); // manageentries is not enough for adding
@@ -163,8 +163,8 @@ $attachmentoptions = array('subdirs'=>false, 'maxfiles'=> 99, 'maxbytes'=>$CFG->
 
 $blogeditform = new blog_edit_form(null, compact('entry', 'summaryoptions', 'attachmentoptions', 'sitecontext', 'courseid', 'modid'));
 
-$entry = file_prepare_standard_editor($entry, 'summary', $summaryoptions, $sitecontext, 'blog_post', $entry->id);
-$entry = file_prepare_standard_filemanager($entry, 'attachment', $attachmentoptions, $sitecontext, 'blog_attachment', $entry->id);
+$entry = file_prepare_standard_editor($entry, 'summary', $summaryoptions, $sitecontext, 'blog', 'post', $entry->id);
+$entry = file_prepare_standard_filemanager($entry, 'attachment', $attachmentoptions, $sitecontext, 'blog', 'attachment', $entry->id);
 
 if (!empty($CFG->usetags) && !empty($entry->id)) {
     include_once($CFG->dirroot.'/tag/lib.php');
index da01dc5..0135b0c 100644 (file)
@@ -110,7 +110,7 @@ class blog_entry {
             $cmt->showcount = $CFG->blogshowcommentscount;
             $options->comments = $cmt;
         }
-        $this->summary = file_rewrite_pluginfile_urls($this->summary, 'pluginfile.php', SYSCONTEXTID, 'blog_post', $this->id);
+        $this->summary = file_rewrite_pluginfile_urls($this->summary, 'pluginfile.php', SYSCONTEXTID, 'blog', 'post', $this->id);
 
         $template['body'] = format_text($this->summary, $this->summaryformat, $options);
         $template['title'] = format_string($this->subject);
@@ -369,8 +369,8 @@ class blog_entry {
             $entry->$var = $val;
         }
 
-        $entry = file_postupdate_standard_editor($entry, 'summary', $summaryoptions, $sitecontext, 'blog_post', $entry->id);
-        $entry = file_postupdate_standard_filemanager($entry, 'attachment', $attachmentoptions, $sitecontext, 'blog_attachment', $entry->id);
+        $entry = file_postupdate_standard_editor($entry, 'summary', $summaryoptions, $sitecontext, 'blog', 'post', $entry->id);
+        $entry = file_postupdate_standard_filemanager($entry, 'attachment', $attachmentoptions, $sitecontext, 'blog', 'attachment', $entry->id);
 
         if (!empty($CFG->useblogassociations)) {
             $entry->add_associations();
@@ -462,8 +462,8 @@ class blog_entry {
      */
     public function delete_attachments() {
         $fs = get_file_storage();
-        $fs->delete_area_files(SYSCONTEXTID, 'blog_attachment', $this->id);
-        $fs->delete_area_files(SYSCONTEXTID, 'blog_post', $this->id);
+        $fs->delete_area_files(SYSCONTEXTID, 'blog', 'attachment', $this->id);
+        $fs->delete_area_files(SYSCONTEXTID, 'blog', 'post', $this->id);
     }
 
     /**
@@ -480,9 +480,8 @@ class blog_entry {
         require_once($CFG->libdir.'/filelib.php');
 
         $fs = get_file_storage();
-        $browser = get_file_browser();
 
-        $files = $fs->get_area_files(SYSCONTEXTID, 'blog_attachment', $this->id);
+        $files = $fs->get_area_files(SYSCONTEXTID, 'blog', 'attachment', $this->id);
 
         $imagereturn = "";
         $output = "";
@@ -495,7 +494,7 @@ class blog_entry {
             }
 
             $filename = $file->get_filename();
-            $ffurl    = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.SYSCONTEXTID.'/blog_attachment/'.$this->id.'/'.$filename);
+            $ffurl    = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.SYSCONTEXTID.'/blog/attachment/'.$this->id.'/'.$filename);
             $mimetype = $file->get_mimetype();
 
             $icon     = substr(mimeinfo_from_type("icon", $mimetype), 0, -4);
index a5da6f8..fc78b91 100644 (file)
@@ -1626,11 +1626,6 @@ class calendar_event {
      * @var string
      */
     protected $_description = null;
-    /**
-     * The filearea to use with this event
-     * @var string
-     */
-    protected static $filearea = 'calendar_event_description';
     /**
      * The options to use with this description editor
      * @var array
@@ -1790,7 +1785,7 @@ class calendar_event {
             }
 
             // Convert file paths in the description so that things display correctly
-            $this->_description = file_rewrite_pluginfile_urls($this->properties->description, 'pluginfile.php', $this->editorcontext->id, self::$filearea, $itemid);
+            $this->_description = file_rewrite_pluginfile_urls($this->properties->description, 'pluginfile.php', $this->editorcontext->id, 'calendar', 'event_description', $itemid);
             // Clean the text so no nasties get through
             $this->_description = clean_text($this->_description, $this->properties->format);
         }
@@ -1883,7 +1878,8 @@ class calendar_event {
                 $this->properties->description = file_save_draft_area_files(
                                                 $editor['itemid'],
                                                 $this->editorcontext->id,
-                                                self::$filearea,
+                                                'calendar',
+                                                'event_description',
                                                 $this->properties->id,
                                                 $this->editoroptions,
                                                 $editor['text'],
@@ -1914,7 +1910,7 @@ class calendar_event {
                     // If the context has been set delete all associated files
                     if ($usingeditor) {
                         $fs = get_file_storage();
-                        $files = $fs->get_area_files($this->editorcontext->id, self::$filearea, $this->properties->id);
+                        $files = $fs->get_area_files($this->editorcontext->id, 'calendar', 'event_description', $this->properties->id);
                         foreach ($files as $file) {
                             $fs->create_file_from_storedfile(array('itemid'=>$eventcopyid), $file);
                         }
@@ -1940,7 +1936,8 @@ class calendar_event {
                     $this->properties->description = file_save_draft_area_files(
                                                     $this->properties->description['itemid'],
                                                     $this->editorcontext->id,
-                                                    self::$filearea,
+                                                    'calendar',
+                                                    'event_description',
                                                     $this->properties->id,
                                                     $this->editoroptions,
                                                     $this->properties->description['text'],
@@ -2035,7 +2032,7 @@ class calendar_event {
         // If the context has been set delete all associated files
         if ($this->editorcontext !== null) {
             $fs = get_file_storage();
-            $files = $fs->get_area_files($this->editorcontext->id, self::$filearea, $this->properties->id);
+            $files = $fs->get_area_files($this->editorcontext->id, 'calendar', 'event_description', $this->properties->id);
             foreach ($files as $file) {
                 $file->delete();
             }
@@ -2133,7 +2130,7 @@ class calendar_event {
                 // Just encase it has already been submitted
                 $draftiddescription = file_get_submitted_draft_itemid('description');
                 // Prepare the draft area, this copies existing files to the draft area as well
-                $properties->description = file_prepare_draft_area($draftiddescription, $contextid, self::$filearea, $properties->id, $this->editoroptions, $properties->description);
+                $properties->description = file_prepare_draft_area($draftiddescription, $contextid, 'calendar', 'event_description', $properties->id, $this->editoroptions, $properties->description);
             } else {
                 $draftiddescription = 0;
             }
index 2b9128a..35dd01b 100644 (file)
         if (!isset($category->descriptionformat)) {
             $category->descriptionformat = FORMAT_MOODLE;
         }
-        $text = file_rewrite_pluginfile_urls($category->description, 'pluginfile.php', $context->id, 'category_description', $category->id);
+        $text = file_rewrite_pluginfile_urls($category->description, 'pluginfile.php', $context->id, 'coursecat', 'description', null);
         echo format_text($text, $category->descriptionformat, $options);
         echo $OUTPUT->box_end();
     }
index 2b2d9e4..45dd3c0 100644 (file)
@@ -74,10 +74,10 @@ if (!empty($course)) {
         }
     }
     $course->allowedmods = $allowedmods;
-    $course = file_prepare_standard_editor($course, 'summary', $editoroptions, $coursecontext, 'course_summary', 0);
+    $course = file_prepare_standard_editor($course, 'summary', $editoroptions, $coursecontext, 'course', 'summary', 0);
 
 } else {
-    $course = file_prepare_standard_editor($course, 'summary', $editoroptions, null, 'course_summary', null);
+    $course = file_prepare_standard_editor($course, 'summary', $editoroptions, null, 'course', 'summary', null);
 }
 
 // first create the form
index ae4037f..34d66a1 100644 (file)
@@ -42,7 +42,7 @@ if ($id) {
 }
 
 $editoroptions = array('maxfiles' => EDITOR_UNLIMITED_FILES, 'maxbytes'=>$CFG->maxbytes, 'trusttext'=>true);
-$category = file_prepare_standard_editor($category, 'description', $editoroptions, $editorcontext, 'category_description', $category->id);
+$category = file_prepare_standard_editor($category, 'description', $editoroptions, $editorcontext, 'coursecat', 'description', 0);
 
 $mform = new editcategory_form('editcategory.php', compact('category', 'editoroptions'));
 $mform->set_data($category);
@@ -82,7 +82,7 @@ if ($mform->is_cancelled()) {
         mark_context_dirty($newcategory->context->path);
     }
 
-    $newcategory = file_postupdate_standard_editor($newcategory, 'description', $editoroptions, $categorycontext, 'category_description', $newcategory->id);
+    $newcategory = file_postupdate_standard_editor($newcategory, 'description', $editoroptions, $categorycontext, 'coursecat', 'description', 0);
     $DB->update_record('course_categories', $newcategory);
     fix_course_sortorder();
 
index aa1c08e..1b56288 100644 (file)
@@ -40,7 +40,7 @@ $context = get_context_instance(CONTEXT_COURSE, $course->id);
 require_capability('moodle/course:update', $context);
 
 $editoroptions = array('maxfiles' => EDITOR_UNLIMITED_FILES, 'maxbytes'=>$CFG->maxbytes, 'trusttext'=>false, 'noclean'=>true);
-$section = file_prepare_standard_editor($section, 'summary', $editoroptions, $context, 'course_section', $section->id);
+$section = file_prepare_standard_editor($section, 'summary', $editoroptions, $context, 'course', 'section', $section->id);
 $section->usedefaultname = (is_null($section->name));
 $mform = new editsection_form(null, array('course'=>$course, 'editoroptions'=>$editoroptions));
 $mform->set_data($section); // set current value
@@ -55,7 +55,7 @@ if ($mform->is_cancelled()){
     } else {
         $section->name = null;
     }
-    $data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $context, 'course_section', $section->id);
+    $data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $context, 'course', 'section', $section->id);
     $section->summary = $data->summary;
     $section->summaryformat = $data->summaryformat;
     $DB->update_record('course_sections', $section);
index 834fc35..8ba44c6 100644 (file)
@@ -104,7 +104,7 @@ if ($thissection->summary or $thissection->sequence or $PAGE->user_is_editing())
     echo '<div class="summary">';
 
     $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-    $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course_section', $thissection->id);
+    $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $thissection->id);
     $summaryformatoptions = new object();
     $summaryformatoptions->noclean = true;
     echo format_text($summarytext, $thissection->summaryformat, $summaryformatoptions);
@@ -231,7 +231,7 @@ while ($section <= $course->numsections) {
             echo '<div class="summary">';
             if ($thissection->summary) {
                 $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-                $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course_section', $thissection->id);
+                $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $thissection->id);
                 $summaryformatoptions = new object();
                 $summaryformatoptions->noclean = true;
                 echo format_text($summarytext, $thissection->summaryformat, $summaryformatoptions);
index 08cc37b..f68247f 100644 (file)
@@ -95,7 +95,7 @@
         echo '<div class="summary">';
 
         $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-        $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course_section', $thissection->id);
+        $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $thissection->id);
         $summaryformatoptions = new object();
         $summaryformatoptions->noclean = true;
         echo format_text($summarytext, $thissection->summaryformat, $summaryformatoptions);
                 }
                 echo '<div class="summary">';
                 $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-                $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course_section', $thissection->id);
+                $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $thissection->id);
                 $summaryformatoptions = new object();
                 $summaryformatoptions->noclean = true;
                 echo format_text($summarytext, $thissection->summaryformat, $summaryformatoptions);
index 9c0d32a..e62ccb9 100644 (file)
@@ -62,7 +62,7 @@
 
     echo $OUTPUT->box_start('generalbox info');
 
-    $course->summary = file_rewrite_pluginfile_urls($course->summary, 'pluginfile.php', $context->id, 'course_summary', NULL);
+    $course->summary = file_rewrite_pluginfile_urls($course->summary, 'pluginfile.php', $context->id, 'course', 'summary', NULL);
     echo format_text($course->summary, $course->summaryformat, NULL, $course->id);
 
     if (!empty($CFG->coursecontact)) {
index 8aeacf6..34019ad 100644 (file)
@@ -2226,7 +2226,7 @@ function print_course($course, $highlightterms = '') {
     $context = get_context_instance(CONTEXT_COURSE, $course->id);
 
     // Rewrite file URLs so that they are correct
-    $course->summary = file_rewrite_pluginfile_urls($course->summary, 'pluginfile.php', $context->id, 'course_summary', NULL);
+    $course->summary = file_rewrite_pluginfile_urls($course->summary, 'pluginfile.php', $context->id, 'course', 'summary', NULL);
 
     $linkcss = $course->visible ? '' : ' class="dimmed" ';
 
@@ -3483,7 +3483,7 @@ function create_course($data, $editoroptions = NULL) {
 
     if ($editoroptions) {
         // Save the files used in the summary editor and store
-        $data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $context, 'course_summary', 0);
+        $data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $context, 'course', 'summary', 0);
         $DB->set_field('course', 'summary', $data->summary, array('id'=>$newcourseid));
         $DB->set_field('course', 'summaryformat', $data->summary_format, array('id'=>$newcourseid));
     }
@@ -3548,7 +3548,7 @@ function update_course($data, $editoroptions = NULL) {
     $context   = get_context_instance(CONTEXT_COURSE, $oldcourse->id);
 
     if ($editoroptions) {
-        $data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $context, 'course_summary', 0);
+        $data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $context, 'course', 'summary', 0);
     }
 
     if (!isset($data->category) or empty($data->category)) {
@@ -3631,6 +3631,9 @@ function average_number_of_courses_modules() {
  * This class pertains to course requests and contains methods associated with
  * create, approving, and removing course requests.
  *
+ * Please note we do not allow embedded images here because there is no context
+ * to store them with proper access control.
+ *
  * @copyright 2009 Sam Hemelryk
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @since Moodle 2.0
@@ -3661,22 +3664,6 @@ class course_request {
      */
     protected static $summaryeditoroptions;
 
-    /**
-     * The context used when working with files for the summary editor
-     * This is initially set by {@link summary_editor_context()}
-     * @var stdClass
-     * @static
-     */
-    protected static $summaryeditorcontext;
-
-    /**
-     * The string used to identify the file area for course_requests
-     * This is initially set by {@link summary_editor_context()}
-     * @var string
-     * @static
-     */
-    protected static $summaryeditorfilearea = 'course_request_summary';
-
     /**
      * Static function to prepare the summary editor for working with a course
      * request.
@@ -3692,7 +3679,7 @@ class course_request {
         if ($data === null) {
             $data = new stdClass;
         }
-        $data = file_prepare_standard_editor($data, 'summary', self::summary_editor_options(), self::summary_editor_context(), self::summary_editor_filearea(), null);
+        $data = file_prepare_standard_editor($data, 'summary', self::summary_editor_options());
         return $data;
     }
 
@@ -3709,19 +3696,13 @@ class course_request {
     public static function create($data) {
         global $USER, $DB, $CFG;
         $data->requester = $USER->id;
-        $editorused = (!empty($data->summary_editor));
-        // Has summary_editor been set. If so we have come through with a editor and
-        // may need to save files
-        if ($editorused && empty($data->summary)) {
-            // Summary is a required field so copy the text over
-            $data->summary = $data->summary_editor['text'];
-        }
+
+        // Summary is a required field so copy the text over
+        $data->summary       = $data->summary_editor['text'];
+        $data->summaryformat = $data->summary_editor['format'];
+
         $data->id = $DB->insert_record('course_request', $data);
-        if ($editorused) {
-            // Save any files and then update the course with the fixed data
-            $data = file_postupdate_standard_editor($data, 'summary', self::summary_editor_options(), self::summary_editor_context(), self::summary_editor_filearea(), $data->id);
-            $DB->update_record('course_request', $data);
-        }
+
         // Create a new course_request object and return it
         $request = new course_request($data);
 
@@ -3750,31 +3731,11 @@ class course_request {
     public static function summary_editor_options() {
         global $CFG;
         if (self::$summaryeditoroptions === null) {
-            self::$summaryeditoroptions = array('maxfiles' => 0, 'maxbytes'=>0, 'trusttext'=>true);
+            self::$summaryeditoroptions = array('maxfiles' => 0, 'maxbytes'=>0);
         }
         return self::$summaryeditoroptions;
     }
 
-    /**
-     * Returns the context to use with the summary editor
-     *
-     * @uses course_request::$summaryeditorcontext
-     * @return stdClass The context to use
-     */
-    public static function summary_editor_context() {
-        return null;
-    }
-
-    /**
-     * Returns the filearea to use with the summary editor
-     *
-     * @uses course_request::$summaryeditorfilearea
-     * @return string The filearea to use with the summary editor
-     */
-    public static function summary_editor_filearea() {
-        return self::$summaryeditorfilearea;
-    }
-
     /**
      * Loads the properties for this course request object. Id is required and if
      * only id is provided then we load the rest of the properties from the database
@@ -3810,9 +3771,6 @@ class course_request {
      * @return mixed
      */
     public function __get($key) {
-        if ($key === 'summary' && self::summary_editor_context() !== null) {
-            return file_rewrite_pluginfile_urls($this->properties->summary, 'pluginfile.php', self::summary_editor_context()->id, self::summary_editor_filearea(), $this->properties->id);
-        }
         return $this->properties->$key;
     }
 
@@ -3927,13 +3885,12 @@ class course_request {
             blocks_add_default_course_blocks($course);
             $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
             // TODO: do some real enrolment here
-            role_assign($CFG->creatornewroleid, $this->properties->requester, $coursecontext->id); // assing teacher role
+            role_assign($CFG->creatornewroleid, $this->properties->requester, $coursecontext->id); // assign teacher role
             if (!empty($CFG->restrictmodulesfor) && $CFG->restrictmodulesfor != 'none' && !empty($CFG->restrictbydefault)) {
                 // if we're all or requested we're ok.
                 $allowedmods = explode(',',$CFG->defaultallowedmodules);
                 update_restricted_mods($course, $allowedmods);
             }
-            $this->copy_summary_files_to_course($course);
             $this->delete();
             fix_course_sortorder();
 
@@ -3967,36 +3924,6 @@ class course_request {
     public function delete() {
         global $DB;
         $DB->delete_records('course_request', array('id' => $this->properties->id));
-        if (self::summary_editor_context() !== null) {
-            $fs = get_file_storage();
-            $files = $fs->get_area_files(self::summary_editor_context()->id, self::summary_editor_filearea(), $this->properties->id);
-            foreach ($files as $file) {
-                $file->delete();
-            }
-        }
-    }
-
-    /**
-     * This function copies all files used in the summary for the request to the
-     * summary of the course.
-     *
-     * This function copies, original files are left associated with the request
-     * and are removed only when the request is deleted
-     *
-     * @param stdClass $course An object representing the course to copy files to
-     */
-    protected function copy_summary_files_to_course($course) {
-        if (self::summary_editor_context() !== null) {
-            $fs = get_file_storage();
-            $files = $fs->get_area_files(self::summary_editor_context()->id, self::summary_editor_filearea(), $this->properties->id);
-            foreach ($files as $file) {
-                $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-                if (!$file->is_directory()) {
-                    $filerecord = array('contextid'=>$coursecontext->id, 'filearea'=>'course_summary', 'itemid'=>0, 'filepath'=>$file->get_filepath(), 'filename'=>$file->get_filename());
-                    $fs->create_file_from_storedfile($filerecord, $file);
-                }
-            }
-        }
     }
 
     /**
index 38ecd4a..e1bf014 100644 (file)
@@ -79,7 +79,7 @@ if (!empty($add)) {
 
     if (plugin_supports('mod', $data->modulename, FEATURE_MOD_INTRO, true)) {
         $draftid_editor = file_get_submitted_draft_itemid('introeditor');
-        file_prepare_draft_area($draftid_editor, null, null, null);
+        file_prepare_draft_area($draftid_editor, null, null, null, null);
         $data->introeditor = array('text'=>'', 'format'=>FORMAT_HTML, 'itemid'=>$draftid_editor); // TODO: add better default
     }
 
@@ -140,7 +140,7 @@ if (!empty($add)) {
 
     if (plugin_supports('mod', $data->modulename, FEATURE_MOD_INTRO, true)) {
         $draftid_editor = file_get_submitted_draft_itemid('introeditor');
-        $currentintro = file_prepare_draft_area($draftid_editor, $context->id, $data->modulename.'_intro', 0, array('subdirs'=>true), $data->intro);
+        $currentintro = file_prepare_draft_area($draftid_editor, $context->id, 'mod_'.$data->modulename, 'intro', 0, array('subdirs'=>true), $data->intro);
         $data->introeditor = array('text'=>$currentintro, 'format'=>$data->introformat, 'itemid'=>$draftid_editor);
     }
 
@@ -321,7 +321,7 @@ if ($mform->is_cancelled()) {
         // update embedded links and save files
         if (plugin_supports('mod', $fromform->modulename, FEATURE_MOD_INTRO, true)) {
             $fromform->intro = file_save_draft_area_files($fromform->introeditor['itemid'], $modcontext->id,
-                                                          $fromform->modulename.'_intro', 0,
+                                                          'mod_'.$fromform->modulename, 'intro', 0,
                                                           array('subdirs'=>true), $fromform->introeditor['text']);
             $fromform->introformat = $fromform->introeditor['format'];
             unset($fromform->introeditor);
@@ -425,7 +425,7 @@ if ($mform->is_cancelled()) {
         $modcontext = get_context_instance(CONTEXT_MODULE, $fromform->coursemodule);
         if (plugin_supports('mod', $fromform->modulename, FEATURE_MOD_INTRO, true)) {
             $fromform->intro = file_save_draft_area_files($introeditor['itemid'], $modcontext->id,
-                                                          $fromform->modulename.'_intro', 0,
+                                                          'mod_'.$fromform->modulename, 'intro', 0,
                                                           array('subdirs'=>true), $introeditor['text']);
             $DB->set_field($fromform->modulename, 'intro', $fromform->intro, array('id'=>$fromform->instance));
         }
index 247a6fa..dc2d1f3 100644 (file)
@@ -159,7 +159,7 @@ if (has_capability('moodle/course:publish', get_context_instance(CONTEXT_COURSE,
         if (!empty($fromform->screenshots)) {
             $screenshots = $fromform->screenshots;
             $fs = get_file_storage();
-            $files = $fs->get_area_files(get_context_instance(CONTEXT_USER, $USER->id)->id, 'user_draft', $screenshots);
+            $files = $fs->get_area_files(get_context_instance(CONTEXT_USER, $USER->id)->id, 'user', 'draft', $screenshots);
             if (!empty($files)) {
                 $courseinfo->screenshots = $courseinfo->screenshots + count($files) - 1; //minus the ./ directory
             }
@@ -179,7 +179,7 @@ if (has_capability('moodle/course:publish', get_context_instance(CONTEXT_COURSE,
         try {
             $courseids = $xmlrpcclient->call($serverurl, $registeredhub->token, $function, $params);
         } catch (Exception $e) {
-            throw new moodle_exception('errorcoursepublish', 'hub', 
+            throw new moodle_exception('errorcoursepublish', 'hub',
                     new moodle_url('/course/view.php', array('id' => $id)), $e->getMessage());
         }
 
@@ -233,7 +233,7 @@ if (has_capability('moodle/course:publish', get_context_instance(CONTEXT_COURSE,
         } else {
             //redirect to the index publis page
             redirect(new moodle_url('/course/publish/index.php',
-                            array('sesskey' => sesskey(), 'id' => $id, 'published' => true, 
+                            array('sesskey' => sesskey(), 'id' => $id, 'published' => true,
                                 'hubname' => $hubname, 'huburl' => $huburl)));
         }
     }
index 08216f8..8be8272 100644 (file)
@@ -84,7 +84,7 @@ if ($scales = $DB->get_records("scale", array("courseid"=>$course->id), "name AS
 
     foreach ($scales as $scale) {
 
-        $scale->description = file_rewrite_pluginfile_urls($scale->description, 'pluginfile.php', $systemcontext->id, 'grade_scale', $scale->id);
+        $scale->description = file_rewrite_pluginfile_urls($scale->description, 'pluginfile.php', $systemcontext->id, 'grade', 'scale', $scale->id);
 
         $scalemenu = make_menu_from_list($scale->scale);
 
@@ -110,7 +110,7 @@ if ($scales = $DB->get_records("scale", array("courseid"=>0), "name ASC")) {
     echo $OUTPUT->heading($strstandardscales);
     foreach ($scales as $scale) {
 
-        $scale->description = file_rewrite_pluginfile_urls($scale->description, 'pluginfile.php', $systemcontext->id, 'grade_scale', $scale->id);
+        $scale->description = file_rewrite_pluginfile_urls($scale->description, 'pluginfile.php', $systemcontext->id, 'grade', 'scale', $scale->id);
 
         $scalemenu = make_menu_from_list($scale->scale);
 
index de82ca4..baeceaf 100644 (file)
@@ -18,7 +18,7 @@
 /**
  * This script serves draft files of current user
  *
- * @package    moodlecore
+ * @package    core
  * @subpackage file
  * @copyright  2008 Petr Skoda (http://skodak.org)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -52,11 +52,17 @@ if (count($args) == 0) { // always at least user id
 }
 
 $contextid = (int)array_shift($args);
-$filearea = array_shift($args);
+$component = array_shift($args);
+$filearea  = array_shift($args);
+$draftid   = (int)array_shift($args);
+
+if ($component !== 'user' or $filearea !== 'draft') {
+    send_file_not_found();
+}
 
 $context = get_context_instance_by_id($contextid);
 if ($context->contextlevel != CONTEXT_USER) {
-    print_error('invalidarguments');
+    send_file_not_found();
 }
 
 $userid = $context->instanceid;
@@ -64,20 +70,11 @@ if ($USER->id != $userid) {
     print_error('invaliduserid');
 }
 
-switch ($filearea) {
-    case 'user_draft':
-        $itemid = (int)array_shift($args);
-        break;
-    default:
-        send_file_not_found();
-}
-
-$relativepath = '/'.implode('/', $args);
-
 
 $fs = get_file_storage();
 
-$fullpath = $context->id.$filearea.$itemid.$relativepath;
+$relativepath = implode('/', $args);
+$fullpath = "/$context->id/user/draft/$draftid/$relativepath";
 
 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->get_filename() == '.') {
     send_file_not_found();
index 8c29f48..661453e 100644 (file)
--- a/file.php
+++ b/file.php
@@ -62,7 +62,7 @@ if (count($args) == 0) { // always at least courseid, may search for index.html
 }
 
 $courseid = (int)array_shift($args);
-$relativepath = '/'.implode('/', $args);
+$relativepath = implode('/', $args);
 
 // security: limit access to existing course subdirectories
 $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
@@ -77,8 +77,8 @@ if ($course->id != SITEID) {
 
 } else if ($CFG->forcelogin) {
     if (!empty($CFG->sitepolicy)
-        and ($CFG->sitepolicy == $CFG->wwwroot.'/file.php'.$relativepath
-             or $CFG->sitepolicy == $CFG->wwwroot.'/file.php?file='.$relativepath)) {
+        and ($CFG->sitepolicy == $CFG->wwwroot.'/file.php/'.$relativepath
+             or $CFG->sitepolicy == $CFG->wwwroot.'/file.php?file=/'.$relativepath)) {
         //do not require login for policy file
     } else {
         require_login(0, true, null, false);
@@ -89,7 +89,7 @@ $context = get_context_instance(CONTEXT_COURSE, $course->id);
 
 $fs = get_file_storage();
 
-$fullpath = $context->id.'course_content0'.$relativepath;
+$fullpath = "/$context->id/course/legacy/0/$relativepath";
 
 if (!$file = $fs->get_file_by_hash(sha1($fullpath))) {
     if (strrpos($fullpath, '/') !== strlen($fullpath) -1 ) {
diff --git a/files/draftfiles.php b/files/draftfiles.php
deleted file mode 100644 (file)
index 9569301..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-<?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/>.
-
-/**
- * Draft files management script used when javascript not available.
- *
- * @package    moodlecore
- * @subpackage file
- * @copyright  2008 Petr Skoda (http://skodak.org)
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-require('../config.php');
-require_once($CFG->libdir.'/filelib.php');
-
-$itemid     = required_param('itemid', PARAM_INT);
-$filepath   = optional_param('filepath', '/', PARAM_PATH);
-$newdirname = optional_param('newdirname', '', PARAM_FILE);
-$delete     = optional_param('delete', '', PARAM_PATH);
-$subdirs    = optional_param('subdirs', 0, PARAM_BOOL);
-$maxbytes   = optional_param('maxbytes', 0, PARAM_INT);
-
-require_login();
-if (isguestuser()) {
-    print_error('noguest');
-}
-
-if (!$context = get_context_instance(CONTEXT_USER, $USER->id)) {
-    print_error('invalidcontext');
-}
-
-$notice = '';
-
-$contextid = $context->id;
-$filearea  = 'user_draft';
-
-$browser = get_file_browser();
-$fs      = get_file_storage();
-
-if (!$subdirs) {
-    $filepath = '/';
-}
-
-if (!$directory = $fs->get_file($context->id, 'user_draft', $itemid, $filepath, '.')) {
-    $directory = new virtual_root_file($context->id, 'user_draft', $itemid);
-    $filepath = $directory->get_filepath();
-}
-$files = $fs->get_directory_files($context->id, 'user_draft', $itemid, $directory->get_filepath());
-$parent = $directory->get_parent_directory();
-
-$totalbytes = 0;
-foreach ($files as $hash=>$file) {
-    if (!$subdirs and $file->get_filepath() !== '/') {
-        unset($files[$hash]);
-        continue;
-    }
-    $totalbytes += $file->get_filesize();
-}
-
-/// process actions
-if ($newdirname !== '' and data_submitted() and confirm_sesskey()) {
-    $newdirname = $directory->get_filepath().$newdirname.'/';
-    $fs->create_directory($contextid, $filearea, $itemid, $newdirname, $USER->id);
-    redirect('draftfiles.php?itemid='.$itemid.'&amp;filepath='.rawurlencode($newdirname).'&amp;subdirs='.$subdirs.'&amp;maxbytes='.$maxbytes);
-}
-
-if (isset($_FILES['newfile']) and data_submitted() and confirm_sesskey()) {
-    if (!empty($_FILES['newfile']['error'])) {
-        $notice = file_get_upload_error($_FILES['newfile']['error']);
-    } else {
-        $file = $_FILES['newfile'];
-        $newfilename = clean_param($file['name'], PARAM_FILE);
-        if (is_uploaded_file($_FILES['newfile']['tmp_name'])) {
-            if ($existingfile = $fs->get_file($contextid, $filearea, $itemid, $filepath, $newfilename)) {
-                $existingfile->delete();
-            }
-            $filerecord = array('contextid'=>$contextid, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>$filepath,
-                                'filename'=>$newfilename, 'userid'=>$USER->id);
-            $newfile = $fs->create_file_from_pathname($filerecord, $_FILES['newfile']['tmp_name']);
-            redirect('draftfiles.php?itemid='.$itemid.'&amp;filepath='.rawurlencode($filepath).'&amp;subdirs='.$subdirs.'&amp;maxbytes='.$maxbytes);
-        }
-    }
-}
-
-if ($delete !== '' and $file = $fs->get_file($contextid, $filearea, $itemid, $filepath, $delete)) {
-    if (!data_submitted() or !confirm_sesskey()) {
-        echo $OUTPUT->header();
-        echo $OUTPUT->notification(get_string('deletecheckwarning').': '.s($file->get_filepath().$file->get_filename()));
-        $optionsno  = array('itemid'=>$itemid, 'filepath'=>$filepath, 'subdirs'=>$subdirs);
-        $optionsyes = array('itemid'=>$itemid, 'filepath'=>$filepath, 'delete'=>$delete, 'sesskey'=>sesskey(), 'subdirs'=>$subdirs);
-        echo $OUTPUT->confirm(get_string('deletecheckfiles'), new moodle_url('draftfiles.php', $optionsyes), new moodle_url('draftfiles.php', $optionsno));
-        echo $OUTPUT->footer();
-        die;
-
-    } else {
-        $isdir = $file->is_directory();
-        $file->delete();
-        if ($isdir) {
-            redirect('draftfiles.php?itemid='.$itemid.'&amp;filepath='.rawurlencode($parent->get_filepath()).'&amp;subdirs='.$subdirs.'&amp;maxbytes='.$maxbytes);
-        } else {
-            redirect('draftfiles.php?itemid='.$itemid.'&amp;filepath='.rawurlencode($filepath).'&amp;subdirs='.$subdirs.'&amp;maxbytes='.$maxbytes);
-        }
-    }
-}
-
-echo $OUTPUT->header();
-
-if ($notice !== '') {
-    echo $OUTPUT->notification($notice);
-}
-
-echo '<div class="areafiles">';
-
-$strfolder   = get_string('folder');
-$strfile     = get_string('file');
-$strdownload = get_string('download');
-$strdelete   = get_string('delete');
-
-if ($parent) {
-    echo '<div class="folder">';
-    echo '<a href="draftfiles.php?itemid='.$itemid.'&amp;filepath='.$parent->get_filepath().'&amp;subdirs='.$subdirs.'&amp;maxbytes='.$maxbytes.'"><img src="'.$OUTPUT->pix_url('f/parent') . '" class="icon" alt="" />&nbsp;'.get_string('parentfolder').'</a>';
-    echo '</div>';
-}
-
-foreach ($files as $file) {
-    $filename    = $file->get_filename();
-    $filenameurl = rawurlencode($filename);
-    $filepath    = $file->get_filepath();
-    $filesize    = $file->get_filesize();
-    $filesize    = $filesize ? display_size($filesize) : '';
-
-    $mimetype = $file->get_mimetype();
-
-    if ($file->is_directory()) {
-        if ($subdirs) {
-            $dirname = explode('/', trim($filepath, '/'));
-            $dirname = array_pop($dirname);
-            echo '<div class="folder">';
-            echo "<a href=\"draftfiles.php?itemid=$itemid&amp;filepath=$filepath&amp;subdirs=$subdirs&amp;maxbytes=$maxbytes\"><img src=\"" . $OUTPUT->pix_url('f/folder') . "\" class=\"icon\" alt=\"$strfolder\" />&nbsp;".s($dirname)."</a> ";
-            echo "<a href=\"draftfiles.php?itemid=$itemid&amp;filepath=$filepath&amp;delete=$filenameurl&amp;subdirs=$subdirs&amp;maxbytes=$maxbytes\"><img src=\"" . $OUTPUT->pix_url('t/delete') . "\" class=\"iconsmall\" alt=\"$strdelete\" /></a>";
-            echo '</div>';
-        }
-
-    } else {
-        $viewurl = file_encode_url("$CFG->wwwroot/draftfile.php", "/$contextid/user_draft/$itemid".$filepath.$filename, false, false);
-        echo '<div class="file">';
-        echo "<a href=\"$viewurl\"><img src=\"" . $OUTPUT->pix_url(file_mimetype_icon($mimetype)) . "\" class=\"icon\" alt=\"$strfile\" />&nbsp;".s($filename)." ($filesize)</a> ";
-        echo "<a href=\"draftfiles.php?itemid=$itemid&amp;filepath=$filepath&amp;delete=$filenameurl&amp;subdirs=$subdirs&amp;maxbytes=$maxbytes\"><img src=\"" . $OUTPUT->pix_url('t/delete') . "\" class=\"iconsmall\" alt=\"$strdelete\" /></a>";;
-        echo '</div>';
-    }
-}
-
-echo '</div>';
-
-if ($maxbytes == 0 or $maxbytes > $totalbytes) {
-    echo '<form enctype="multipart/form-data" method="post" action="draftfiles.php"><div>';
-    if ($maxbytes) {
-        echo '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxbytes-$totalbytes).'" />';
-    }
-    echo '<input type="hidden" name="itemid" value="'.$itemid.'" />';
-    echo '<input type="hidden" name="filepath" value="'.s($filepath).'" />';
-    echo '<input type="hidden" name="subdirs" value="'.$subdirs.'" />';
-    echo '<input type="hidden" name="maxbytes" value="'.$maxbytes.'" />';
-    echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
-    echo '<input name="newfile" type="file" />';
-    echo '<input type="submit" value="'.get_string('uploadafile').'" />';
-    if ($maxbytes) {
-        echo ' ('.get_string('maxsize', '', display_size(get_max_upload_file_size($CFG->maxbytes, $maxbytes-$totalbytes))).')';
-    } else {
-        echo ' ('.get_string('maxsize', '', display_size(get_max_upload_file_size($CFG->maxbytes))).')';
-    }
-    echo '</div></form>';
-} else {
-    //TODO: notify upload limit reached here
-    echo get_string('maxsize', '', display_size(get_max_upload_file_size($CFG->maxbytes, $maxbytes)));
-}
-
-if ($subdirs) {
-    echo '<form action="draftfiles.php" method="post"><div>';
-    echo '<input type="hidden" name="itemid" value="'.$itemid.'" />';
-    echo '<input type="hidden" name="filepath" value="'.s($filepath).'" />';
-    echo '<input type="hidden" name="subdirs" value="'.$subdirs.'" />';
-    echo '<input type="hidden" name="maxbytes" value="'.$maxbytes.'" />';
-    echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
-    echo '<input type="text" name="newdirname" value="" />';
-    echo '<input type="submit" value="'.get_string('makeafolder').'" />';
-    echo '</div></form>';
-}
-
-echo $OUTPUT->footer();
-
-
index c352f40..e1a488e 100755 (executable)
@@ -38,8 +38,9 @@ class moodle_file_external extends external_api {
             array(
                 'params' => new external_single_structure(array(
                         'contextid' => new external_value(PARAM_INT, 'context id'),
-                        'itemid'    => new external_value(PARAM_INT, 'associated id'),
+                        'component' => new external_value(PARAM_TEXT, 'component'),
                         'filearea'  => new external_value(PARAM_TEXT, 'file area'),
+                        'itemid'    => new external_value(PARAM_INT, 'associated id'),
                         'filepath'  => new external_value(PARAM_RAW, 'file path'),
                         'filename'  => new external_value(PARAM_TEXT, 'file name'),
                     )
@@ -54,7 +55,21 @@ class moodle_file_external extends external_api {
      * @return array
      */
     public static function get_files($fileinfo) {
+
+throw new coding_exception('File browsing api function is not implemented yet, sorry');
+
         global $CFG, $USER, $OUTPUT;
+        if (empty($fileinfo['contextid'])) {
+            $context  = get_system_context();
+        } else {
+            $context  = get_context_instance_by_id($fileinfo['contextid']);
+        }
+        if (empty($fileinfo['component'])) {
+            $fileinfo['component'] = null;
+        }
+        if (empty($fileinfo['filearea'])) {
+            $fileinfo['filearea'] = null;
+        }
         if (empty($fileinfo['itemid'])) {
             $fileinfo['itemid'] = null;
         }
@@ -64,14 +79,6 @@ class moodle_file_external extends external_api {
         if (empty($fileinfo['filepath'])) {
             $fileinfo['filepath'] = null;
         }
-        if (empty($fileinfo['filearea'])) {
-            $fileinfo['filearea'] = null;
-        }
-        if (empty($fileinfo['contextid'])) {
-            $context  = get_system_context();
-        } else {
-            $context  = get_context_instance_by_id($fileinfo['contextid']);
-        }
         try {
             $browser = get_file_browser();
 
@@ -79,7 +86,7 @@ class moodle_file_external extends external_api {
             $return['parents'] = array();
             $return['files'] = array();
             $file = $browser->get_file_info($context, null, null, null, null);
-            if ($file = $browser->get_file_info($context, $fileinfo['filearea'], $fileinfo['itemid'], $fileinfo['filepath'], $fileinfo['filename'])) {
+            if ($file = $browser->get_file_info($context, $fileinfo['component'], $fileinfo['filearea'], $fileinfo['itemid'], $fileinfo['filepath'], $fileinfo['filename'])) {
                 $level = $file->get_parent();
                 while ($level) {
                     $params = $level->get_params();
@@ -93,24 +100,28 @@ class moodle_file_external extends external_api {
                     $params = $child->get_params();
                     if ($child->is_directory()) {
                         $node = array(
-                            'filename' => $child->get_visible_name(),
-                            'filepath' => $params['filepath'],
-                            'filearea' => $params['filearea'],
-                            'itemid' => $params['itemid'],
+                            //TODO: this is wrong, you need to fetch info from the child node!!!!
                             'contextid' => $params['contextid'],
-                            'url' => null,
-                            'isdir'=>true
+                            'component' => $params['component'],
+                            'filearea'  => $params['filearea'],
+                            'itemid'    => $params['itemid'],
+                            'filepath'  => $params['filepath'],
+                            'filename'  => $child->get_visible_name(),
+                            'url'       => null,
+                            'isdir'     =>true
                         );
                         $list[] = $node;
                     } else {
                         $node = array(
-                            'filename' => $child->get_visible_name(),
-                            'filepath' => $params['filepath'],
-                            'filearea' => $params['filearea'],
-                            'itemid' => $params['itemid'],
+                            //TODO: this is wrong, you need to fetch info from the child node!!!!
                             'contextid' => $params['contextid'],
-                            'url' => $child->get_url(),
-                            'isdir'=>false
+                            'component' => $params['component'],
+                            'filearea'  => $params['filearea'],
+                            'itemid'    => $params['itemid'],
+                            'filepath'  => $params['filepath'],
+                            'filename'  => $child->get_visible_name(),
+                            'url'       => $child->get_url(),
+                            'isdir'     => false
                         );
                         $list[] = $node;
                     }
@@ -134,23 +145,25 @@ class moodle_file_external extends external_api {
                     new external_single_structure(
                         array(
                             'contextid' => new external_value(PARAM_INT, ''),
-                            'filename' => new external_value(PARAM_TEXT, ''),
-                            'filearea' => new external_value(PARAM_TEXT, ''),
-                            'filepath' => new external_value(PARAM_TEXT, ''),
-                            'itemid'   => new external_value(PARAM_INT, '')
+                            'component' => new external_value(PARAM_ALPHAEXT, ''),
+                            'filearea'  => new external_value(PARAM_ALPHAEXT, ''),
+                            'itemid'    => new external_value(PARAM_INT, ''),
+                            'filepath'  => new external_value(PARAM_TEXT, ''),
+                            'filename'  => new external_value(PARAM_TEXT, ''),
                         )
                     )
                 ),
                 'files' => new external_multiple_structure(
                     new external_single_structure(
                         array(
-                            'filename' => new external_value(PARAM_TEXT, ''),
-                            'filearea' => new external_value(PARAM_TEXT, ''),
-                            'filepath' => new external_value(PARAM_TEXT, ''),
+                            'contextid' => new external_value(PARAM_INT, ''),
+                            'component' => new external_value(PARAM_ALPHAEXT, ''),
+                            'filearea'  => new external_value(PARAM_ALPHAEXT, ''),
                             'itemid'   => new external_value(PARAM_INT, ''),
+                            'filepath' => new external_value(PARAM_TEXT, ''),
+                            'filename' => new external_value(PARAM_TEXT, ''),
                             'isdir'    => new external_value(PARAM_BOOL, ''),
                             'url'      => new external_value(PARAM_TEXT, ''),
-                            'contextid' => new external_value(PARAM_INT, '')
                         )
                     )
                 )
@@ -167,8 +180,9 @@ class moodle_file_external extends external_api {
             array(
                 'params' => new external_single_structure(array(
                         'contextid' => new external_value(PARAM_INT, 'context id'),
+                        'filearea'  => new external_value(PARAM_ALPHAEXT, 'file area'),
+                        'component' => new external_value(PARAM_ALPHAEXT, 'component'),
                         'itemid'    => new external_value(PARAM_INT, 'associated id'),
-                        'filearea'  => new external_value(PARAM_TEXT, 'file area'),
                         'filepath'  => new external_value(PARAM_RAW, 'file path'),
                         'filename'  => new external_value(PARAM_TEXT, 'file name'),
                         'filecontent' => new external_value(PARAM_TEXT, 'file content')
@@ -215,6 +229,9 @@ class moodle_file_external extends external_api {
         file_put_contents($savedfilepath, base64_decode($fileinfo['filecontent']));
         unset($fileinfo['filecontent']);
 
+        $component = $fileinfo['component'];
+
+        //TODO: mandatory!!!
         if (!empty($fileinfo['filearea'])) {
             $filearea = $fileinfo['filearea'];
         } else {
@@ -226,7 +243,7 @@ class moodle_file_external extends external_api {
         } else {
             $filepath = '';
         }
+
         if (isset($fileinfo['itemid'])) {
             $itemid = $fileinfo['itemid'];
         } else {
@@ -238,16 +255,21 @@ class moodle_file_external extends external_api {
             $context = get_system_context();
         }
 
-        $fs = get_file_storage();
+
+// TODO: we MUST obey access control restrictions here, no messing with file_storage here, the only allowed way is to use file_browser here!!!!!!!!!!!!!!!!!!!!!!!!
+throw new coding_exception('File upload ext api needs to be made secure first!!!!');
+
+
         $browser = get_file_browser();
 
         // check existing file
-        if ($file = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) {
+        if ($file = $fs->get_file($context->id, $component, $filearea, $itemid, $filepath, $filename)) {
             throw new moodle_exception('fileexist');
         }
 
         $file_record = new object();
         $file_record->contextid = $context->id;
+        $file_record->component = $component;
         $file_record->filearea  = $filearea;
         $file_record->itemid    = $itemid;
         $file_record->filepath  = $filepath;
diff --git a/files/filebrowser_ajax.php b/files/filebrowser_ajax.php
new file mode 100755 (executable)
index 0000000..342fb38
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * File manager support
+ *
+ * @package    core
+ * @subpackage file
+ * @copyright  2010 Dongsheng Cai <dongsheng@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+define('AJAX_SCRIPT', true);
+
+require('../config.php');
+require_once($CFG->libdir.'/filelib.php');
+
+$action = optional_param('action', 'list', PARAM_ALPHA);
+
+require_login();
+
+$err = new stdclass;
+
+if (isguestuser()) {
+    $err->error = get_string('noguest');
+    die(json_encode($err));
+}
+
+switch ($action) {
+    // used by course file tree viewer
+    case 'getfiletree':
+
+        $contextid  = required_param('contextid', PARAM_INT);
+        $component  = required_param('component', PARAM_ALPHAEXT);
+        $filearea   = required_param('filearea', PARAM_ALPHAEXT);
+        $itemid     = required_param('itemid', PARAM_INT);
+        $filepath   = required_param('filepath', PARAM_PATH);
+
+        $browser = get_file_browser();
+        $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($contextid, $component, $filearea, $itemid, $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;
+
+    default:
+        break;
+}
diff --git a/files/files_ajax.php b/files/files_ajax.php
deleted file mode 100755 (executable)
index 88c4beb..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-<?php
-
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * File manager
- *
- * @package    moodlecore
- * @subpackage file
- * @copyright  2010 Dongsheng Cai <dongsheng@moodle.com>
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-require('../config.php');
-require_once($CFG->libdir.'/filelib.php');
-require_once($CFG->libdir.'/adminlib.php');
-
-require_login();
-
-$err = new stdclass;
-
-if (isguestuser()) {
-    $err->error = get_string('noguest');
-    die(json_encode($err));
-}
-
-if (!confirm_sesskey()) {
-    $err->error = get_string('invalidsesskey');
-    die(json_encode($err));
-}
-
-$action     = optional_param('action', 'list', PARAM_ALPHA);
-$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);
-$itemid     = optional_param('itemid', -1, PARAM_INT);
-$newfilepath = optional_param('newfilepath', '/', PARAM_PATH);
-$newdirname  = optional_param('newdirname', '', PARAM_FILE);
-$newfilename = optional_param('newfilename', '', PARAM_FILE);
-
-$user_context = get_context_instance(CONTEXT_USER, $USER->id);
-
-switch ($action) {
-// used by course file tree viewer
-case 'getfiletree':
-    $browser = get_file_browser();
-    $fs = get_file_storage();
-    $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();
-
-            // hide empty folder
-            if (!empty($params['itemid'])) {
-                $itemid = $params['itemid'];
-            } else {
-                $itemid = false;
-            }
-            $draftfiles = $fs->get_area_files($params['contextid'], $params['filearea'], $itemid, 'id', false);
-            if (count($draftfiles) == 0) {
-                continue;
-            }
-        } 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);
-    echo json_encode($data);
-    break;
-
-case 'list':
-    $data = file_get_user_area_files($itemid, $filepath, $filearea);
-    echo json_encode($data);
-    break;
-
-case 'mkdir':
-    $fs = get_file_storage();
-    $fs->create_directory($user_context->id, $filearea, $itemid, file_correct_filepath(file_correct_filepath($filepath).$newdirname));
-    $return = new stdclass;
-    $return->filepath = $filepath;
-    echo json_encode($return);
-    break;
-
-case 'delete':
-    $fs = get_file_storage();
-    $filepath = file_correct_filepath($filepath);
-    $return = new stdclass;
-    if ($stored_file = $fs->get_file($user_context->id, $filearea, $itemid, $filepath, $filename)) {
-        $parent_path = $stored_file->get_parent_directory()->get_filepath();
-        if($result = $stored_file->delete()) {
-            $return->filepath = $parent_path;
-            echo json_encode($return);
-        } else {
-            echo json_encode(false);
-        }
-    } else {
-        echo json_encode(false);
-    }
-    break;
-
-case 'setmainfile':
-    $filepath = file_correct_filepath($filepath);
-    // reset sort order
-    file_reset_sortorder($user_context->id, $filearea, $itemid);
-    // set main file
-    $return = file_set_sortorder($user_context->id, $filearea, $itemid, $filepath, $filename, 1);
-    echo json_encode($return);
-    break;
-
-case 'renamedir':
-    $fs = get_file_storage();
-    $fb = get_file_browser();
-    $return = new stdclass;
-    $fileinfo = $fb->get_file_info($user_context, $filearea, $itemid, $filepath, '.');
-    if ($result = $fileinfo->delete()) {
-        $newdir = $fs->create_directory($user_context->id, $filearea, $itemid, file_correct_filepath($newfilename));
-        $return->filepath = $newdir->get_parent_directory()->get_filepath();
-        echo json_encode($return);
-    } else {
-        echo json_encode(false);
-    }
-    break;
-
-case 'rename':
-    $fb = get_file_browser();
-    $file = $fb->get_file_info($user_context, $filearea, $itemid, $filepath, $filename);
-    $file->copy_to_storage($user_context->id, $filearea, $itemid, $filepath, $newfilename);
-    if ($file->delete()) {
-        $return = new stdclass;
-        $return->filepath = $filepath;
-        echo json_encode($return);
-    } else {
-        echo json_encode(false);
-    }
-    break;
-
-case 'movefile':
-case 'movedir':
-    $fb = get_file_browser();
-    $return = new stdclass;
-    if ($filepath != $newfilepath) {
-        $file = $fb->get_file_info($user_context, $filearea, $itemid, $filepath, $filename);
-        $file->copy_to_storage($user_context->id, $filearea, $itemid, $newfilepath, $filename);
-        if ($file->delete()) {
-            $return->filepath = $newfilepath;
-        }
-    }
-    if (!isset($return->filepath)) {
-        $return->filepath = '/';
-    }
-    echo json_encode($return);
-    break;
-
-case 'zip':
-    $zipper = new zip_packer();
-    $fs = get_file_storage();
-
-    $file = $fs->get_file($user_context->id, $filearea, $itemid, $filepath, '.');
-
-    $parent_path = $file->get_parent_directory()->get_filepath();
-
-    if ($newfile = $zipper->archive_to_storage(array($file), $user_context->id, $filearea, $itemid, $parent_path, $filepath.'.zip', $USER->id)) {
-        $return = new stdclass;
-        $return->filepath = $parent_path;
-        echo json_encode($return);
-    } else {
-        echo json_encode(false);
-    }
-    break;
-
-case 'downloaddir':
-    $zipper = new zip_packer();
-    $fs = get_file_storage();
-    $area = file_get_user_area_info($itemid, $filearea);
-    if ($area['filecount'] == 0) {
-        echo json_encode(false);
-        die;
-    }
-
-    $stored_file = $fs->get_file($user_context->id, $filearea, $itemid, $filepath, '.');
-    if ($filepath === '/') {
-        $parent_path = '/';
-        $filename = get_string('files').'.zip';
-    } else {
-        $parent_path = $stored_file->get_parent_directory()->get_filepath();
-        $filename = trim($filepath, '/').'.zip';
-    }
-
-    // archive compressed file to an unused draft area
-    $newdraftitemid = file_get_unused_draft_itemid();
-    if ($newfile = $zipper->archive_to_storage(array($stored_file), $user_context->id, 'user_draft', $newdraftitemid, '/', $filename, $USER->id)) {
-        $return = new stdclass;
-        $return->fileurl  = $CFG->wwwroot . '/draftfile.php/' . $user_context->id .'/user_draft/'.$newdraftitemid.'/'.$filename;
-        $return->filepath = $parent_path;
-        echo json_encode($return);
-    } else {
-        echo json_encode(false);
-    }
-    break;
-
-case 'unzip':
-    $zipper = new zip_packer();
-
-    $fs = get_file_storage();
-
-    $file = $fs->get_file($user_context->id, $filearea, $itemid, $filepath, $filename);
-
-    if ($newfile = $file->extract_to_storage($zipper, $user_context->id, $filearea, $itemid, $filepath, $USER->id)) {
-        $return = new stdclass;
-        $return->filepath = $filepath;
-        echo json_encode($return);
-    } else {
-        echo json_encode(false);
-    }
-    break;
-
-case 'upload':
-    break;
-
-default:
-    break;
-}
index bc9acbf..11e47a1 100644 (file)
@@ -18,7 +18,7 @@
 /**
  * Moodle file tree viewer based on YUI2 Treeview
  *
- * @package    moodlecore
+ * @package    core
  * @subpackage file
  * @copyright  2010 Dongsheng Cai <dongsheng@moodle.com>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 
 require('../config.php');
 
-$courseid   = optional_param('id', 0, PARAM_INT);
-
 $contextid  = optional_param('contextid', SYSCONTEXTID, PARAM_INT);
+$component  = optional_param('component', '', PARAM_ALPHAEXT);
 $filearea   = optional_param('filearea', '', PARAM_ALPHAEXT);
 $itemid     = optional_param('itemid', -1, PARAM_INT);
 $filepath   = optional_param('filepath', '', PARAM_PATH);
 $filename   = optional_param('filename', '', PARAM_FILE);
 
-if ($courseid) {
-    $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
-    $context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST);
-    redirect(new moodle_url('index.php', array('contextid' => $context->id, 'itemid'=> 0, 'filearea' => 'course_content')));
-}
-
-$context = get_context_instance_by_id($contextid, MUST_EXIST);
-$PAGE->set_context($context);
+$PAGE->set_url('/files/index.php', array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>$filepath, 'filename'=>$filename));
 
-$course = null;
-$cm = null;
-if ($context->contextlevel == CONTEXT_MODULE) {
-    $cm = get_coursemodule_from_id(null, $context->instanceid, 0, false, MUST_EXIST);
-    $course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST);
-} else if ($context->contextlevel == CONTEXT_COURSE) {
-    $course = $DB->get_record('course', array('id'=>$context->instanceid), '*', MUST_EXIST);
+if ($component === '') {
+    $component = null;
 }
 
-require_login($course, false, $cm);
-require_capability('moodle/course:managefiles', $context);
-
 if ($filearea === '') {
     $filearea = null;
 }
@@ -71,11 +55,21 @@ if ($filename === '') {
     $filename = null;
 }
 
+list($context, $course, $cm) = get_context_info_array($contextid);
+
+require_login($course, false, $cm);
+require_capability('moodle/course:managefiles', $context);
+
 $browser = get_file_browser();
 
-$file_info = $browser->get_file_info($context, $filearea, $itemid, $filepath, $filename);
+$file_info = $browser->get_file_info($context, $component, $filearea, $itemid, $filepath, $filename);
 
 $strfiles = get_string("files");
+
+$PAGE->navbar->add($strfiles);
+$PAGE->set_title("$SITE->shortname: $strfiles");
+$PAGE->set_heading($SITE->fullname);
+
 if ($context->contextlevel == CONTEXT_MODULE) {
     $PAGE->set_pagelayout('incourse');
 } else if ($context->contextlevel == CONTEXT_COURSE) {
@@ -84,16 +78,20 @@ if ($context->contextlevel == CONTEXT_MODULE) {
     $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();
+$output = $PAGE->get_renderer('core', 'files');
+
+echo $output->header();
+echo $output->box_start();
+
+if ($file_info) {
+    $options = array();
+    //$options['visible_areas'] = array('backup'=>array('section', 'course'), 'course'=>array('legacy'), 'user'=>array('backup'));
+    echo $output->files_tree_viewer($file_info, $options);
+} else {
+    notify(get_string('nofilesavailable', 'repository'));
+}
+
+echo $output->box_end();
 
-$options = array();
-$options['enabled_fileareas'] = array('section_backup', 'course_backup', 'course_content', 'user_backup');
-echo $OUTPUT->box_start();
-echo $OUTPUT->moodle_file_tree_viewer($context->id, $filearea, $itemid, $filepath, $options);
-echo $OUTPUT->box_end();
+echo $output->footer();
 
-echo $OUTPUT->footer();
index 49274e1..2665405 100644 (file)
@@ -2,7 +2,7 @@
 // Author: Dongsheng Cai <dongsheng@moodle.com>
 M.core_filetree = {
     y3: null,
-    api: M.cfg.wwwroot+'/files/files_ajax.php',
+    api: M.cfg.wwwroot+'/files/filebrowser_ajax.php',
     request: function(url, node, cb) {
         var api = this.api + '?action=getfiletree';
         var params = [];
diff --git a/files/renderer.php b/files/renderer.php
new file mode 100644 (file)
index 0000000..141b3bc
--- /dev/null
@@ -0,0 +1,156 @@
+<?php
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// This file is part of Moodle - http://moodle.org/                      //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//                                                                       //
+// 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/>.       //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Rendering of files viewer related widgets.
+ * @package   core
+ * @subpackage file
+ * @copyright 2010 Dongsheng Cai
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since     Moodle 2.0
+ */
+
+/**
+ * File manager render
+ *
+ * @copyright 2010 Dongsheng Cai
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since     Moodle 2.0
+ */
+class core_files_renderer extends plugin_renderer_base {
+
+    public function files_tree_viewer(file_info $file_info, array $options = null) {
+        $tree = new files_tree_viewer($file_info, $options);
+        return $this->render($tree);
+    }
+
+    public function render_files_tree_viewer(files_tree_viewer $tree) {
+
+        $html = '<div>';
+        foreach($tree->path as $path) {
+            $html .= $path;
+            $html .= ' / ';
+        }
+        $html .= '</div>';
+
+        $html .= '<div id="course-file-tree-view" class="filemanager-container">';
+        if (empty($tree->tree)) {
+            $html .= get_string('nofilesavailable', 'repository');
+        } else {
+            $this->page->requires->js_init_call('M.core_filetree.init');
+            $html .= '<ul>';
+            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 .= '<li '.$class.'>';
+                $html .= html_writer::link($node['url'], $node['filename'], $link_attributes);
+                $html .= '</li>';
+            }
+            $html .= '</ul>';
+        }
+        $html .= '</div>';
+        return $html;
+    }
+}
+
+
+/**
+ * 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 files_tree_viewer implements renderable {
+    public $tree;
+    public $path;
+
+    /**
+     * Constructor of moodle_file_tree_viewer class
+     * @param file_info $file_info
+     * @param array $options
+     */
+    public function __construct(file_info $file_info, array $options = null) {
+        global $CFG;
+
+        //note: this MUST NOT use get_file_storage() !!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+        $this->options = (array)$options;
+        if (isset($this->options['visible_areas'])) {
+            $visible_areas = (array)$this->options['visible_areas'];
+        } else {
+            $visible_areas = false;
+        }
+
+        $this->tree = array();
+        $children = $file_info->get_children();
+        $parent_info = $file_info->get_parent();
+
+        $level = $parent_info;
+        $this->path = array();
+        while ($level) {
+            $params = $level->get_params();
+            $context = get_context_instance_by_id($params['contextid']);
+            // lock user in course level
+            if ($context->contextlevel == CONTEXT_COURSECAT or $context->contextlevel == CONTEXT_SYSTEM) {
+                break;
+            }
+            $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[] = $file_info->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);
+                if ($visible_areas !== false) {
+                    if (!isset($visible_areas[$params['component']][$params['filearea']])) {
+                        continue;
+                    }
+                }
+            } else {
+                $fileitem['url'] = $child->get_url();
+            }
+            $this->tree[] = $fileitem;
+        }
+    }
+}
index 6d355b0..abdd6dd 100644 (file)
@@ -96,9 +96,9 @@ $returnurl = $gpr->get_return_url('index.php?id='.$courseid);
 $editoroptions = array('maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$CFG->maxbytes, 'trusttext'=>false, 'noclean'=>true);
 
 if (!empty($outcome_rec->id)) {
-    $outcome_rec = file_prepare_standard_editor($outcome_rec, 'description', $editoroptions, $systemcontext, 'grade_outcome', $outcome_rec->id);
+    $outcome_rec = file_prepare_standard_editor($outcome_rec, 'description', $editoroptions, $systemcontext, 'grade', 'outcome', $outcome_rec->id);
 } else {
-    $outcome_rec = file_prepare_standard_editor($outcome_rec, 'description', $editoroptions, $systemcontext, 'grade_outcome', null);
+    $outcome_rec = file_prepare_standard_editor($outcome_rec, 'description', $editoroptions, $systemcontext, 'grade', 'outcome', null);
 }
 
 $mform = new edit_outcome_form(null, compact('gpr', 'editoroptions'));
@@ -124,10 +124,10 @@ if ($mform->is_cancelled()) {
         }
         $outcome->insert();
 
-        $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $systemcontext, 'grade_outcome', $outcome->id);
+        $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $systemcontext, 'grade', 'outcome', $outcome->id);
         $DB->set_field($outcome->table, 'description', $data->description, array('id'=>$outcome->id));
     } else {
-        $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $systemcontext, 'grade_outcome', $id);
+        $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $systemcontext, 'grade', 'outcome', $id);
         grade_outcome::set_properties($outcome, $data);
         if (isset($data->standard)) {
             $outcome->courseid = !empty($data->standard) ? null : $courseid;
index 66c2e86..12d410e 100644 (file)
@@ -90,9 +90,9 @@ $returnurl = $gpr->get_return_url('index.php?id='.$courseid);
 $editoroptions = array('maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$CFG->maxbytes, 'trusttext'=>false, 'noclean'=>true);
 
 if (!empty($scale_rec->id)) {
-    $scale_rec = file_prepare_standard_editor($scale_rec, 'description', $editoroptions, $systemcontext, 'grade_scale', $scale_rec->id);
+    $scale_rec = file_prepare_standard_editor($scale_rec, 'description', $editoroptions, $systemcontext, 'grade', 'scale', $scale_rec->id);
 } else {
-    $scale_rec = file_prepare_standard_editor($scale_rec, 'description', $editoroptions, $systemcontext, 'grade_scale', null);
+    $scale_rec = file_prepare_standard_editor($scale_rec, 'description', $editoroptions, $systemcontext, 'grade', 'scale', null);
 }
 $mform = new edit_scale_form(null, compact('gpr', 'editoroptions'));
 
@@ -113,10 +113,10 @@ if ($mform->is_cancelled()) {
         }
         $scale->courseid = !empty($data->standard) ? 0 : $courseid;
         $scale->insert();
-        $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $systemcontext, 'grade_scale', $scale->id);
+        $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $systemcontext, 'grade', 'scale', $scale->id);
         $DB->set_field($scale->table, 'description', $data->description, array('id'=>$scale->id));
     } else {
-        $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $systemcontext, 'grade_scale', $id);
+        $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $systemcontext, 'grade', 'scale', $id);
         grade_scale::set_properties($scale, $data);
         if (isset($data->standard)) {
             $scale->courseid = !empty($data->standard) ? 0 : $courseid;
index ed4be5f..1cb7710 100755 (executable)
@@ -98,7 +98,7 @@ class edit_grade_form extends moodleform {
         $mform->disabledIf('locktime', 'gradetype', 'eq', GRADE_TYPE_NONE);
 
         // Feedback format is automatically converted to html if user has enabled editor
-        $feedbackoptions = array('maxfiles'=>0, 'maxbytes'=>0, 'trusttext'=>true);
+        $feedbackoptions = array('maxfiles'=>0, 'maxbytes'=>0); //TODO: no files here for now, if ever gets implemented use component 'grade' and filearea 'feedback'
         $mform->addElement('editor', 'feedback', get_string('feedback', 'grades'), null, $feedbackoptions);
         $mform->addHelpButton('feedback', 'feedback', 'grades');
         $mform->setType('text', PARAM_RAW); // to be cleaned before display, no XSS risk
index 1830fc3..80f504a 100644 (file)
@@ -85,9 +85,9 @@ if ($id and $delete) {
 // Prepare the description editor: We do support files for group descriptions
 $editoroptions = array('maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$course->maxbytes, 'trust'=>false, 'context'=>$context, 'noclean'=>true);
 if (!empty($group->id)) {
-    $group = file_prepare_standard_editor($group, 'description', $editoroptions, $context, 'course_group_description', $group->id);
+    $group = file_prepare_standard_editor($group, 'description', $editoroptions, $context, 'group', 'description', $group->id);
 } else {
-    $group = file_prepare_standard_editor($group, 'description', $editoroptions, $context, 'course_group_description', null);
+    $group = file_prepare_standard_editor($group, 'description', $editoroptions, $context, 'group', 'description', null);
 }
 
 /// First create the form
index 131428f..66359b4 100644 (file)
@@ -80,9 +80,9 @@ if ($id and $delete) {
 // Prepare the description editor: We do support files for grouping descriptions
 $editoroptions = array('maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$course->maxbytes, 'trust'=>true, 'context'=>$context, 'noclean'=>true);
 if (!empty($grouping->id)) {
-    $grouping = file_prepare_standard_editor($grouping, 'description', $editoroptions, $context, 'course_grouping_description', $grouping->id);
+    $grouping = file_prepare_standard_editor($grouping, 'description', $editoroptions, $context, 'grouping', 'description', $grouping->id);
 } else {
-    $grouping = file_prepare_standard_editor($grouping, 'description', $editoroptions, $context, 'course_grouping_description', null);
+    $grouping = file_prepare_standard_editor($grouping, 'description', $editoroptions, $context, 'grouping', 'description', null);
 }
 
 /// First create the form
index 9f6c667..6e97723 100644 (file)
@@ -148,7 +148,7 @@ function groups_create_group($data, $editform=false, $editoroptions=null) {
             $description = new stdClass;
             $description->id = $data->id;
             $description->description_editor = $data->description_editor;
-            $description = file_postupdate_standard_editor($description, 'description', $editoroptions, $editoroptions['context'], 'course_group_description', $description->id);
+            $description = file_postupdate_standard_editor($description, 'description', $editoroptions, $editoroptions['context'], 'group', 'description', $description->id);
             $DB->update_record('groups', $description);
         }
     }
@@ -185,7 +185,7 @@ function groups_create_grouping($data, $editoroptions=null) {
         $description = new stdClass;
         $description->id = $data->id;
         $description->description_editor = $data->description_editor;
-        $description = file_postupdate_standard_editor($description, 'description', $editoroptions, $editoroptions['context'], 'course_grouping_description', $description->id);
+        $description = file_postupdate_standard_editor($description, 'description', $editoroptions, $editoroptions['context'], 'grouping', 'description', $description->id);
         $DB->update_record('groupings', $description);
     }
 
@@ -209,7 +209,7 @@ function groups_update_group($data, $editform=false) {
 
     if ($editform && method_exists($editform, 'get_editor_options')) {
         $editoroptions = $editform->get_editor_options();
-        $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $editoroptions['context'], 'course_group_description', $data->id);
+        $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $editoroptions['context'], 'group', 'description', $data->id);
     }
 
     $DB->update_record('groups', $data);
@@ -238,7 +238,7 @@ function groups_update_grouping($data, $editoroptions=null) {
     $data->timemodified = time();
     $data->name         = trim($data->name);
     if ($editoroptions !== null) {
-        $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $editoroptions['context'], 'course_grouping_description', $data->id);
+        $data = file_postupdate_standard_editor($data, 'description', $editoroptions, $editoroptions['context'], 'grouping', 'description', $data->id);
     }
     $DB->update_record('groupings', $data);
     //trigger groups events
@@ -282,7 +282,7 @@ function groups_delete_group($grouporid) {
     // Delete all files associated with this group
     $context = get_context_instance(CONTEXT_COURSE, $group->courseid);
     $fs = get_file_storage();
-    $files = $fs->get_area_files($context->id, 'course_group_description', $groupid);
+    $files = $fs->get_area_files($context->id, 'group', 'description', $groupid);
     foreach ($files as $file) {
         $file->delete();
     }
@@ -323,7 +323,7 @@ function groups_delete_grouping($groupingorid) {
 
     $context = get_context_instance(CONTEXT_COURSE, $grouping->courseid);
     $fs = get_file_storage();
-    $files = $fs->get_area_files($context->id, 'course_grouping_description', $groupingid);
+    $files = $fs->get_area_files($context->id, 'grouping', 'description', $groupingid);
     foreach ($files as $file) {
         $file->delete();
     }
@@ -388,8 +388,6 @@ function groups_delete_groupings_groups($courseid, $showfeedback=false) {
 
     // Delete all files associated with groupings for this course
     $context = get_context_instance(CONTEXT_COURSE, $courseid);
-    $fs = get_file_storage();
-    $fs->delete_area_files($context->id, 'course_group_description');
 
     //trigger groups events
     events_trigger('groups_groupings_groups_removed', $courseid);
@@ -427,6 +425,10 @@ function groups_delete_groups($courseid, $showfeedback=false) {
     $groupssql = "SELECT id FROM {groups} g WHERE g.courseid = ?";
     $DB->delete_records_select('event', "groupid IN ($groupssql)", array($courseid));
 
+    $context = get_context_instance(CONTEXT_COURSE, $courseid);
+    $fs = get_file_storage();
+    $fs->delete_area_files($context->id, 'group');
+
     $DB->delete_records('groups', array('courseid'=>$courseid));
 
     //trigger groups events
@@ -458,12 +460,12 @@ function groups_delete_groupings($courseid, $showfeedback=false) {
     // remove the groupingid from all course modules
     $DB->set_field('course_modules', 'groupingid', 0, array('course'=>$courseid));
 
-    $DB->delete_records('groupings', array('courseid'=>$courseid));
-
     // Delete all files associated with groupings for this course
     $context = get_context_instance(CONTEXT_COURSE, $courseid);
     $fs = get_file_storage();
-    $fs->delete_area_files($context->id, 'course_grouping_description');
+    $fs->delete_area_files($context->id, 'grouping');
+
+    $DB->delete_records('groupings', array('courseid'=>$courseid));
 
     //trigger groups events
     events_trigger('groups_groupings_deleted', $courseid);
@@ -508,7 +510,7 @@ function groups_get_potential_members($courseid, $roleid = null, $cohortid = nul
     $listofcontexts = get_related_contexts_string($context);
 
     list($esql, $params) = get_enrolled_sql($context);
-    
+
     if ($roleid) {
         $params['roleid'] = $roleid;
         $where = "WHERE u.id IN (SELECT userid
index 1b9649f..85149ea 100644 (file)
@@ -159,7 +159,7 @@ foreach ($members as $gpgid=>$groupdata) {
         }
         $line = array();
         $name = format_string($groups[$gpid]->name);
-        $description = file_rewrite_pluginfile_urls($groups[$gpid]->description, 'pluginfile.php', $context->id, 'course_group_description', $gpid);
+        $description = file_rewrite_pluginfile_urls($groups[$gpid]->description, 'pluginfile.php', $context->id, 'group', 'description', $gpid);
         $options = new stdClass;
         $options->noclean = true;
         $jsdescription = trim(format_text($description, $groups[$gpid]->descriptionformat, $options));
@@ -184,7 +184,7 @@ foreach ($members as $gpgid=>$groupdata) {
         echo $OUTPUT->heading($strnotingrouping, 3);
     } else {
         echo $OUTPUT->heading(format_string($groupings[$gpgid]->name), 3);
-        $description = file_rewrite_pluginfile_urls($groupings[$gpgid]->description, 'pluginfile.php', $context->id, 'course_grouping_description', $gpgid);
+        $description = file_rewrite_pluginfile_urls($groupings[$gpgid]->description, 'pluginfile.php', $context->id, 'grouping', 'description', $gpgid);
         $options = new stdClass;
         $options->noclean = true;
         echo $OUTPUT->box(format_text($description, $groupings[$gpgid]->descriptionformat, $options), 'generalbox boxwidthnarrow boxaligncenter');
index a6a004d..46b2204 100644 (file)
--- a/index.php
+++ b/index.php
@@ -91,7 +91,7 @@
     echo $OUTPUT->header();
 
 /// Print Section
-    if ($SITE->numsections > 0) { 
+    if ($SITE->numsections > 0) {
 
         if (!$section = $DB->get_record('course_sections', array('course'=>$SITE->id, 'section'=>1))) {
             $DB->delete_records('course_sections', array('course'=>$SITE->id, 'section'=>1)); // Just in case
             $section->id = $DB->insert_record('course_sections', $section);
         }
 
-        if (!empty($section->sequence) or !empty($section->summary) or $editing) { 
+        if (!empty($section->sequence) or !empty($section->summary) or $editing) {
             echo $OUTPUT->box_start('generalbox sitetopic');
 
             /// If currently moving a file then show the current clipboard
             }
 
             $context = get_context_instance(CONTEXT_COURSE, SITEID);
-            $summarytext = file_rewrite_pluginfile_urls($section->summary, 'pluginfile.php', $context->id, 'course_section', $section->id);
+            $summarytext = file_rewrite_pluginfile_urls($section->summary, 'pluginfile.php', $context->id, 'course', 'section', $section->id);
             $summaryformatoptions = new object();
             $summaryformatoptions->noclean = true;
 
         }
     }
 
-    if (isloggedin() and !isguestuser() and isset($CFG->frontpageloggedin)) { 
+    if (isloggedin() and !isguestuser() and isset($CFG->frontpageloggedin)) {
         $frontpagelayout = $CFG->frontpageloggedin;
     } else {
         $frontpagelayout = $CFG->frontpage;
     }
 
-    foreach (explode(',',$frontpagelayout) as $v) {  
+    foreach (explode(',',$frontpagelayout) as $v) {
         switch ($v) {     /// Display the main part of the front page.
             case FRONTPAGENEWS:
                 if ($SITE->newsitems) { // Print forums only when needed
                 }
             break;
 
-            case FRONTPAGECOURSELIST:                
+            case FRONTPAGECOURSELIST:
                 if (isloggedin() and !has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM)) and !isguestuser() and empty($CFG->disablemycourses)) {
                     echo html_writer::tag('a', get_string('skipa', 'access', moodle_strtolower(get_string('mycourses'))), array('href'=>'#skipmycourses', 'class'=>'skip-block'));
                     echo $OUTPUT->heading(get_string('mycourses'), 2, 'headingblock header');
                     echo $OUTPUT->heading(get_string('availablecourses'), 2, 'headingblock header');
                     print_courses(0);
                     echo html_writer::tag('span', '', array('class'=>'skip-block-to', 'id'=>'skipavailablecourses'));
-                }                
+                }
             break;
 
             case FRONTPAGECATEGORYNAMES:
index a24832e..29f3084 100755 (executable)
@@ -430,7 +430,7 @@ $string['statsdisable'] = 'Stats is not enabled';
 $string['statsnodata'] = 'There is no available data for that combination of course and time period';
 $string['storedfilecannotcreatefiledirs'] = 'Can not create local file pool directories, please verify permissions in dataroot.';
 $string['storedfilecannotread'] = 'Can not read file, either file does not exist or there are permission problems';
-$string['storedfilenotcreated'] = 'Can not create file "{$a->contextid}/{$a->filearea}/{$a->itemid}/{$a->filepath}/{$a->filename}"';
+$string['storedfilenotcreated'] = 'Can not create file "{$a->contextid}/{$a->component}/{$a->filearea}/{$a->itemid}/{$a->filepath}/{$a->filename}"';
 $string['storedfileproblem'] = 'Unknown exception related to local files ({$a})';
 $string['tagdisabled'] = 'Tags are disabled!';
 $string['tagnotfound'] = 'The specified tag was not found in the database';
index 5be6869..d1211a4 100644 (file)
@@ -110,7 +110,7 @@ $string['invalidaddformat'] = 'Invalid add format passed to portfolio_add_button
 $string['invalidbuttonproperty'] = 'Could not find that property ({$a}) of portfolio_button';
 $string['invalidconfigproperty'] = 'Could not find that config property ({$a->property} of {$a->class})';
 $string['invalidexportproperty'] = 'Could not find that export config property ({$a->property} of {$a->class})';
-$string['invalidfileareaargs'] = 'Invalid file area arguments passed to set_file_and_format_data - must contain contextid, filearea and itemid';
+$string['invalidfileareaargs'] = 'Invalid file area arguments passed to set_file_and_format_data - must contain contextid, component, filearea and itemid';
 $string['invalidformat'] = 'Something is exporting an invalid format, {$a}';
 $string['invalidinstance'] = 'Could not find that portfolio instance';
 $string['invalidpreparepackagefile'] = 'Invalid call to prepare_package_file - either single or multifiles must be set';
index de44b62..cd337a0 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="lib/db" VERSION="20100624" COMMENT="XMLDB file for core Moodle tables"
+<XMLDB PATH="lib/db" VERSION="20100625" COMMENT="XMLDB file for core Moodle tables"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
 >
         <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me"/>
       </KEYS>
     </TABLE>
-    <TABLE NAME="files" COMMENT="description of files, content stored in sha1 file pool" PREVIOUS="message_working" NEXT="repository">
+    <TABLE NAME="files" COMMENT="description of files, content is stored in sha1 file pool" PREVIOUS="message_working" NEXT="repository">
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="contenthash"/>
         <FIELD NAME="contenthash" TYPE="char" LENGTH="40" NOTNULL="true" SEQUENCE="false" COMMENT="sha1 hash of file content" PREVIOUS="id" NEXT="pathnamehash"/>
         <FIELD NAME="pathnamehash" TYPE="char" LENGTH="40" NOTNULL="true" SEQUENCE="false" COMMENT="complete file path sha1 hash - unique for each file" PREVIOUS="contenthash" NEXT="contextid"/>
-        <FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The context id defined in context table - identifies the instance of plugin owning the file" PREVIOUS="pathnamehash" NEXT="filearea"/>
-        <FIELD NAME="filearea" TYPE="char" LENGTH="50" NOTNULL="true" SEQUENCE="false" COMMENT="Like &quot;coursefiles&quot;. &quot;submission&quot;, &quot;intro&quot; and &quot;content&quot; (images and swf linked from summaries), etc." PREVIOUS="contextid" NEXT="itemid"/>
+        <FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The context id defined in context table - identifies the instance of plugin owning the file" PREVIOUS="pathnamehash" NEXT="component"/>
+        <FIELD NAME="component" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false" COMMENT="Full name of the component owning the area" PREVIOUS="contextid" NEXT="filearea"/>
+        <FIELD NAME="filearea" TYPE="char" LENGTH="50" NOTNULL="true" SEQUENCE="false" COMMENT="Like &quot;coursefiles&quot;. &quot;submission&quot;, &quot;intro&quot; and &quot;content&quot; (images and swf linked from summaries), etc." PREVIOUS="component" NEXT="itemid"/>
         <FIELD NAME="itemid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="Optional - some plugin specific item id (eg. forum post, blog entry or assignment submission, user id for user files)" PREVIOUS="filearea" NEXT="filepath"/>
         <FIELD NAME="filepath" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="Optional - relative path to file from module content root, useful in Scorm and Resource mod - most of the mods do not need this" PREVIOUS="itemid" NEXT="filename"/>
         <FIELD NAME="filename" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="The full Unicode name of this file (case sensitive) - some chars are not allowed though" PREVIOUS="filepath" NEXT="userid"/>
         <KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id" PREVIOUS="contextid"/>
       </KEYS>
       <INDEXES>
-        <INDEX NAME="filearea-contextid-itemid" UNIQUE="false" FIELDS="filearea, contextid, itemid" NEXT="contenthash"/>
-        <INDEX NAME="contenthash" UNIQUE="false" FIELDS="contenthash" PREVIOUS="filearea-contextid-itemid" NEXT="pathnamehash"/>
+        <INDEX NAME="component-filearea-contextid-itemid" UNIQUE="false" FIELDS="component, filearea, contextid, itemid" NEXT="contenthash"/>
+        <INDEX NAME="contenthash" UNIQUE="false" FIELDS="contenthash" PREVIOUS="component-filearea-contextid-itemid" NEXT="pathnamehash"/>
         <INDEX NAME="pathnamehash" UNIQUE="true" FIELDS="pathnamehash" PREVIOUS="contenthash"/>
       </INDEXES>
     </TABLE>
index 2555d17..ab21857 100644 (file)
@@ -497,6 +497,7 @@ function xmldb_main_upgrade($oldversion) {
         $table->add_field('contenthash', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null);
         $table->add_field('pathnamehash', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null);
         $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
+        $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
         $table->add_field('filearea', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, null, null);
         $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
         $table->add_field('filepath', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
@@ -517,7 +518,7 @@ function xmldb_main_upgrade($oldversion) {
         $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
 
     /// Adding indexes to table files
-        $table->add_index('filearea-contextid-itemid', XMLDB_INDEX_NOTUNIQUE, array('filearea', 'contextid', 'itemid'));
+        $table->add_index('component-filearea-contextid-itemid', XMLDB_INDEX_NOTUNIQUE, array('component', 'filearea', 'contextid', 'itemid'));
         $table->add_index('contenthash', XMLDB_INDEX_NOTUNIQUE, array('contenthash'));
         $table->add_index('pathnamehash', XMLDB_INDEX_UNIQUE, array('pathnamehash'));
 
@@ -4846,6 +4847,64 @@ WHERE gradeitemid IS NOT NULL AND grademax IS NOT NULL");
         upgrade_main_savepoint($result, 2010062101);
     }
 
+    if ($result && $oldversion < 2010070300) {
+        //TODO: this is a temporary hack for upgrade from PR3, to be removed later
+
+        // Define field component to be added to files
+        $table = new xmldb_table('files');
+        $field = new xmldb_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, 'contextid');
+
+        // Conditionally upgrade from PR3
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+            $index = new xmldb_index('filearea-contextid-itemid', XMLDB_INDEX_NOTUNIQUE, array('filearea', 'contextid', 'itemid'));
+            $dbman->drop_index($table, $index);
+            $index = new xmldb_index('component-filearea-contextid-itemid', XMLDB_INDEX_NOTUNIQUE, array('component', 'filearea', 'contextid', 'itemid'));
+            $dbman->add_index($table, $index);
+
+            // Rename areas as add proper component
+            $areas = $DB->get_fieldset_sql("SELECT DISTINCT filearea FROM {files}");
+            if ($areas) {
+                // fix incorrect itemids
+                $DB->execute("UPDATE {files} SET itemid = 0 WHERE filearea = 'category_description'"); // context identifies instances
+                $DB->execute("UPDATE {files} SET itemid = 0 WHERE filearea = 'user_profile'"); // context identifies instances
+                $DB->execute("UPDATE {files} SET itemid = 0 WHERE filearea = 'block_html'"); // context identifies instances
+                foreach ($areas as $area) {
+                    // rename areas
+                    if ($area === 'course_backup') {
+                        $area = 'backup_course';
+                    } else if ($area === 'section_backup') {
+                        $area = 'backup_section';
+                    } else if ($area === 'activity_backup') {
+                        $area = 'backup_activity';
+                    } else if ($area === 'category_description') {
+                        $area = 'coursecat_description';
+                    }
+                    if ($area === 'block_html') {
+                        $component = 'block_html';
+                        $filearea = 'content';
+                    } else {
+                        list($component, $filearea) = explode('_', $area, 2);
+                        // note this is just a hack which guesses plugin from old PRE3 files code, the whole point of adding component is to get rid of this guessing
+                        if (file_exists("$CFG->dirroot/mod/$component/lib.php")) {
+                            $component = 'mod_'.$component;
+                        }
+                    }
+                    $DB->execute("UPDATE {files} SET component = :component, filearea = :filearea WHERE filearea = :area", array('component'=>$component, 'filearea'=>$filearea, 'area'=>$area));
+                }
+                // Update all hashes
+                $rs = $DB->get_recordset('files', array());
+                foreach ($rs as $file) {
+                    $pathnamehash = sha1("/$file->contextid/$file->component/$file->filearea/$file->itemid".$file->filepath.$file->filename);
+                    $DB->set_field('files', 'pathnamehash', $pathnamehash, array('id'=>$file->id));
+                }
+                $rs->close();
+            }
+        }
+
+        // Main savepoint reached
+        upgrade_main_savepoint($result, 2010070300);
+    }
 
 
     return $result;
index 923c1d7..547b2f0 100644 (file)
@@ -105,11 +105,13 @@ function upgrade_migrate_files_course($context, $path, $delete) {
         }
 
         if (strpos($path, '/backupdata/') === 0) {
-            $filearea = 'course_backup';
-            $filepath = substr($path, strlen('/backupdata'));
+            $component = 'backup';
+            $filearea  = 'course';
+            $filepath  = substr($path, strlen('/backupdata'));
         } else {
-            $filearea = 'course_content';
-            $filepath = $path;
+            $component = 'course';
+            $filearea  = 'legacy';
+            $filepath  = $path;
         }
 
         if ($item->isFile()) {
@@ -126,8 +128,8 @@ function upgrade_migrate_files_course($context, $path, $delete) {
                 continue;
             }
 
-            if (!$fs->file_exists($context->id, $filearea, '0', $filepath, $filename)) {
-                $file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>0, 'filepath'=>$filepath, 'filename'=>$filename,
+            if (!$fs->file_exists($context->id, $component, $filearea, '0', $filepath, $filename)) {
+                $file_record = array('contextid'=>$context->id, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>0, 'filepath'=>$filepath, 'filename'=>$filename,
                                      'timecreated'=>$item->getCTime(), 'timemodified'=>$item->getMTime());
                 if ($fs->create_file_from_pathname($file_record, $fullpathname.$item->getFilename())) {
                     if ($delete_this) {
@@ -148,7 +150,7 @@ function upgrade_migrate_files_course($context, $path, $delete) {
             }
             $filepath = ($filepath.$dirname.'/');
             if ($filepath !== '/backupdata/') {
-                $fs->create_directory($context->id, $filearea, 0, $filepath);
+                $fs->create_directory($context->id, $component, $filearea, 0, $filepath);
             }
 
             //migrate recursively all subdirectories
@@ -203,8 +205,8 @@ function upgrade_migrate_files_blog() {
                 continue;
             }
 
-            if (!$fs->file_exists(SYSCONTEXTID, 'blog', $entry->id, '/', $filename)) {
-                $file_record = array('contextid'=>SYSCONTEXTID, 'filearea'=>'blog_attachment', 'itemid'=>$entry->id, 'filepath'=>'/', 'filename'=>$filename,
+            if (!$fs->file_exists(SYSCONTEXTID, 'blog', 'attachment', $entry->id, '/', $filename)) {
+                $file_record = array('contextid'=>SYSCONTEXTID, 'component'=>'blog', 'filearea'=>'attachment', 'itemid'=>$entry->id, 'filepath'=>'/', 'filename'=>$filename,
                                      'timecreated'=>filectime($pathname), 'timemodified'=>filemtime($pathname), 'userid'=>$entry->userid);
                 $fs->create_file_from_pathname($file_record, $pathname);
             }
diff --git a/lib/file/file_browser.php b/lib/file/file_browser.php
deleted file mode 100644 (file)
index 752bd60..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-<?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/>.
-
-
-/**
- * Utility class for browsing of files.
- *
- * @package    moodlecore
- * @subpackage file-browser
- * @copyright  2008 Petr Skoda (http://skodak.org)
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-require_once("$CFG->libdir/file/file_info.php");
-require_once("$CFG->libdir/file/file_info_module.php");
-require_once("$CFG->libdir/file/file_info_stored.php");
-require_once("$CFG->libdir/file/file_info_system.php");
-require_once("$CFG->libdir/file/file_info_user.php");
-require_once("$CFG->libdir/file/file_info_coursecat.php");
-require_once("$CFG->libdir/file/file_info_course.php");
-require_once("$CFG->libdir/file/file_info_coursesection.php");
-require_once("$CFG->libdir/file/file_info_coursesectionbackup.php");
-require_once("$CFG->libdir/file/file_info_coursefile.php");
-require_once("$CFG->libdir/file/virtual_root_file.php");
-
-/**
- * This class provides the main entry point for other code wishing to get
- * information about files.
- *
- * The whole file storage for a Moodle site can be seen as a huge virtual tree.
- * The spine of the tree is the tree of contexts (system, course-categories,
- * courses, modules, also users). Then, within each context, there may be any number of
- * file areas, and a file area contains folders and files. The various file_info
- * subclasses return info about the things in this tree. They should be obtained
- * from an instance of this class.
- *
- * This virtual tree is different for each user depending of his/her current permissions.
- * Some branches such as draft areas are hidden, but accessible.
- *
- * Always use this abstraction when you need to access module files from core code.
- */
-class file_browser {
-
-    /**
-     * Looks up file_info instance
-     * @param object $context
-     * @param string $filearea
-     * @param int $itemid
-     * @param string $filepath
-     * @param string $filename
-     * @return file_info instance or null if not found or access not allowed
-     */
-    public function get_file_info($context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        switch ($context->contextlevel) {
-            case CONTEXT_SYSTEM:
-                return $this->get_file_info_system($context, $filearea, $itemid, $filepath, $filename);
-            case CONTEXT_USER:
-                return $this->get_file_info_user($context, $filearea, $itemid, $filepath, $filename);
-            case CONTEXT_COURSECAT:
-                return $this->get_file_info_coursecat($context, $filearea, $itemid, $filepath, $filename);
-            case CONTEXT_COURSE:
-                return $this->get_file_info_course($context, $filearea, $itemid, $filepath, $filename);
-            case CONTEXT_MODULE:
-                return $this->get_file_info_module($context, $filearea, $itemid, $filepath, $filename);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns info about the files at System context
-     * @param object $context
-     * @param string $filearea
-     * @return file_info_system
-     */
-    private function get_file_info_system($context, $filearea=null) {
-        if (is_null($filearea)) {
-            return new file_info_system($this);
-        }
-        //TODO: question files browsing
-
-        return null;
-    }
-
-    /**
-     * Returns info about the files at User context
-     * @param object $context
-     * @param string $filearea
-     * @return file_info_system
-     */
-    private function get_file_info_user($context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        global $USER, $DB;
-        if ($context->instanceid == $USER->id) {
-            $user = $USER;
-        } else {
-            $user = $DB->get_record('user', array('id'=>$context->instanceid));
-        }
-
-        if (isguestuser($user) or empty($user->id)) {
-            // no guests or not logged in users here
-            return null;
-        }
-
-        if ($user->deleted) {
-            return null;
-        }
-
-        if (is_null($filearea)) {
-            // access control: list areas only for myself
-            if ($context->instanceid != $USER->id) {
-                return null;
-            }
-
-            return new file_info_user($this, $context);
-
-        } else {
-            $methodname = "get_file_info_$filearea";
-            if (method_exists($this, $methodname)) {
-                return $this->$methodname($user, $context, $filearea, $itemid, $filepath, $filename);
-            }
-        }
-
-        return null;
-    }
-
-    private function get_file_info_user_private($user, $context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        global $USER, $CFG;
-
-        $fs = get_file_storage();
-
-        // access control: only my files for now, nobody else
-        if ($context->instanceid != $USER->id) {
-            return null;
-        }
-
-        if (is_null($itemid)) {
-            return new file_info_user($this, $context);
-        }
-        $filepath = is_null($filepath) ? '/' : $filepath;
-        $filename = is_null($filename) ? '.' : $filename;
-
-        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;
-            }
-        }
-        $urlbase = $CFG->wwwroot.'/userfile.php';
-        return new file_info_stored($this, $context, $storedfile, $urlbase, get_string('areauserpersonal', 'repository'), false, true, true, false);
-    }
-
-    private function get_file_info_user_profile($user, $context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        global $USER, $CFG;
-
-        $fs = get_file_storage();
-
-        if (is_null($itemid)) {
-            return new file_info_user($this, $context);
-        }
-
-        // access controll here must match user edit forms
-        if ($user->id == $USER->id) {
-             if (!has_capability('moodle/user:editownprofile', get_context_instance(CONTEXT_SYSTEM))) {
-                return null;
-             }
-        } else {
-            if (!has_capability('moodle/user:editprofile', $context) and !has_capability('moodle/user:update', $context)) {
-                return null;
-            }
-        }
-
-        $filepath = is_null($filepath) ? '/' : $filepath;
-        $filename = is_null($filename) ? '.' : $filename;
-
-        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;
-            }
-        }
-        $urlbase = $CFG->wwwroot.'/userfile.php';
-        return new file_info_stored($this, $context, $storedfile, $urlbase, get_string('areauserprofile', 'repository'), false, true, true, false);
-    }
-
-    private function get_file_info_user_draft($user, $context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        global $USER, $CFG;
-
-        $fs = get_file_storage();
-
-        // access control: only my files
-        if ($context->instanceid != $USER->id) {
-            return null;
-        }
-
-        if (empty($itemid)) {
-            // do not browse itemids - you most know the draftid to see what is there
-            return null;
-        }
-        $urlbase = $CFG->wwwroot.'/draftfile.php';
-
-        $filepath = is_null($filepath) ? '/' : $filepath;
-        $filename = is_null($filename) ? '.' : $filename;
-
-        if (!$storedfile = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) {
-            if ($filepath === '/' and $filename === '.') {
-                $storedfile = new virtual_root_file($context->id, $filearea, $itemid);
-            } else {
-                // not found
-                return null;
-            }
-        }
-        return new file_info_stored($this, $context, $storedfile, $urlbase, get_string('areauserdraft', 'repository'), true, true, true, true);
-    }
-
-    private function get_file_info_user_backup($user, $context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        global $USER, $CFG;
-
-        $fs = get_file_storage();
-
-        // only current user can access this area
-        if ($context->instanceid != $USER->id) {
-            return null;
-        }
-        if ($USER->id != $user->id) {
-            return null;
-        }
-
-        $urlbase = $CFG->wwwroot.'/userfile.php';
-
-        $filepath = is_null($filepath) ? '/' : $filepath;
-        $filename = is_null($filename) ? '.' : $filename;
-
-        if (!$storedfile = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) {
-            if ($filepath === '/' and $filename === '.') {
-                $storedfile = new virtual_root_file($context->id, $filearea, 0);
-            } else {
-                // not found
-                return null;
-            }
-        }
-        return new file_info_stored($this, $context, $storedfile, $urlbase, get_string('areauserbackup', 'repository'), false, true, true, false);
-    }
-
-    private function get_file_info_coursecat($context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        global $DB, $CFG;
-
-        $fs = get_file_storage();
-
-        if (!$category = $DB->get_record('course_categories', array('id'=>$context->instanceid))) {
-            return null;
-        }
-
-        if (!$category->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
-            return null;
-        }
-
-        if (!is_null($filearea) and !in_array($filearea, array('coursecat_intro'))) {
-            // file area does not exist, sorry
-            $filearea = null;
-        }
-
-        if (is_null($filearea) or is_null($itemid)) {
-            return new file_info_coursecat($this, $context, $category);
-
-        } else {
-            if ($filearea == 'coursecat_intro') {
-                if (!has_capability('moodle/course:update', $context)) {
-                    return null;
-                }
-
-                $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;
-                    }
-                }
-                return new file_info_stored($this, $context, $storedfile, $urlbase, get_string('areacategoryintro', 'repository'), false, true, true, false);
-            }
-        }
-
-        return null;
-    }
-
-    private function get_file_info_course($context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        global $DB, $COURSE;
-
-        if ($context->instanceid == $COURSE->id) {
-            $course = $COURSE;
-        } else if (!$course = $DB->get_record('course', array('id'=>$context->instanceid))) {
-            return null;
-        }
-
-        if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
-            return null;
-        }
-
-        if (!is_null($filearea) and !in_array($filearea, array('course_summary', 'course_content', 'course_section', 'course_backup', 'section_backup'))) {
-            // file area does not exist, sorry
-            $filearea = null;
-        }
-
-        if ($filearea === 'course_content' and $course->legacyfiles != 2) {
-            // bad luck, legacy course files not used any more
-            return null;
-        }
-
-        $filepath = is_null($filepath) ? '/' : $filepath;
-        $filename = is_null($filename) ? '.' : $filename;
-
-        if (is_null($filearea)) {
-            return new file_info_course($this, $context, $course);
-
-        } else {
-            $methodname = "get_file_info_$filearea";
-            if (method_exists($this, $methodname)) {
-                return $this->$methodname($course, $context, $filearea, $itemid, $filepath, $filename);
-            }
-        }
-
-        return null;
-    }
-
-    private function get_file_info_course_summary($course, $context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        global $CFG;
-
-        $fs = get_file_storage();
-
-        if (!has_capability('moodle/course:update', $context)) {
-            return null;
-        }
-        if (is_null($itemid)) {
-            return new file_info_course($this, $context, $course);
-        }
-
-        $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;
-            }
-        }
-        return new file_info_stored($this, $context, $storedfile, $urlbase, get_string('areacourseintro', 'repository'), false, true, true, false);
-
-    }
-
-    private function get_file_info_course_section($course, $context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        global $CFG, $DB;
-
-        $fs = get_file_storage();
-
-        if (!has_capability('moodle/course:update', $context)) {
-            return null;
-        }
-        $urlbase = $CFG->wwwroot.'/pluginfile.php';
-
-        if (empty($itemid)) {
-            // list all sections
-            return new file_info_coursesection($this, $context, $course);
-        }
-
-        if (!$section = $DB->get_record('course_sections', array('course'=>$course->id, 'id'=>$itemid))) {
-            return null; // does not exist
-        }
-
-        if (!$storedfile = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) {
-            if ($filepath === '/' and $filename === '.') {
-                $storedfile = new virtual_root_file($context->id, $filearea, $itemid);
-            } else {
-                // not found
-                return null;
-            }
-        }
-        return new file_info_stored($this, $context, $storedfile, $urlbase, $section->section, true, true, true, false);
-
-    }
-
-    private function get_file_info_course_backup($course, $context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        global $CFG;
-
-        $fs = get_file_storage();
-
-        if (!has_capability('moodle/backup:backupcourse', $context) and !has_capability('moodle/restore:restorecourse', $context)) {
-            return null;
-        }
-        if (is_null($itemid)) {
-            return new file_info_course($this, $context, $course);
-        }
-
-        $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;
-            }
-        }
-
-        $downloadable = has_capability('moodle/backup:downloadfile', $context);
-        $uploadable   = has_capability('moodle/restore:uploadfile', $context);
-        return new file_info_stored($this, $context, $storedfile, $urlbase, get_string('coursebackup', 'repository'), false, $downloadable, $uploadable, false);
-
-    }
-
-    private function get_file_info_section_backup($course, $context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        global $CFG, $DB;
-
-        if (!has_capability('moodle/backup:backupcourse', $context) and !has_capability('moodle/restore:restorecourse', $context)) {
-            return null;
-        }
-
-        $fs = get_file_storage();
-        if (empty($itemid)) {
-            // list all sections
-            return new file_info_coursesectionbackup($this, $context, $course);
-        }
-
-        if (!$section = $DB->get_record('course_sections', array('course'=>$course->id, 'id'=>$itemid))) {
-            return null; // does not exist
-        }
-
-
-        $urlbase = $CFG->wwwroot.'/pluginfile.php';
-        if (!$storedfile = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) {
-            if ($filepath === '/' and $filename === '.') {
-                $storedfile = new virtual_root_file($context->id, $filearea, $itemid);
-            } else {
-                // not found
-                return null;
-            }
-        }
-
-        $downloadable = has_capability('moodle/backup:downloadfile', $context);
-        $uploadable   = has_capability('moodle/restore:uploadfile', $context);
-        return new file_info_stored($this, $context, $storedfile, $urlbase, $section->id, true, $downloadable, $uploadable, false);
-    }
-
-    private function get_file_info_course_content($course, $context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        $fs = get_file_storage();
-
-        if (!has_capability('moodle/course:managefiles', $context)) {
-            return null;
-        }
-        if (is_null($itemid)) {
-            return new file_info_course($this, $context, $course);
-        }
-
-        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;
-            }
-        }
-
-        return new file_info_coursefile($this, $context, $storedfile);
-    }
-
-    private function get_file_info_module($context, $filearea=null, $itemid=null, $filepath=null, $filename=null) {
-        global $COURSE, $DB, $CFG;
-
-        $fs = get_file_storage();
-
-        if (!$cm = get_coursemodule_from_id('', $context->instanceid)) {
-            return null;
-        }
-
-        if ($cm->course == $COURSE->id) {
-            $course = $COURSE;
-        } else if (!$course = $DB->get_record('course', array('id'=>$cm->course))) {
-            return null;
-        }
-
-        $modinfo = get_fast_modinfo($course);
-
-        if (empty($modinfo->cms[$cm->id]->uservisible)) {
-            return null;
-        }
-
-        $modname = $modinfo->cms[$cm->id]->modname;
-
-        $libfile = "$CFG->dirroot/mod/$modname/lib.php";
-        if (!file_exists($libfile)) {
-            return null;
-        }
-        require_once($libfile);
-
-        $fileinfofunction = $modname.'_get_file_areas';
-        if (function_exists($fileinfofunction)) {
-            $areas = $fileinfofunction($course, $cm, $context);
-        } else {
-            $areas = array();
-        }
-        if (!isset($areas[$modname.'_intro'])
-          and plugin_supports('mod', $modname, FEATURE_MOD_INTRO, true)
-          and has_capability('moodle/course:managefiles', $context)) {
-            $areas = array_merge(array($modname.'_intro'=>get_string('moduleintro')), $areas);
-        }
-
-        if (has_capability('moodle/backup:downloadfile', $context)) {
-            $areas = array_merge(array('activity_backup'=>get_string('activitybackup', 'repository')), $areas);
-        }
-
-        if (empty($areas)) {
-            return null;
-        }
-
-        if ($filearea === $modname.'_intro' || $filearea === 'activity_backup') {
-            // always only itemid 0
-            if (!has_capability('moodle/course:managefiles', $context)) {
-                return null;
-            }
-            // need downloadfile cap when accessing activity_backup area
-            if ($filearea === 'activity_backup' && !has_capability('moodle/backup:downloadfile', $context)) {
-                return null;
-            }
-
-            $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;
-                }
-            }
-            return new file_info_stored($this, $context, $storedfile, $urlbase, $areas[$filearea], false, true, true, false);
-
-        } else if (is_null($filearea)) {
-            // modules have to decide if they want to use itemids
-            return new file_info_module($this, $course, $cm, $context, $areas);
-
-        } else if (!array_key_exists($filearea, $areas)) {
-            return null;
-
-        } else {
-            $fileinfofunction = $modname.'_get_file_info';
-            if (function_exists($fileinfofunction)) {
-                return $fileinfofunction($this, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename);
-            }
-        }
-
-        return null;
-    }
-}
diff --git a/lib/file/file_info_course.php b/lib/file/file_info_course.php
deleted file mode 100644 (file)
index 3cdd866..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-<?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/>.
-
-
-/**
- * Utility class for browsing of course files.
- *
- * @package    moodlecore
- * @subpackage file-browser
- * @copyright  2008 Petr Skoda (http://skodak.org)
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-/**
- * Represents a course context in the tree navigated by @see{file_browser}.
- */
-class file_info_course extends file_info {
-    protected $course;
-
-    public function __construct($browser, $context, $course) {
-        global $DB;
-        parent::__construct($browser, $context);
-        $this->course   = $course;
-    }
-
-    /**
-     * Returns list of standard virtual file/directory identification.
-     * The difference from stored_file parameters is that null values
-     * are allowed in all fields
-     * @return array with keys contextid, filearea, itemid, filepath and filename
-     */
-    public function get_params() {
-        return array('contextid'=>$this->context->id,
-                     'filearea' =>null,
-                     'itemid'   =>null,
-                     'filepath' =>null,
-                     'filename' =>null);
-    }
-
-    public function get_visible_name() {
-        return ($this->course->id == SITEID) ? get_string('frontpage', 'admin') : format_string($this->course->fullname);
-    }
-
-    /**
-     * Can I add new files or directories?
-     * @return bool
-     */
-    public function is_writable() {
-        return false;
-    }
-
-    /**
-     * Is directory?
-     * @return bool
-     */
-    public function is_directory() {
-        return true;
-    }
-
-    /**
-     * Returns list of children.
-     * @return array of file_info instances
-     */
-    public function get_children() {
-        $children = array();
-
-        if ($child = $this->browser->get_file_info($this->context, 'course_summary', 0)) {
-            $children[] = $child;
-        }
-        if ($child = $this->browser->get_file_info($this->context, 'course_section')) {
-            $children[] = $child;
-        }
-        if ($child = $this->browser->get_file_info($this->context, 'section_backup')) {
-            $children[] = $child;
-        }
-
-        if ($child = $this->browser->get_file_info($this->context, 'course_backup', 0)) {
-            $children[] = $child;
-        }
-
-        if ($this->course->legacyfiles == 2) {
-            if ($child = $this->browser->get_file_info($this->context, 'course_content', 0)) {
-                $children[] = $child;
-            }
-        }
-
-        $modinfo = get_fast_modinfo($this->course);
-        foreach ($modinfo->cms as $cminfo) {
-            if (empty($cminfo->uservisible)) {
-                continue;
-            }
-            $modcontext = get_context_instance(CONTEXT_MODULE, $cminfo->id);
-            if ($child = $this->browser->get_file_info($modcontext)) {
-                $children[] = $child;
-            }
-        }
-
-        return $children;
-    }
-
-    /**
-     * Returns parent file_info instance
-     * @return file_info or null for root
-     */
-    public function get_parent() {
-        //TODO: error checking if get_parent_contextid() returns false
-        $pcid = get_parent_contextid($this->context);
-        $parent = get_context_instance_by_id($pcid);
-        return $this->browser->get_file_info($parent);
-    }
-}
diff --git a/lib/file/file_info_coursefile.php b/lib/file/file_info_coursefile.php
deleted file mode 100644 (file)
index 0d1073f..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-<?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/>.
-
-
-/**
- * Utility class for browsing of coursefiles.
- *
- * @package    moodlecore
- * @subpackage file-browser
- * @copyright  2008 Petr Skoda (http://skodak.org)
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-/**
- * Subclass of file_info_stored for files in the course files area.
- */
-class file_info_coursefile extends file_info_stored {
-    public function __construct($browser, $context, $storedfile) {
-        global $CFG;
-        $urlbase = $CFG->wwwroot.'/file.php';
-        parent::__construct($browser, $context, $storedfile, $urlbase, get_string('coursefiles'), false, true, true, false);
-    }
-
-    /**
-     * Returns file download url
-     * @param bool $forcedownload
-     * @param bool $htts force https
-     * @return string url
-     */
-    public function get_url($forcedownload=false, $https=false) {
-        global $CFG;
-
-        if (!$this->is_readable()) {
-            return null;
-        }
-
-        if ($this->lf->is_directory()) {
-            return null;
-        }
-
-        $filepath = $this->lf->get_filepath();
-        $filename = $this->lf->get_filename();
-        $courseid = $this->context->instanceid;
-
-        $path = '/'.$courseid.$filepath.$filename;
-
-        return file_encode_url($this->urlbase, $path, $forcedownload, $https);
-    }
-
-    /**
-     * Returns list of children.
-     * @return array of file_info instances
-     */
-    public function get_children() {
-        if (!$this->lf->is_directory()) {
-            return array();
-        }
-
-        $result = array();
-        $fs = get_file_storage();
-
-        $storedfiles = $fs->get_directory_files($this->context->id, 'course_content', 0, $this->lf->get_filepath(), false, true, "filepath, filename");
-        foreach ($storedfiles as $file) {
-            $result[] = new file_info_coursefile($this->browser, $this->context, $file);
-        }
-
-        return $result;
-    }
-}
diff --git a/lib/file/file_info_coursesection.php b/lib/file/file_info_coursesection.php
deleted file mode 100644 (file)
index d42f1ce..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-<?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/>.
-
-
-/**
- * Utility class for browsing of course section files.
- *
- * @package    moodlecore
- * @subpackage file-browser
- * @copyright  2008 Petr Skoda (http://skodak.org)
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-/**
- * Represents a course category context in the tree navigated by @see{file_browser}.
- */
-class file_info_coursesection extends file_info {
-    protected $course;
-
-    public function __construct($browser, $context, $course) {
-        parent::__construct($browser, $context);
-        $this->course = $course;
-    }
-
-    /**
-     * Returns list of standard virtual file/directory identification.
-     * The difference from stored_file parameters is that null values
-     * are allowed in all fields
-     * @return array with keys contextid, filearea, itemid, filepath and filename
-     */
-    public function get_params() {
-        return array('contextid'=>$this->context->id,
-                     'filearea' =>'course_section',
-                     'itemid'   =>null,
-                     'filepath' =>null,
-                     'filename' =>null);
-    }
-
-    /**
-     * Returns localised visible name.
-     * @return string
-     */
-    public function get_visible_name() {
-        $format = $this->course->format;
-        $sectionsname = get_string("coursesectionsummaries");
-
-        return $sectionsname;
-    }
-
-    /**
-     * Can I add new files or directories?
-     * @return bool
-     */
-    public function is_writable() {
-        return false;
-    }
-
-    /**
-     * Is directory?
-     * @return bool
-     */
-    public function is_directory() {
-        return true;
-    }
-
-    /**
-     * Returns list of children.
-     * @return array of file_info instances
-     */
-    public function get_children() {
-        global $DB;
-
-        $children = array();
-
-        $course_sections = $DB->get_records('course_sections', array('course'=>$this->course->id), 'section');
-        foreach ($course_sections as $section) {
-            if ($child = $this->browser->get_file_info($this->context, 'course_section', $section->id)) {
-                $children[] = $child;
-            }
-        }
-
-        return $children;
-    }
-
-    /**
-     * Returns parent file_info instance
-     * @return file_info or null for root
-     */
-    public function get_parent() {
-        return $this->browser->get_file_info($this->context);
-    }
-}
diff --git a/lib/file/file_info_coursesectionbackup.php b/lib/file/file_info_coursesectionbackup.php
deleted file mode 100644 (file)
index ae7664a..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-<?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/>.
-
-
-/**
- * Utility class for browsing of course section files.
- *
- * @package    moodlecore
- * @subpackage file-browser
- * @copyright  2010 Dongsheng Cai <dongsheng@moodle.com>
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-/**
- */
-class file_info_coursesectionbackup extends file_info {
-    protected $course;
-
-    public function __construct($browser, $context, $course) {
-        parent::__construct($browser, $context);
-        $this->course = $course;
-    }
-
-    /**
-     * Returns list of standard virtual file/directory identification.
-     * The difference from stored_file parameters is that null values
-     * are allowed in all fields
-     * @return array with keys contextid, filearea, itemid, filepath and filename
-     */
-    public function get_params() {
-        return array('contextid'=>$this->context->id,
-                     'filearea' =>'section_backup',
-                     'itemid'   =>null,
-                     'filepath' =>null,
-                     'filename' =>null);
-    }
-
-    /**
-     * Returns localised visible name.
-     * @return string
-     */
-    public function get_visible_name() {
-        $format = $this->course->format;
-        $sectionsname = get_string('sectionbackup', 'repository');
-
-        return $sectionsname;
-    }
-
-    /**
-     * Can I add new files or directories?
-     * @return bool
-     */
-    public function is_writable() {
-        return false;
-    }
-
-    /**
-     * Is directory?
-     * @return bool
-     */
-    public function is_directory() {
-        return true;
-    }
-
-    /**
-     * Returns list of children.
-     * @return array of file_info instances
-     */
-    public function get_children() {
-        global $DB;
-
-        $children = array();
-
-        $course_sections = $DB->get_records('course_sections', array('course'=>$this->course->id), 'section');
-        foreach ($course_sections as $section) {
-            if ($child = $this->browser->get_file_info($this->context, 'section_backup', $section->id)) {
-                $children[] = $child;
-            }
-        }
-
-        return $children;
-    }
-
-    /**
-     * Returns parent file_info instance
-     * @return file_info or null for root
-     */
-    public function get_parent() {
-        return $this->browser->get_file_info($this->context);
-    }
-}
-
diff --git a/lib/file/file_info_module.php b/lib/file/file_info_module.php
deleted file mode 100644 (file)
index d32129d..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-<?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/>.
-
-
-/**
- * Utility class for browsing of module files.
- *
- * @package    moodlecore
- * @subpackage file-browser
- * @copyright  2008 Petr Skoda (http://skodak.org)
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-/**
- * Represents a module context in the tree navigated by @see{file_browser}.
- */
-class file_info_module extends file_info {
-    protected $course;
-    protected $cm;
-    protected $areas;
-
-    public function __construct($browser, $course, $cm, $context, $areas) {
-        global $DB;
-        parent::__construct($browser, $context);
-        $this->course = $course;
-        $this->cm     = $cm;
-        $this->areas  = $areas;
-    }
-
-    /**
-     * Returns list of standard virtual file/directory identification.
-     * The difference from stored_file parameters is that null values
-     * are allowed in all fields
-     * @return array with keys contextid, filearea, itemid, filepath and filename
-     */
-    public function get_params() {
-        return array('contextid'=>$this->context->id,
-                     'filearea' =>null,
-                     'itemid'   =>null,
-                     'filepath' =>null,
-                     'filename' =>null);
-    }
-
-    /**
-     * Returns localised visible name.
-     * @return string
-     */
-    public function get_visible_name() {
-        return $this->cm->name.' ('.get_string('modulename', $this->cm->modname).')';
-    }
-
-    /**
-     * Can I add new files or directories?
-     * @return bool
-     */
-    public function is_writable() {
-        return false;
-    }
-
-    /**
-     * Is directory?
-     * @return bool
-     */
-    public function is_directory() {
-        return true;
-    }
-
-    /**
-     * Returns list of children.
-     * @return array of file_info instances
-     */
-    public function get_children() {
-        $children = array();
-        foreach ($this->areas as $area=>$desctiption) {
-            if ($child = $this->browser->get_file_info($this->context, $area, null)) {
-                $children[] = $child;
-            }
-        }
-        return $children;
-    }
-
-    /**
-     * Returns parent file_info instance
-     * @return file_info or null for root
-     */
-    public function get_parent() {
-        $pcid = get_parent_contextid($this->context);
-        $parent = get_context_instance_by_id($pcid);
-        return $this->browser->get_file_info($parent);
-    }
-}
diff --git a/lib/file/file_info_user.php b/lib/file/file_info_user.php
deleted file mode 100644 (file)
index 91fb9fe..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-<?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/>.
-
-
-/**
- * Utility class for browsing of user files.
- *
- * @package    moodlecore
- * @subpackage file-browser
- * @copyright  2008 Petr Skoda (http://skodak.org)
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-/**
- * Represents a user context in the tree navigated by @see{file_browser}.
- */
-class file_info_user extends file_info {
-    protected $user;
-
-    public function __construct($browser, $context) {
-        global $DB, $USER;
-
-        parent::__construct($browser, $context);
-
-        $userid = $context->instanceid;
-
-        if ($userid == $USER->id) {
-            $this->user = $USER;
-        } else {
-            // if context exists user record should exist too ;-)
-            $this->user = $DB->get_record('user', array('id'=>$userid));
-        }
-    }
-
-    /**
-     * Returns list of standard virtual file/directory identification.
-     * The difference from stored_file parameters is that null values
-     * are allowed in all fields
-     * @return array with keys contextid, filearea, itemid, filepath and filename
-     */
-    public function get_params() {
-        return array('contextid'=>$this->context->id,
-                     'filearea' =>null,
-                     'itemid'   =>null,
-                     'filepath' =>null,
-                     'filename' =>null);
-    }
-
-    /**
-     * Returns localised visible name.
-     * @return string
-     */
-    public function get_visible_name() {
-        return fullname($this->user, true);
-    }
-
-    /**
-     * Can I add new files or directories?
-     * @return bool
-     */
-    public function is_writable() {
-        return false;
-    }
-
-    /**
-     * Is directory?
-     * @return bool
-     */
-    public function is_directory() {
-        return true;
-    }
-
-    /**
-     * Returns list of children.
-     * @return array of file_info instances
-     */
-    public function get_children() {
-        global $USER, $CFG;
-
-        $children = array();
-
-        if ($child = $this->browser->get_file_info(get_context_instance(CONTEXT_USER, $USER->id), 'user_private', 0)) {
-            $children[] = $child;
-        }
-
-        if ($child = $this->browser->get_file_info(get_context_instance(CONTEXT_USER, $USER->id), 'user_profile', 0)) {
-            $children[] = $child;
-        }
-
-        if ($child = $this->browser->get_file_info(get_context_instance(CONTEXT_USER, $USER->id), 'user_backup', 0)) {
-            $children[] = $child;
-        }
-        // do not list user_draft here - it is browsable only if you know the draft itemid ;-)
-
-        return $children;
-    }
-
-    /**
-     * Returns parent file_info instance
-     * @return file_info or null for root
-     */
-    public function get_parent() {
-        return $this->browser->get_file_info(get_context_instance(CONTEXT_SYSTEM));
-    }
-}
diff --git a/lib/filebrowser/file_browser.php b/lib/filebrowser/file_browser.php
new file mode 100644 (file)
index 0000000..0c482c7
--- /dev/null
@@ -0,0 +1,228 @@
+<?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/>.
+
+
+/**
+ * Utility class for browsing of files.
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once("$CFG->libdir/filebrowser/file_info.php");
+
+// general area types
+require_once("$CFG->libdir/filebrowser/file_info_stored.php");
+require_once("$CFG->libdir/filebrowser/virtual_root_file.php");
+
+// description of available areas in each context level
+require_once("$CFG->libdir/filebrowser/file_info_context_system.php");
+require_once("$CFG->libdir/filebrowser/file_info_context_user.php");
+require_once("$CFG->libdir/filebrowser/file_info_context_coursecat.php");
+require_once("$CFG->libdir/filebrowser/file_info_context_course.php");
+require_once("$CFG->libdir/filebrowser/file_info_context_module.php");
+
+/**
+ * This class provides the main entry point for other code wishing to get
+ * information about files.
+ *
+ * The whole file storage for a Moodle site can be seen as a huge virtual tree.
+ * The spine of the tree is the tree of contexts (system, course-categories,
+ * courses, modules, also users). Then, within each context, there may be any number of
+ * file areas, and a file area contains folders and files. The various file_info
+ * subclasses return info about the things in this tree. They should be obtained
+ * from an instance of this class.
+ *
+ * This virtual tree is different for each user depending of his/her current permissions.
+ * Some branches such as draft areas are hidden, but accessible.
+ *
+ * Always use this abstraction when you need to access module files from core code.
+  *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+*/
+class file_browser {
+
+    /**
+     * Looks up file_info instance
+     * @param object $context
+     * @param string $component
+     * @param string $filearea
+     * @param int $itemid
+     * @param string $filepath
+     * @param string $filename
+     * @return file_info instance or null if not found or access not allowed
+     */
+    public function get_file_info($context = NULL, $component = NULL, $filearea = NULL, $itemid = NULL, $filepath = NULL, $filename = NULL) {
+        if (!$context) {
+            $context = get_context_instance(CONTEXT_SYSTEM);
+        }
+        switch ($context->contextlevel) {
+            case CONTEXT_SYSTEM:
+                return $this->get_file_info_context_system($context, $component, $filearea, $itemid, $filepath, $filename);
+            case CONTEXT_USER:
+                return $this->get_file_info_context_user($context, $component, $filearea, $itemid, $filepath, $filename);
+            case CONTEXT_COURSECAT:
+                return $this->get_file_info_context_coursecat($context, $component, $filearea, $itemid, $filepath, $filename);
+            case CONTEXT_COURSE:
+                return $this->get_file_info_context_course($context, $component, $filearea, $itemid, $filepath, $filename);
+            case CONTEXT_MODULE:
+                return $this->get_file_info_context_module($context, $component, $filearea, $itemid, $filepath, $filename);
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns info about the files at System context
+     * @param object $context
+     * @param string $component
+     * @param string $filearea
+     * @param int $itemid
+     * @param string $filepath
+     * @param string $filename
+     * @return file_info instance or null if not found or access not allowed
+     */
+    private function get_file_info_context_system($context, $component, $filearea, $itemid, $filepath, $filename) {
+        $level = new file_info_context_system($this, $context);
+        return $level->get_file_info($component, $filearea, $itemid, $filepath, $filename);
+        // nothing supported at this context yet
+    }
+
+    /**
+     * Returns info about the files at User context
+     * @param object $context
+     * @param string $component
+     * @param string $filearea
+     * @param int $itemid
+     * @param string $filepath
+     * @param string $filename
+     * @return file_info instance or null if not found or access not allowed
+     */
+    private function get_file_info_context_user($context, $component, $filearea, $itemid, $filepath, $filename) {
+        global $DB, $USER;
+        if ($context->instanceid == $USER->id) {
+            $user = $USER;
+        } else {
+            $user = $DB->get_record('user', array('id'=>$context->instanceid));
+        }
+
+        if (isguestuser($user)) {
+            // guests do not have any files
+            return null;
+        }
+
+        if ($user->deleted) {
+            return null;
+        }
+
+        $level = new file_info_context_user($this, $context, $user);
+        return $level->get_file_info($component, $filearea, $itemid, $filepath, $filename);
+    }
+
+    /**
+     * Returns info about the files at Course category context
+     * @param object $context
+     * @param string $component
+     * @param string $filearea
+     * @param int $itemid
+     * @param string $filepath
+     * @param string $filename
+     * @return file_info instance or null if not found or access not allowed
+     */
+    private function get_file_info_context_coursecat($context, $component, $filearea, $itemid, $filepath, $filename) {
+        global $DB, $CFG;
+
+        if (!$category = $DB->get_record('course_categories', array('id'=>$context->instanceid))) {
+            return null;
+        }
+
+        $level = new file_info_context_coursecat($this, $context, $category);
+        return $level->get_file_info($component, $filearea, $itemid, $filepath, $filename);
+    }
+
+    /**
+     * Returns info about the files at Course category context
+     * @param object $context
+     * @param string $component
+     * @param string $filearea
+     * @param int $itemid
+     * @param string $filepath
+     * @param string $filename
+     * @return file_info instance or null if not found or access not allowed
+     */
+    private function get_file_info_context_course($context, $component, $filearea, $itemid, $filepath, $filename) {
+        global $DB, $COURSE;
+
+        if ($context->instanceid == $COURSE->id) {
+            $course = $COURSE;
+        } else if (!$course = $DB->get_record('course', array('id'=>$context->instanceid))) {
+            return null;
+        }
+
+        $level = new file_info_context_course($this, $context, $course);
+        return $level->get_file_info($component, $filearea, $itemid, $filepath, $filename);
+    }
+
+    /**
+     * Returns info about the files at Course category context
+     * @param object $context
+     * @param string $component
+     * @param string $filearea
+     * @param int $itemid
+     * @param string $filepath
+     * @param string $filename
+     * @return file_info instance or null if not found or access not allowed
+     */
+    private function get_file_info_context_module($context, $component, $filearea, $itemid, $filepath, $filename) {
+        global $COURSE, $DB, $CFG;
+
+
+        if (!$cm = get_coursemodule_from_id('', $context->instanceid)) {
+            return null;
+        }
+
+        if ($cm->course == $COURSE->id) {
+            $course = $COURSE;
+        } else if (!$course = $DB->get_record('course', array('id'=>$cm->course))) {
+            return null;
+        }
+
+        $modinfo = get_fast_modinfo($course);
+        if (empty($modinfo->cms[$cm->id]->uservisible)) {
+            return null;
+        }
+
+        $modname = $modinfo->cms[$cm->id]->modname;
+
+        if (!file_exists("$CFG->dirroot/mod/$modname/lib.php")) {
+            return null;
+        }
+
+        // ok, we know that module exists, and user may access it
+
+        $level = new file_info_context_module($this, $context, $course, $cm, $modname);
+        return $level->get_file_info($component, $filearea, $itemid, $filepath, $filename);
+    }
+
+}
similarity index 87%
rename from lib/file/file_info.php
rename to lib/filebrowser/file_info.php
index 40c54db..0c294f6 100644 (file)
 /**
  * Base for all file browsing classes.
  *
- * @package    moodlecore
- * @subpackage file-browser
+ * @package    core
+ * @subpackage filebrowser
  * @copyright  2008 Petr Skoda (http://skodak.org)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * Base class for things in the tree navigated by @see{file_browser}.
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 abstract class file_info {
 
@@ -43,9 +50,16 @@ abstract class file_info {
      * Returns list of standard virtual file/directory identification.
      * The difference from stored_file parameters is that null values
      * are allowed in all fields
-     * @return array with keys contextid, filearea, itemid, filepath and filename
+     * @return array with keys contextid, component, filearea, itemid, filepath and filename
      */
-    public abstract function get_params();
+    public function get_params() {
+        return array('contextid' => $this->context->id,
+                     'component' => null,
+                     'filearea'  => null,
+                     'itemid'    => null,
+                     'filepath'  => null,
+                     'filename'  => null);
+    }
 
     /**
      * Returns localised visible name.
@@ -79,6 +93,7 @@ abstract class file_info {
         $params = $this->get_params();
         $encoded = array();
         $encoded[] = 'contextid='.$params['contextid'];
+        $encoded[] = 'component='.$params['component'];
         $encoded[] = 'filearea='.$params['filearea'];
         $encoded[] = 'itemid='.(is_null($params['itemid']) ? -1 : $params['itemid']);
         $encoded[] = 'filepath='.(is_null($params['filepath']) ? '' : rawurlencode($params['filepath']));
@@ -184,7 +199,7 @@ abstract class file_info {
      * @param int id of author, default $USER->id
      * @return file_info new directory
      */
-    public function create_directory($newdirname, $userid=null) {
+    public function create_directory($newdirname, $userid = NULL) {
         return null;
     }
 
@@ -196,7 +211,7 @@ abstract class file_info {
      * @param int id of author, default $USER->id
      * @return file_info new file
      */
-    public function create_file_from_string($newfilename, $content, $userid=null) {
+    public function create_file_from_string($newfilename, $content, $userid = NULL) {
         return null;
     }
 
@@ -208,7 +223,7 @@ abstract class file_info {
      * @param int id of author, default $USER->id
      * @return file_info new file
      */
-    public function create_file_from_pathname($newfilename, $pathname, $userid=null) {
+    public function create_file_from_pathname($newfilename, $pathname, $userid = NULL) {
         return null;
     }
 
@@ -220,7 +235,7 @@ abstract class file_info {
      * @param int id of author, default $USER->id
      * @return file_info new file
      */
-    public function create_file_from_storedfile($newfilename, $fid, $userid=null) {
+    public function create_file_from_storedfile($newfilename, $fid, $userid = NULL) {
         return null;
     }
 
@@ -235,13 +250,14 @@ abstract class file_info {
     /**
      * Copy content of this file to local storage, overriding current file if needed.
      * @param int $contextid
+     * @param string $component
      * @param string $filearea
      * @param int $itemid
      * @param string $filepath
      * @param string $filename
      * @return boolean success
      */
-    public function copy_to_storage($contextid, $filearea, $itemid, $filepath, $filename) {
+    public function copy_to_storage($contextid, $component, $filearea, $itemid, $filepath, $filename) {
         return false;
     }
 
diff --git a/lib/filebrowser/file_info_context_course.php b/lib/filebrowser/file_info_context_course.php
new file mode 100644 (file)
index 0000000..b2e08d1
--- /dev/null
@@ -0,0 +1,540 @@
+<?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/>.
+
+
+/**
+ * Utility class for browsing of course files.
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Represents a course context in the tree navigated by @see{file_browser}.
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class file_info_context_course extends file_info {
+    protected $course;
+
+    public function __construct($browser, $context, $course) {
+        parent::__construct($browser, $context);
+        $this->course   = $course;
+    }
+
+    /**
+     * Return information about this specific context level
+     *
+     * @param $component
+     * @param $filearea
+     * @param $itemid
+     * @param $filepath
+     * @param $filename
+     */
+    public function get_file_info($component, $filearea, $itemid, $filepath, $filename) {
+        global $DB;
+
+        if (!$this->course->visible and !has_capability('moodle/course:viewhiddencourses', $this->context)) {
+            return null;
+        }
+
+        if (empty($component)) {
+            return $this;
+        }
+
+        $methodname = "get_area_{$component}_{$filearea}";
+
+        if (method_exists($this, $methodname)) {
+            return $this->$methodname($itemid, $filepath, $filename);
+        }
+
+        return null;
+    }
+
+    protected function get_area_course_summary($itemid, $filepath, $filename) {
+        global $CFG;
+
+        if (!has_capability('moodle/course:update', $this->context)) {
+            return null;
+        }
+        if (is_null($itemid)) {
+            return $this;
+        }
+
+        $fs = get_file_storage();
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+        if (!$storedfile = $fs->get_file($this->context->id, 'course', 'summary', 0, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($this->context->id, 'course', 'summary', 0);
+            } else {
+                // not found
+                return null;
+            }
+        }
+        $urlbase = $CFG->wwwroot.'/pluginfile.php';
+        return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('areacourseintro', 'repository'), false, true, true, false);
+    }
+
+
+    protected function get_area_course_section($itemid, $filepath, $filename) {
+        global $CFG, $DB;
+
+        if (!has_capability('moodle/course:update', $this->context)) {
+            return null;
+        }
+
+        if (empty($itemid)) {
+            // list all sections
+            return new file_info_area_course_section($this->browser, $this->context, $this->course, $this);
+        }
+
+        if (!$section = $DB->get_record('course_sections', array('course'=>$this->course->id, 'id'=>$itemid))) {
+            return null; // does not exist
+        }
+
+        $fs = get_file_storage();
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+        if (!$storedfile = $fs->get_file($this->context->id, 'course', 'section', $itemid, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($this->context->id, 'course', 'section', $itemid);
+            } else {
+                // not found
+                return null;
+            }
+        }
+        $urlbase = $CFG->wwwroot.'/pluginfile.php';
+        return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, $section->section, true, true, true, false);
+    }
+
+
+    protected function get_area_course_legacy($itemid, $filepath, $filename) {
+        if (!has_capability('moodle/course:managefiles', $this->context)) {
+            return null;
+        }
+
+        if ($this->course->id != SITEID and $this->course->legacyfiles != 2) {
+            // bad luck, legacy course files not used any more
+        }
+
+        if (empty($itemid)) {
+            return $this;
+        }
+
+        $fs = get_file_storage();
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+        if (!$storedfile = $fs->get_file($this->context->id, 'course', 'legacy', 0, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($this->context->id, $filearea, 0);
+            } else {
+                // not found
+                return null;
+            }
+        }
+
+        return new file_info_area_course_legacy($this->browser, $this->context, $storedfile);
+    }
+
+    protected function get_area_backup_course($itemid, $filepath, $filename) {
+        global $CFG;
+
+        if (!has_capability('moodle/backup:backupcourse', $this->context) and !has_capability('moodle/restore:restorecourse', $this->context)) {
+            return null;
+        }
+        if (is_null($itemid)) {
+            return $this;
+        }
+
+        $fs = get_file_storage();
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+        if (!$storedfile = $fs->get_file($this->context->id, 'backup', 'course', 0, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($this->context->id, 'backup', 'course', 0);
+            } else {
+                // not found
+                return null;
+            }
+        }
+
+        $downloadable = has_capability('moodle/backup:downloadfile', $this->context);
+        $uploadable   = has_capability('moodle/restore:uploadfile', $this->context);
+
+        $urlbase = $CFG->wwwroot.'/pluginfile.php';
+        return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('coursebackup', 'repository'), false, $downloadable, $uploadable, false);
+    }
+
+    protected function get_area_backup_section($itemid, $filepath, $filename) {
+        global $CFG, $DB;
+
+        if (!has_capability('moodle/backup:backupcourse', $this->context) and !has_capability('moodle/restore:restorecourse', $this->context)) {
+            return null;
+        }
+
+        if (empty($itemid)) {
+            // list all sections
+            return new file_info_area_backup_section($this->browser, $this->context, $this->course, $this);
+        }
+
+        if (!$section = $DB->get_record('course_sections', array('course'=>$this->course->id, 'id'=>$itemid))) {
+            return null; // does not exist
+        }
+
+        $fs = get_file_storage();
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+        if (!$storedfile = $fs->get_file($this->context->id, 'backup', 'section', $itemid, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($this->context->id, 'backup', 'section', $itemid);
+            } else {
+                // not found
+                return null;
+            }
+        }
+
+        $downloadable = has_capability('moodle/backup:downloadfile', $this->context);
+        $uploadable   = has_capability('moodle/restore:uploadfile', $this->context);
+
+        $urlbase = $CFG->wwwroot.'/pluginfile.php';
+        return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, $section->id, true, $downloadable, $uploadable, false);
+    }
+
+    public function get_visible_name() {
+        return ($this->course->id == SITEID) ? get_string('frontpage', 'admin') : format_string($this->course->fullname);
+    }
+
+    /**
+     * Can I add new files or directories?
+     * @return bool
+     */
+    public function is_writable() {
+        return false;
+    }
+
+    /**
+     * Is directory?
+     * @return bool
+     */
+    public function is_directory() {
+        return true;
+    }
+
+    /**
+     * Returns list of children.
+     * @return array of file_info instances
+     */
+    public function get_children() {
+        $children = array();
+
+        if ($child = $this->get_area_course_summary(0, '/', '.')) {
+            $children[] = $child;
+        }
+        if ($child = $this->get_area_course_section(null, null, null)) {
+            $children[] = $child;
+        }
+        if ($child = $this->get_area_backup_section(null, null, null)) {
+            $children[] = $child;
+        }
+        if ($child = $this->get_area_backup_course(0, '/', '.')) {
+            $children[] = $child;
+        }
+        if ($child = $this->get_area_course_legacy(0, '/', '.')) {
+            $children[] = $child;
+        }
+
+        // now list all modules
+        $modinfo = get_fast_modinfo($this->course);
+        foreach ($modinfo->cms as $cminfo) {
+            if (empty($cminfo->uservisible)) {
+                continue;
+            }
+            $modcontext = get_context_instance(CONTEXT_MODULE, $cminfo->id);
+            if ($child = $this->browser->get_file_info($modcontext)) {
+                $children[] = $child;
+            }
+        }
+
+        return $children;
+    }
+
+    /**
+     * Returns parent file_info instance
+     * @return file_info or null for root
+     */
+    public function get_parent() {
+        //TODO: error checking if get_parent_contextid() returns false
+        $pcid = get_parent_contextid($this->context);
+        $parent = get_context_instance_by_id($pcid);
+        return $this->browser->get_file_info($parent);
+    }
+}
+
+
+/**
+ * Subclass of file_info_stored for files in the course files area.
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class file_info_area_course_legacy extends file_info_stored {
+    public function __construct($browser, $context, $storedfile) {
+        global $CFG;
+        $urlbase = $CFG->wwwroot.'/file.php';
+        parent::__construct($browser, $context, $storedfile, $urlbase, get_string('coursefiles'), false, true, true, false);
+    }
+
+    /**
+     * Returns file download url
+     * @param bool $forcedownload
+     * @param bool $htts force https
+     * @return string url
+     */
+    public function get_url($forcedownload=false, $https=false) {
+        global $CFG;
+
+        if (!$this->is_readable()) {
+            return null;
+        }
+
+        if ($this->lf->is_directory()) {
+            return null;
+        }
+
+        $filepath = $this->lf->get_filepath();
+        $filename = $this->lf->get_filename();
+        $courseid = $this->context->instanceid;
+
+        $path = '/'.$courseid.$filepath.$filename;
+
+        return file_encode_url($this->urlbase, $path, $forcedownload, $https);
+    }
+
+    /**
+     * Returns list of children.
+     * @return array of file_info instances
+     */
+    public function get_children() {
+        if (!$this->lf->is_directory()) {
+            return array();
+        }
+
+        $result = array();
+        $fs = get_file_storage();
+
+        $storedfiles = $fs->get_directory_files($this->context->id, 'course', 'legacy', 0, $this->lf->get_filepath(), false, true, "filepath ASC, filename ASC");
+        foreach ($storedfiles as $file) {
+            $result[] = new file_info_area_course_legacy($this->browser, $this->context, $file);
+        }
+
+        return $result;
+    }
+}
+
+/**
+ * Represents a course category context in the tree navigated by @see{file_browser}.
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class file_info_area_course_section extends file_info {
+    protected $course;
+    protected $courseinfo;
+
+    public function __construct($browser, $context, $course, file_info_context_course $courseinfo) {
+        parent::__construct($browser, $context);
+        $this->course     = $course;
+        $this->courseinfo = $courseinfo;
+    }
+
+    /**
+     * Returns list of standard virtual file/directory identification.
+     * The difference from stored_file parameters is that null values
+     * are allowed in all fields
+     * @return array with keys contextid, filearea, itemid, filepath and filename
+     */
+    public function get_params() {
+        return array('contextid' => $this->context->id,
+                     'component' => 'course',
+                     'filearea'  => 'section',
+                     'itemid'    => null,
+                     'filepath'  => null,
+                     'filename'  => null);
+    }
+
+    /**
+     * Returns localised visible name.
+     * @return string
+     */
+    public function get_visible_name() {
+        $format = $this->course->format;
+        $sectionsname = get_string("coursesectionsummaries");
+
+        return $sectionsname;
+    }
+
+    /**
+     * Can I add new files or directories?
+     * @return bool
+     */
+    public function is_writable() {
+        return false;
+    }
+
+    /**
+     * Is directory?
+     * @return bool
+     */
+    public function is_directory() {
+        return true;
+    }
+
+    /**
+     * Returns list of children.
+     * @return array of file_info instances
+     */
+    public function get_children() {
+        global $DB;
+
+        $children = array();
+
+        $course_sections = $DB->get_records('course_sections', array('course'=>$this->course->id), 'section');
+        foreach ($course_sections as $section) {
+            if ($child = $this->courseinfo->get_file_info('course', 'section', $section->id, '/', '.')) {
+                $children[] = $child;
+            }
+        }
+
+        return $children;
+    }
+
+    /**
+     * Returns parent file_info instance
+     * @return file_info or null for root
+     */
+    public function get_parent() {
+        return $this->courseinfo;
+    }
+}
+
+
+/**
+ * Implementation of course section backup area
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class file_info_area_backup_section extends file_info {
+    protected $course;
+    protected $courseinfo;
+
+    public function __construct($browser, $context, $course, file_info_context_course $courseinfo) {
+        parent::__construct($browser, $context);
+        $this->course     = $course;
+        $this->courseinfo = $courseinfo;
+    }
+
+    /**
+     * Returns list of standard virtual file/directory identification.
+     * The difference from stored_file parameters is that null values
+     * are allowed in all fields
+     * @return array with keys contextid, component, filearea, itemid, filepath and filename
+     */
+    public function get_params() {
+        return array('contextid' => $this->context->id,
+                     'component' => 'backup',
+                     'filearea'  => 'section',
+                     'itemid'    => null,
+                     'filepath'  => null,
+                     'filename'  => null);
+    }
+
+    /**
+     * Returns localised visible name.
+     * @return string
+     */
+    public function get_visible_name() {
+        $format = $this->course->format;
+        $sectionsname = get_string('sectionbackup', 'repository');
+
+        return $sectionsname;
+    }
+
+    /**
+     * Can I add new files or directories?
+     * @return bool
+     */
+    public function is_writable() {
+        return false;
+    }
+
+    /**
+     * Is directory?
+     * @return bool
+     */
+    public function is_directory() {
+        return true;
+    }
+
+    /**
+     * Returns list of children.
+     * @return array of file_info instances
+     */
+    public function get_children() {
+        global $DB;
+
+        $children = array();
+
+        $course_sections = $DB->get_records('course_sections', array('course'=>$this->course->id), 'section');
+        foreach ($course_sections as $section) {
+            if ($child = $this->courseinfo->get_file_info('backup', 'section', $section->id, '/', '.')) {
+                $children[] = $child;
+            }
+        }
+
+        return $children;
+    }
+
+    /**
+     * Returns parent file_info instance
+     * @return file_info or null for root
+     */
+    public function get_parent() {
+        return $this->browser->get_file_info($this->context);
+    }
+}
+
+
similarity index 51%
rename from lib/file/file_info_coursecat.php
rename to lib/filebrowser/file_info_context_coursecat.php
index 97f7180..24ef22c 100644 (file)
 /**
  * Utility class for browsing of curse category files.
  *
- * @package    moodlecore
- * @subpackage file-browser
+ * @package    core
+ * @subpackage filebrowser
  * @copyright  2008 Petr Skoda (http://skodak.org)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * Represents a course category context in the tree navigated by @see{file_browser}.
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-class file_info_coursecat extends file_info {
+class file_info_context_coursecat extends file_info {
     protected $category;
 
     public function __construct($browser, $context, $category) {
@@ -37,17 +44,68 @@ class file_info_coursecat extends file_info {
     }
 
     /**
-     * Returns list of standard virtual file/directory identification.
-     * The difference from stored_file parameters is that null values
-     * are allowed in all fields
-     * @return array with keys contextid, filearea, itemid, filepath and filename
+     * Return information about this specific context level
+     *
+     * @param $component
+     * @param $filearea
+     * @param $itemid
+     * @param $filepath
+     * @param $filename
      */
-    public function get_params() {
-        return array('contextid'=>$this->context->id,
-                     'filearea' =>null,
-                     'itemid'   =>null,
-                     'filepath' =>null,
-                     'filename' =>null);
+    public function get_file_info($component, $filearea, $itemid, $filepath, $filename) {
+        global $DB;
+
+        if (!$this->category->visible and !has_capability('moodle/category:viewhiddencategories', $this->context)) {
+            if (empty($component)) {
+                // we can not list the category contents, so try parent, or top system
+                if ($this->category->parent and $pc = $DB->get_record('course_categories', array('id'=>$this->category->parent))) {
+                    $parent = get_context_instance(CONTEXT_COURSECAT, $pc->id);
+                    return $this->browser->get_file_info($parent);
+                } else {
+                    return $this->browser->get_file_info();
+                }
+            }
+            return null;
+        }
+
+        if (empty($component)) {
+            return $this;
+        }
+
+        $methodname = "get_area_{$component}_{$filearea}";
+        if (method_exists($this, $methodname)) {
+            return $this->$methodname($itemid, $filepath, $filename);
+        }
+
+        return null;
+    }
+
+    protected function get_area_coursecat_description($itemid, $filepath, $filename) {
+        global $CFG;
+
+        if (!has_capability('moodle/course:update', $this->context)) {
+            return null;
+        }
+
+        if (is_null($itemid)) {
+            return $this;
+        }
+
+        $fs = get_file_storage();
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+        $urlbase = $CFG->wwwroot.'/pluginfile.php';
+        if (!$storedfile = $fs->get_file($this->context->id, 'coursecat', 'description', 0, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($this->context->id, 'coursecat', 'description', 0);
+            } else {
+                // not found
+                return null;
+            }
+        }
+
+        return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('areacategoryintro', 'repository'), false, true, true, false);
     }
 
     /**
@@ -83,14 +141,14 @@ class file_info_coursecat extends file_info {
 
         $children = array();
 
-        if ($child = $this->browser->get_file_info($this->context, 'coursecat_intro', 0)) {
+        if ($child = $this->get_area_coursecat_description(0, '/', '.')) {
             $children[] = $child;
         }
 
-        $course_cats = $DB->get_records('course_categories', array('parent'=>$this->category->id), 'sortorder');
+        $course_cats = $DB->get_records('course_categories', array('parent'=>$this->category->id), 'sortorder', 'id,visible');
         foreach ($course_cats as $category) {
             $context = get_context_instance(CONTEXT_COURSECAT, $category->id);
-            if (!$category->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
+            if (!$category->visible and !has_capability('moodle/category:viewhiddencategories', $context)) {
                 continue;
             }
             if ($child = $this->browser->get_file_info($context)) {
@@ -98,7 +156,7 @@ class file_info_coursecat extends file_info {
             }
         }
 
-        $courses = $DB->get_records('course', array('category'=>$this->category->id), 'sortorder');
+        $courses = $DB->get_records('course', array('category'=>$this->category->id), 'sortorder', 'id,visible');
         foreach ($courses as $course) {
             $context = get_context_instance(CONTEXT_COURSE, $course->id);
             if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
diff --git a/lib/filebrowser/file_info_context_module.php b/lib/filebrowser/file_info_context_module.php
new file mode 100644 (file)
index 0000000..dc9cbb2
--- /dev/null
@@ -0,0 +1,221 @@
+<?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/>.
+
+
+/**
+ * Utility class for browsing of module files.
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Represents a module context in the tree navigated by @see{file_browser}.
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class file_info_context_module extends file_info {
+    protected $course;
+    protected $cm;
+    protected $modname;
+    protected $areas;
+
+    public function __construct($browser, $context, $course, $cm, $modname) {
+        global $DB, $CFG;
+
+        parent::__construct($browser, $context);
+        $this->course  = $course;
+        $this->cm      = $cm;
+        $this->modname = $modname;
+
+        include_once("$CFG->dirroot/mod/$modname/lib.php");
+
+        //find out all supported areas
+        $functionname     = 'mod_'.$modname.'_get_file_areas';
+        $functionname_old = $modname.'_get_file_areas';
+
+        if (function_exists($functionname)) {
+            $this->areas = $functionname($course, $cm, $context);
+        } else if (function_exists($functionname_old)) {
+            $this->areas = $functionname_old($course, $cm, $context);
+        } else {
+            $this->areas = array();
+        }
+        unset($this->areas['intro']); // hardcoded, ignore attempts to override it
+    }
+
+    /**
+     * Return information about this specific context level
+     *
+     * @param $component
+     * @param $filearea
+     * @param $itemid
+     * @param $filepath
+     * @param $filename
+     */
+    public function get_file_info($component, $filearea, $itemid, $filepath, $filename) {
+        global $USER;
+
+        if (!is_enrolled($this->context) and !is_viewing($this->context)) {
+            // no peaking here if not enrolled or inspector
+            return null;
+        }
+
+        if (empty($component)) {
+            return $this;
+        }
+
+        if ($component == 'mod_'.$this->modname and $filearea === 'intro') {
+            return $this->get_area_intro($itemid, $filepath, $filename);
+        } else if ($component == 'backup' and $filearea === 'activity') {
+            return $this->get_area_backup($itemid, $filepath, $filename);
+        }
+
+        $functionname     = 'mod_'.$this->modname.'_get_file_info';
+        $functionname_old = $this->modname.'_get_file_info';
+
+        if (function_exists($functionname)) {
+            return $functionname($this->browser, $this->areas, $this->course, $this->cm, $this->context, $filearea, $itemid, $filepath, $filename);
+        } else if (function_exists($functionname_old)) {
+            return $functionname_old($this->browser, $this->areas, $this->course, $this->cm, $this->context, $filearea, $itemid, $filepath, $filename);
+        }
+
+        return null;
+    }
+
+    protected function get_area_intro($itemid, $filepath, $filename) {
+        global $CFG;
+
+        if (!plugin_supports('mod', $this->modname, FEATURE_MOD_INTRO, true) or !has_capability('moodle/course:managefiles', $this->context)) {
+            return null;
+        }
+
+        if (!isset($itemid)) {
+            return $this;
+        }
+
+        $fs = get_file_storage();
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+        if (!$storedfile = $fs->get_file($this->context->id, 'mod_'.$this->modname, 'intro', 0, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($this->context->id, 'mod_'.$this->modname, 'intro', 0);
+            } else {
+                // not found
+                return null;
+            }
+        }
+
+        $urlbase = $CFG->wwwroot.'/pluginfile.php';
+        return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('moduleintro'), false, true, true, false);
+    }
+
+    protected function get_area_backup($itemid, $filepath, $filename) {
+        global $CFG;
+
+        if (!has_capability('moodle/backup:backupactivity', $this->context)) {
+            return null;
+        }
+
+        if (empty($itemid)) {
+            return $this;
+        }
+
+        $fs = get_file_storage();
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+        if (!$storedfile = $fs->get_file($this->context->id, 'backup', 'activity', 0, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($this->context->id, 'backup', 'activity', 0);
+            } else {
+                // not found
+                return null;
+            }
+        }
+
+        $downloadable = has_capability('moodle/backup:downloadfile', $this->context);
+        $uploadable   = has_capability('moodle/restore:uploadfile', $this->context);
+
+        $urlbase = $CFG->wwwroot.'/pluginfile.php';
+        return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('activitybackup', 'repository'), false, $downloadable, $uploadable, false);
+    }
+
+    /**
+     * Returns localised visible name.
+     * @return string
+     */
+    public function get_visible_name() {
+        return $this->cm->name.' ('.get_string('modulename', $this->cm->modname).')';
+    }
+
+    /**
+     * Can I add new files or directories?
+     * @return bool
+     */
+    public function is_writable() {
+        return false;
+    }
+
+    /**
+     * Is directory?
+     * @return bool
+     */
+    public function is_directory() {
+        return true;
+    }
+
+    /**
+     * Returns list of children.
+     * @return array of file_info instances
+     */
+    public function get_children() {
+        $children = array();
+
+        if ($child = $this->get_area_backup(0, '/', '.')) {
+            $children[] = $child;
+        }
+        if ($child = $this->get_area_intro(0, '/', '.')) {
+            $children[] = $child;
+        }
+
+        foreach ($this->areas as $area=>$desctiption) {
+            if ($child = $this->get_file_info('mod_'.$this->modname, $area, null, null, null)) {
+                $children[] = $child;
+            }
+        }
+        return $children;
+    }
+
+    /**
+     * Returns parent file_info instance
+     * @return file_info or null for root
+     */
+    public function get_parent() {
+        $pcid = get_parent_contextid($this->context);
+        $parent = get_context_instance_by_id($pcid);
+        return $this->browser->get_file_info($parent);
+    }
+}
similarity index 74%
rename from lib/file/file_info_system.php
rename to lib/filebrowser/file_info_context_system.php
index 23d0016..a3908ef 100644 (file)
 /**
  * Utility class for browsing of system files.
  *
- * @package    moodlecore
- * @subpackage file-browser
+ * @package    core
+ * @subpackage filebrowser
  * @copyright  2008 Petr Skoda (http://skodak.org)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * Represents the system context in the tree navigated by @see{file_browser}.
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-class file_info_system extends file_info {
-    public function __construct($browser) {
-        parent::__construct($browser, get_context_instance(CONTEXT_SYSTEM));
+class file_info_context_system extends file_info {
+    public function __construct($browser, $context) {
+        parent::__construct($browser, $context);
     }
 
     /**
-     * Returns list of standard virtual file/directory identification.
-     * The difference from stored_file parameters is that null values
-     * are allowed in all fields
-     * @return array with keys contextid, filearea, itemid, filepath and filename
+     * Return information about this specific part of context level
+     * @param $component
+     * @param $filearea
+     * @param $itemid
+     * @param $filepath
+     * @param $filename
      */
-    public function get_params() {
-        return array('contextid'=>$this->context->id,
-                     'filearea' =>null,
-                     'itemid'   =>null,
-                     'filepath' =>null,
-                     'filename' =>null);
+    public function get_file_info($component, $filearea, $itemid, $filepath, $filename) {
+        if (empty($component)) {
+            return $this;
+        }
+
+        // no components supported at this level yet
+        return null;
     }
 
     /**
@@ -84,10 +94,10 @@ class file_info_system extends file_info {
             $children[] = $child;
         }
 
-        $course_cats = $DB->get_records('course_categories', array('parent'=>0), 'sortorder');
+        $course_cats = $DB->get_records('course_categories', array('parent'=>0), 'sortorder', 'id,visible');
         foreach ($course_cats as $category) {
             $context = get_context_instance(CONTEXT_COURSECAT, $category->id);
-            if (!$category->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
+            if (!$category->visible and !has_capability('moodle/category:viewhiddencategories', $context)) {
                 continue;
             }
             if ($child = $this->browser->get_file_info($context)) {
@@ -95,7 +105,7 @@ class file_info_system extends file_info {
             }
         }
 
-        $courses = $DB->get_records('course', array('category'=>0), 'sortorder');
+        $courses = $DB->get_records('course', array('category'=>0), 'sortorder', 'id,visible');
         foreach ($courses as $course) {
             if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
                 continue;
diff --git a/lib/filebrowser/file_info_context_user.php b/lib/filebrowser/file_info_context_user.php
new file mode 100644 (file)
index 0000000..c9f3a3e
--- /dev/null
@@ -0,0 +1,259 @@
+<?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/>.
+
+
+/**
+ * Utility class for browsing of user files.
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Represents a user context in the tree navigated by @see{file_browser}.
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class file_info_context_user extends file_info {
+    protected $user;
+
+    public function __construct($browser, $context, $user) {
+        parent::__construct($browser, $context);
+        $this->user = $user;
+    }
+
+    /**
+     * Return information about this specific context level
+     *
+     * @param $component
+     * @param $filearea
+     * @param $itemid
+     * @param $filepath
+     * @param $filename
+     */
+    public function get_file_info($component, $filearea, $itemid, $filepath, $filename) {
+        global $USER;
+
+        if (!isloggedin() or isguestuser()) {
+            return null;
+        }
+
+        if (empty($component)) {
+            // access control: list areas only for myself
+            if ($this->user->id != $USER->id) {
+                // no list of areas for other users
+                return null;
+            }
+            return $this;
+        }
+
+        $methodname = "get_area_{$component}_{$filearea}";
+        if (method_exists($this, $methodname)) {
+            return $this->$methodname($itemid, $filepath, $filename);
+        }
+
+        return null;
+    }
+
+    protected function get_area_user_private($itemid, $filepath, $filename) {
+        global $USER, $CFG;
+
+        // access control: only my files, nobody else
+        if ($this->user->id != $USER->id) {
+            return null;
+        }
+
+        if (is_null($itemid)) {
+            // go to parent, we do not use itemids here in private area
+            return $this;;
+        }
+
+        $fs = get_file_storage();
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+
+        if (!$storedfile = $fs->get_file($this->context->id, 'user', 'private', 0, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                // root dir does not exist yet
+                $storedfile = new virtual_root_file($this->context->id, 'user', 'private', 0);
+            } else {
+                // not found
+                return null;
+            }
+        }
+        $urlbase = $CFG->wwwroot.'/pluginfile.php';
+
+        //TODO: user quota from $CFG->userquota
+
+        return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('areauserpersonal', 'repository'), false, true, true, false);
+    }
+
+    protected function get_area_user_profile($itemid, $filepath, $filename) {
+        global $USER, $CFG;
+
+        if (!has_capability('moodle/user:update', $this->context)) {
+            // the idea here is that only admins should be able to list/modify files in user profile, the rest has to use profile page
+            return null;
+        }
+
+        if (is_null($itemid)) {
+            // go to parent, we do not use itemids here in profile area
+            return $this;
+        }
+
+        $fs = get_file_storage();
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+
+        if (!$storedfile = $fs->get_file($this->context->id, 'user', 'profile', 0, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($this->context->id, 'user', 'profile', 0);
+            } else {
+                // not found
+                return null;
+            }
+        }
+        $urlbase = $CFG->wwwroot.'/pluginfile.php';
+        return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('areauserprofile', 'repository'), false, true, true, false);
+    }
+
+    protected function get_area_user_draft($itemid, $filepath, $filename) {
+        global $USER, $CFG;
+
+        // access control: only my files
+        if ($this->user->id != $USER->id) {
+            return null;
+        }
+
+        if (empty($itemid)) {
+            // do not browse itemids - you must know the draftid to see what is there
+            return null;
+        }
+
+        $fs = get_file_storage();
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+
+        if (!$storedfile = $fs->get_file($this->context->id, 'user', 'draft', $itemid, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($this->context->id, 'user', 'draft', $itemid);
+            } else {
+                // not found
+                return null;
+            }
+        }
+        $urlbase = $CFG->wwwroot.'/pluginfile.php';
+        return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('areauserdraft', 'repository'), true, true, true, true);
+    }
+
+    protected function get_area_user_backup($itemid, $filepath, $filename) {
+        global $USER, $CFG;
+
+        // access control: only my files, nobody else - TODO: maybe we need new capability here
+        if ($this->context->instanceid != $USER->id) {
+            return null;
+        }
+
+        if (is_null($itemid)) {
+            // go to parent, we do not use itemids here in profile area
+            return $this;
+        }
+
+        $fs = get_file_storage();
+
+        $filepath = is_null($filepath) ? '/' : $filepath;
+        $filename = is_null($filename) ? '.' : $filename;
+
+        if (!$storedfile = $fs->get_file($this->context->id, 'user', 'backup', $itemid, $filepath, $filename)) {
+            if ($filepath === '/' and $filename === '.') {
+                $storedfile = new virtual_root_file($this->context->id, 'user', 'backup', 0);
+            } else {
+                // not found
+                return null;
+            }
+        }
+        $urlbase = $CFG->wwwroot.'/pluginfile.php';
+        return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('areauserbackup', 'repository'), false, true, true, false);
+    }
+
+    /**
+     * Returns localised visible name.
+     * @return string
+     */
+    public function get_visible_name() {
+        return fullname($this->user, true);
+    }
+
+    /**
+     * Can I add new files or directories?
+     * @return bool
+     */
+    public function is_writable() {
+        return false;
+    }
+
+    /**
+     * Is directory?
+     * @return bool
+     */
+    public function is_directory() {
+        return true;
+    }
+
+    /**
+     * Returns list of children.
+     * @return array of file_info instances
+     */
+    public function get_children() {
+        global $USER, $CFG;
+
+        $children = array();
+
+        if ($child = $this->get_area_user_private(0, '/', '.')) {
+            $children[] = $child;
+        }
+/*
+        if ($child = $this->get_area_user_profile(0, '/', '.')) {
+            $children[] = $child;
+        }
+*/
+        if ($child = $this->get_area_user_backup(0, '/', '.')) {
+            $children[] = $child;
+        }
+        // do not list draft area here - it is browsable only if you know the draft itemid ;-)
+
+        return $children;
+    }
+
+    /**
+     * Returns parent file_info instance
+     * @return file_info or null for root
+     */
+    public function get_parent() {
+        return $this->browser->get_file_info();
+    }
+}
similarity index 80%
rename from lib/file/file_info_stored.php
rename to lib/filebrowser/file_info_stored.php
index 830164e..5cf165e 100644 (file)
 /**
  * Utility class for browsing of stored files.
  *
- * @package    moodlecore
- * @subpackage file-browser
+ * @package    core
+ * @subpackage filebrowser
  * @copyright  2008 Petr Skoda (http://skodak.org)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * Represents an actual file or folder - a row in the file table -
  * in the tree navigated by @see{file_browser}.
+ *
+ * @package    core
+ * @subpackage filebrowser
+ * @copyright  2008 Petr Skoda (http://skodak.org)
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class file_info_stored extends file_info {
     protected $lf;
@@ -38,7 +45,20 @@ class file_info_stored extends file_info {
     protected $writeaccess;
     protected $areaonly;
 
-    public function __construct($browser, $context, $storedfile, $urlbase, $topvisiblename, $itemidused, $readaccess, $writeaccess, $areaonly) {
+    /**
+     * Constructor
+     *
+     * @param file_browser $browser
+     * @param object $context
+     * @param stored_file $storedfile
+     * @param string $urlbase the serving script - usually the $CFG->wwwroot/.'pluginfile.php'
+     * @param string $topvisiblename the human readable name of this area
+     * @param string $itemidused false if itemid  always 0 and not included in URL
+     * @param string $readaccess allow file reading
+     * @param string $writeaccess allow file write, delete
+     * @param string $areaonly do not show links to parent context/area
+     */
+    public function __construct(file_browser $browser, $context, $storedfile, $urlbase, $topvisiblename, $itemidused, $readaccess, $writeaccess, $areaonly) {
         parent::__construct($browser, $context);
 
         $this->lf             = $storedfile;
@@ -54,10 +74,11 @@ class file_info_stored extends file_info {
      * Returns list of standard virtual file/directory identification.
      * The difference from stored_file parameters is that null values
      * are allowed in all fields
-     * @return array with keys contextid, filearea, itemid, filepath and filename
+     * @return array with keys contextid, component, filearea, itemid, filepath and filename
      */
     public function get_params() {
         return array('contextid'=>$this->context->id,
+                     'component' =>$this->lf->get_component(),
                      'filearea' =>$this->lf->get_filearea(),
                      'itemid'   =>$this->lf->get_itemid(),
                      'filepath' =>$this->lf->get_filepath(),
@@ -94,8 +115,6 @@ class file_info_stored extends file_info {
      * @return string url
      */
     public function get_url($forcedownload=false, $https=false) {
-        global $CFG;
-
         if (!$this->is_readable()) {
             return null;
         }
@@ -106,15 +125,16 @@ class file_info_stored extends file_info {
 
         $this->urlbase;
         $contextid = $this->lf->get_contextid();
+        $component = $this->lf->get_component();
         $filearea  = $this->lf->get_filearea();
         $filepath  = $this->lf->get_filepath();
         $filename  = $this->lf->get_filename();
         $itemid    = $this->lf->get_itemid();
 
         if ($this->itemidused) {
-            $path = '/'.$contextid.'/'.$filearea.'/'.$itemid.$filepath.$filename;
+            $path = '/'.$contextid.'/'.$component.'/'.$filearea.'/'.$itemid.$filepath.$filename;
         } else {
-            $path = '/'.$contextid.'/'.$filearea.$filepath.$filename;
+            $path = '/'.$contextid.'/'.$component.'/'.$filearea.$filepath.$filename;
         }
         return file_encode_url($this->urlbase, $path, $forcedownload, $https);
     }
@@ -219,7 +239,7 @@ class file_info_stored extends file_info {
         $result = array();
         $fs = get_file_storage();
 
-        $storedfiles = $fs->get_directory_files($this->context->id, $this->lf->get_filearea(), $this->lf->get_itemid(),
+        $storedfiles = $fs->get_directory_files($this->context->id, $this->lf->get_component(), $this->lf->get_filearea(), $this->lf->get_itemid(),
                                                 $this->lf->get_filepath(), false, true, "filepath, filename");
         foreach ($storedfiles as $file) {
             $result[] = new file_info_stored($this->browser, $this->context, $file, $this->urlbase, $this->topvisiblename,
@@ -238,14 +258,14 @@ class file_info_stored extends file_info {
             if ($this->areaonly) {
                 return null;
             } else if ($this->itemidused) {
-                return $this->browser->get_file_info($this->context, $this->lf->get_filearea());
+                return $this->browser->get_file_info($this->context, $this->lf->get_component(), $this->lf->get_filearea());
             } else {
                 return $this->browser->get_file_info($this->context);
             }
         }
 
         if (!$this->lf->is_directory()) {
-            return $this->browser->get_file_info($this->context, $this->lf->get_filearea(), $this->lf->get_itemid(), $this->lf->get_filepath(), '.');
+            return $this->browser->get_file_info($this->context, $this->lf->get_component(), $this->lf->get_filearea(), $this->lf->get_itemid(), $this->lf->get_filepath(), '.');
         }
 
         $filepath = $this->lf->get_filepath();
@@ -255,7 +275,7 @@ class file_info_stored extends file_info {
         $filepath = implode('/', $dirs);
         $filepath = ($filepath === '') ? '/' : "/$filepath/";
 
-        return $this->browser->get_file_info($this->context, $this->lf->get_filearea(), $this->lf->get_itemid(), $filepath, '.');
+        return $this->browser->get_file_info($this->context, $this->lf->get_component(), $this->lf->get_filearea(), $this->lf->get_itemid(), $filepath, '.');
     }
 
     /**
@@ -265,7 +285,7 @@ class file_info_stored extends file_info {
      * @param int id of author, default $USER->id
      * @return file_info new directory
      */
-    public function create_directory($newdirname, $userid=null) {
+    public function create_directory($newdirname, $userid = NULL) {
         if (!$this->is_writable() or !$this->lf->is_directory()) {
             return null;
         }
@@ -279,8 +299,8 @@ class file_info_stored extends file_info {
 
         $fs = get_file_storage();
 
-        if ($file = $fs->create_directory($this->lf->get_contextid(), $this->lf->get_filearea(), $this->lf->get_itemid(), $filepath, $userid)) {
-            return $this->browser->get_file_info($this->context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
+        if ($file = $fs->create_directory($this->lf->get_contextid(), $this->lf->get_component(), $this->lf->get_filearea(), $this->lf->get_itemid(), $filepath, $userid)) {
+            return $this->browser->get_file_info($this->context, $this->lf->get_component(), $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
         }
         return null;
     }
@@ -294,7 +314,7 @@ class file_info_stored extends file_info {
      * @param int id of author, default $USER->id
      * @return file_info new file
      */
-    public function create_file_from_string($newfilename, $content, $userid=null) {
+    public function create_file_from_string($newfilename, $content, $userid = NULL) {
         if (!$this->is_writable() or !$this->lf->is_directory()) {
             return null;
         }
@@ -310,12 +330,13 @@ class file_info_stored extends file_info {
 
         $newrecord = new object();
         $newrecord->contextid = $this->lf->get_contextid();
+        $newrecord->component = $this->lf->get_component();
         $newrecord->filearea  = $this->lf->get_filearea();
         $newrecord->itemid    = $this->lf->get_itemid();
         $newrecord->filepath  = $this->lf->get_filepath();
         $newrecord->filename  = $newfilename;
 
-        if ($fs->file_exists($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename)) {
+        if ($fs->file_exists($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename)) {
             // file already exists, sorry
             return null;
         }
@@ -326,7 +347,7 @@ class file_info_stored extends file_info {
         $newrecord->userid       = $userid;
 
         if ($file = $fs->create_file_from_string($newrecord, $content)) {
-            return $this->browser->get_file_info($this->context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
+            return $this->browser->get_file_info($this->context, $file->get_component(), $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
         }
         return null;
     }
@@ -339,7 +360,7 @@ class file_info_stored extends file_info {
      * @param int id of author, default $USER->id
      * @return file_info new file
      */
-    public function create_file_from_pathname($newfilename, $pathname, $userid=null) {
+    public function create_file_from_pathname($newfilename, $pathname, $userid = NULL) {
         if (!$this->is_writable() or !$this->lf->is_directory()) {
             return null;
         }
@@ -355,12 +376,13 @@ class file_info_stored extends file_info {
 
         $newrecord = new object();
         $newrecord->contextid = $this->lf->get_contextid();
+        $newrecord->component = $this->lf->get_component();
         $newrecord->filearea  = $this->lf->get_filearea();
         $newrecord->itemid    = $this->lf->get_itemid();
         $newrecord->filepath  = $this->lf->get_filepath();
         $newrecord->filename  = $newfilename;
 
-        if ($fs->file_exists($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename)) {
+        if ($fs->file_exists($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename)) {
             // file already exists, sorry
             return null;
         }
@@ -371,7