From 64f93798d4ece7dbb34c343e5b2e9a9bdfa06314 Mon Sep 17 00:00:00 2001 From: Petr Skoda Date: Sat, 3 Jul 2010 13:37:13 +0000 Subject: [PATCH] MDL-22950 adding new component column to the files table, unfortunately this change requires changes in all 2.0dev code, please review all custom code that was already upgraded to 2.0; fixing multiple problems and regressions in mod/assignment --- admin/bloglevelupgrade.php | 10 +- admin/settings/grades.php | 3 +- backup/backup_execute.html | 2 +- backup/backuplib.php | 2 +- backup/moodle2/backup_stepslib.php | 19 +- .../dbops/backup_structure_dbops.class.php | 5 +- backup/util/helper/backup_helper.class.php | 51 +- .../structure/backup_nested_element.class.php | 35 +- .../backup_structure_processor.class.php | 16 +- .../simpletest/testbackupstructures.php | 34 +- backup/util/ui/backup_ui_stage.class.php | 11 +- blocks/community/locallib.php | 5 +- .../course_summary/block_course_summary.php | 2 +- blocks/html/block_html.php | 41 +- blocks/html/edit_form.php | 4 +- blocks/html/lib.php | 49 ++ blocks/private_files/block_private_files.php | 15 +- blocks/private_files/edit.php | 58 ++ blocks/private_files/edit_form.php | 43 ++ blog/edit.php | 6 +- blog/locallib.php | 15 +- calendar/lib.php | 19 +- course/category.php | 2 +- course/edit.php | 4 +- course/editcategory.php | 4 +- course/editsection.php | 4 +- course/format/topics/format.php | 4 +- course/format/weeks/format.php | 4 +- course/info.php | 2 +- course/lib.php | 103 +-- course/modedit.php | 8 +- course/publish/metadata.php | 6 +- course/scales.php | 4 +- draftfile.php | 25 +- file.php | 8 +- files/draftfiles.php | 206 ------ files/externallib.php | 90 ++- files/filebrowser_ajax.php | 90 +++ files/files_ajax.php | 264 ------- files/index.php | 64 +- files/module.js | 2 +- files/renderer.php | 156 ++++ grade/edit/outcome/edit.php | 8 +- grade/edit/scale/edit.php | 8 +- grade/edit/tree/grade_form.php | 2 +- group/group.php | 4 +- group/grouping.php | 4 +- group/lib.php | 26 +- group/overview.php | 4 +- index.php | 14 +- lang/en/error.php | 2 +- lang/en/portfolio.php | 2 +- lib/db/install.xml | 13 +- lib/db/upgrade.php | 61 +- lib/db/upgradelib.php | 20 +- lib/file/file_browser.php | 575 --------------- lib/file/file_info_course.php | 125 ---- lib/file/file_info_coursefile.php | 83 --- lib/file/file_info_coursesection.php | 106 --- lib/file/file_info_coursesectionbackup.php | 106 --- lib/file/file_info_module.php | 105 --- lib/file/file_info_user.php | 119 --- lib/filebrowser/file_browser.php | 228 ++++++ lib/{file => filebrowser}/file_info.php | 34 +- lib/filebrowser/file_info_context_course.php | 540 ++++++++++++++ .../file_info_context_coursecat.php} | 92 ++- lib/filebrowser/file_info_context_module.php | 221 ++++++ .../file_info_context_system.php} | 46 +- lib/filebrowser/file_info_context_user.php | 259 +++++++ .../file_info_stored.php | 79 +- .../virtual_root_file.php | 39 +- lib/filelib.php | 156 ++-- lib/{packer => filestorage}/file_archive.php | 14 +- lib/{file => filestorage}/file_exceptions.php | 35 +- lib/{packer => filestorage}/file_packer.php | 17 +- lib/{file => filestorage}/file_storage.php | 118 +-- lib/{file => filestorage}/file_types.mm | 0 lib/{file => filestorage}/stored_file.php | 33 +- lib/{packer => filestorage}/zip_archive.php | 16 +- lib/{packer => filestorage}/zip_packer.php | 36 +- lib/form/filemanager.js | 5 +- lib/form/filemanager.php | 183 ++++- lib/form/filepicker.php | 2 +- lib/form/htmleditor.php | 3 +- lib/formslib.php | 47 +- lib/grade/grade_outcome.php | 4 +- lib/grade/grade_scale.php | 4 +- lib/moodlelib.php | 3 +- lib/navigationlib.php | 10 +- lib/outputcomponents.php | 203 +----- lib/outputrenderers.php | 211 ------ lib/portfolio/caller.php | 3 +- lib/portfolio/exporter.php | 9 +- lib/portfoliolib.php | 11 +- lib/resourcelib.php | 7 +- lib/setuplib.php | 2 +- lib/simpletest/broken_testfilelib.php | 40 +- lib/weblib.php | 4 +- .../moodle2/backup_assignment_stepslib.php | 4 +- mod/assignment/db/upgrade.php | 12 +- mod/assignment/lib.php | 58 +- mod/assignment/locallib.php | 2 +- .../type/online/assignment.class.php | 24 +- mod/assignment/type/online/file.php | 2 +- .../type/upload/assignment.class.php | 186 ++--- .../type/uploadsingle/assignment.class.php | 104 +-- .../backup/moodle2/backup_chat_stepslib.php | 2 +- .../backup/moodle2/backup_choice_stepslib.php | 2 +- mod/data/db/upgrade.php | 8 +- mod/data/field/file/field.class.php | 20 +- mod/data/field/picture/field.class.php | 33 +- mod/data/lib.php | 20 +- .../moodle2/backup_feedback_stepslib.php | 4 +- mod/feedback/item/label/lib.php | 68 +- mod/feedback/lib.php | 46 +- .../backup/moodle2/backup_folder_stepslib.php | 3 +- mod/folder/db/upgradelib.php | 4 +- mod/folder/edit.php | 39 +- mod/folder/edit_form.php | 21 +- mod/folder/lib.php | 47 +- mod/folder/locallib.php | 64 +- mod/folder/mod_form.php | 2 +- mod/folder/renderer.php | 67 ++ mod/folder/view.php | 27 +- .../backup/moodle2/backup_forum_stepslib.php | 5 +- mod/forum/db/upgrade.php | 6 +- mod/forum/lib.php | 47 +- mod/forum/locallib.php | 10 +- mod/forum/post.php | 12 +- .../moodle2/backup_glossary_stepslib.php | 5 +- mod/glossary/db/upgrade.php | 6 +- mod/glossary/deleteentry.php | 6 +- mod/glossary/edit.php | 8 +- mod/glossary/exportentry.php | 4 +- mod/glossary/lib.php | 51 +- mod/glossary/locallib.php | 12 +- .../backup/moodle2/backup_imscp_stepslib.php | 4 +- mod/imscp/db/upgradelib.php | 5 +- mod/imscp/lib.php | 60 +- mod/imscp/locallib.php | 12 +- mod/imscp/mod_form.php | 4 +- .../backup/moodle2/backup_label_stepslib.php | 2 +- .../backup/moodle2/backup_lesson_stepslib.php | 4 +- mod/lesson/db/upgrade.php | 6 +- mod/lesson/importppt.php | 10 +- mod/lesson/lib.php | 46 +- mod/lesson/locallib.php | 7 +- mod/lesson/mod_form.php | 2 +- mod/lesson/pagetypes/endofbranch.php | 2 +- mod/lesson/pagetypes/endofcluster.php | 2 +- mod/lesson/pagetypes/essay.php | 2 +- mod/lesson/pagetypes/matching.php | 2 +- .../backup/moodle2/backup_page_stepslib.php | 3 +- mod/page/db/upgradelib.php | 6 +- mod/page/lib.php | 43 +- mod/page/mod_form.php | 2 +- mod/page/view.php | 2 +- .../moodle2/backup_resource_stepslib.php | 3 +- mod/resource/db/upgrade.php | 5 +- mod/resource/db/upgradelib.php | 8 +- mod/resource/lib.php | 45 +- mod/resource/locallib.php | 16 +- mod/resource/mod_form.php | 6 +- mod/resource/view.php | 4 +- .../backup/moodle2/backup_scorm_stepslib.php | 3 +- mod/scorm/datamodels/aicclib.php | 2 +- mod/scorm/db/install.xml | 2 +- mod/scorm/db/upgrade.php | 12 +- mod/scorm/lib.php | 74 +- mod/scorm/loadSCO.php | 2 +- mod/scorm/locallib.php | 43 +- .../backup/moodle2/backup_survey_stepslib.php | 2 +- .../backup/moodle2/backup_url_stepslib.php | 6 +- mod/url/db/upgradelib.php | 1 - mod/url/locallib.php | 1 - .../backup/moodle2/backup_wiki_stepslib.php | 3 +- mod/wiki/db/upgrade.php | 7 +- mod/wiki/edit_form.php | 1 + mod/wiki/editors/wikifiletable.php | 7 +- mod/wiki/lib.php | 17 +- mod/wiki/locallib.php | 19 +- mod/wiki/pagelib.php | 20 +- mod/wiki/renderer.php | 2 +- mod/workshop/db/upgrade.php | 5 +- mod/workshop/exsubmission.php | 8 +- mod/workshop/fileinfolib.php | 3 +- mod/workshop/form/accumulative/lib.php | 43 +- mod/workshop/form/comments/lib.php | 43 +- mod/workshop/form/numerrors/lib.php | 43 +- mod/workshop/form/rubric/lib.php | 43 +- mod/workshop/lib.php | 117 +-- mod/workshop/mod_form.php | 4 +- mod/workshop/renderer.php | 8 +- mod/workshop/submission.php | 8 +- mod/workshop/view.php | 4 +- pluginfile.php | 685 +++++++++++------- repository/draftfiles_ajax.php | 235 ++++++ repository/dropbox/repository.class.php | 3 +- repository/filepicker.js | 1 - repository/filepicker.php | 40 +- repository/flickr/repository.class.php | 2 +- repository/googledocs/repository.class.php | 2 +- repository/lib.php | 82 +-- repository/local/repository.class.php | 13 +- repository/picasa/repository.class.php | 2 +- repository/recent/repository.class.php | 27 +- repository/repository_ajax.php | 42 +- repository/repository_callback.php | 101 +++ repository/upload/repository.class.php | 23 +- repository/user/repository.class.php | 17 +- tag/edit.php | 4 +- tag/lib.php | 2 +- tag/locallib.php | 2 +- user/edit.php | 4 +- user/editadvanced.php | 6 +- user/index.php | 2 +- user/profile.php | 2 +- user/view.php | 7 +- userfile.php | 123 ---- version.php | 2 +- 220 files changed, 4635 insertions(+), 4297 deletions(-) create mode 100644 blocks/html/lib.php create mode 100644 blocks/private_files/edit.php create mode 100644 blocks/private_files/edit_form.php delete mode 100644 files/draftfiles.php create mode 100755 files/filebrowser_ajax.php delete mode 100755 files/files_ajax.php create mode 100644 files/renderer.php delete mode 100644 lib/file/file_browser.php delete mode 100644 lib/file/file_info_course.php delete mode 100644 lib/file/file_info_coursefile.php delete mode 100644 lib/file/file_info_coursesection.php delete mode 100644 lib/file/file_info_coursesectionbackup.php delete mode 100644 lib/file/file_info_module.php delete mode 100644 lib/file/file_info_user.php create mode 100644 lib/filebrowser/file_browser.php rename lib/{file => filebrowser}/file_info.php (87%) create mode 100644 lib/filebrowser/file_info_context_course.php rename lib/{file/file_info_coursecat.php => filebrowser/file_info_context_coursecat.php} (51%) create mode 100644 lib/filebrowser/file_info_context_module.php rename lib/{file/file_info_system.php => filebrowser/file_info_context_system.php} (74%) create mode 100644 lib/filebrowser/file_info_context_user.php rename lib/{file => filebrowser}/file_info_stored.php (80%) rename lib/{file => filebrowser}/virtual_root_file.php (82%) rename lib/{packer => filestorage}/file_archive.php (94%) rename lib/{file => filestorage}/file_exceptions.php (61%) rename lib/{packer => filestorage}/file_packer.php (85%) rename lib/{file => filestorage}/file_storage.php (87%) rename lib/{file => filestorage}/file_types.mm (100%) rename lib/{file => filestorage}/stored_file.php (92%) rename lib/{packer => filestorage}/zip_archive.php (96%) rename lib/{packer => filestorage}/zip_packer.php (91%) create mode 100644 mod/folder/renderer.php create mode 100755 repository/draftfiles_ajax.php create mode 100755 repository/repository_callback.php delete mode 100644 userfile.php diff --git a/admin/bloglevelupgrade.php b/admin/bloglevelupgrade.php index b04d1dc46d199..07eec720bb80e 100644 --- a/admin/bloglevelupgrade.php +++ b/admin/bloglevelupgrade.php @@ -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()); diff --git a/admin/settings/grades.php b/admin/settings/grades.php index d2680ab62eb9f..65457c6efa430 100644 --- a/admin/settings/grades.php +++ b/admin/settings/grades.php @@ -26,8 +26,7 @@ // 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()); diff --git a/backup/backup_execute.html b/backup/backup_execute.html index ebc76b5b72204..5edf378e3191e 100644 --- a/backup/backup_execute.html +++ b/backup/backup_execute.html @@ -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)) { diff --git a/backup/backuplib.php b/backup/backuplib.php index 0a4c3f5c4b9d4..7ea52257323ff 100644 --- a/backup/backuplib.php +++ b/backup/backuplib.php @@ -2637,7 +2637,7 @@ function copy_zip_to_course_dir ($preferences) { //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); diff --git a/backup/moodle2/backup_stepslib.php b/backup/moodle2/backup_stepslib.php index e9631b39b2586..422a79fb443bd 100644 --- a/backup/moodle2/backup_stepslib.php +++ b/backup/moodle2/backup_stepslib.php @@ -232,7 +232,7 @@ protected function define_structure() { $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 @@ protected function define_structure() { $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 @@ protected function define_structure() { // 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 @@ protected function define_structure() { $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 @@ protected function define_execution() { 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 @@ protected function define_execution() { 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(); diff --git a/backup/util/dbops/backup_structure_dbops.class.php b/backup/util/dbops/backup_structure_dbops.class.php index 46213856a6dbd..ee2cdd17eca4b 100644 --- a/backup/util/dbops/backup_structure_dbops.class.php +++ b/backup/util/dbops/backup_structure_dbops.class.php @@ -103,13 +103,14 @@ public static function insert_backup_ids_record($backupid, $itemname, $itemid) { } } - 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 = ?'; diff --git a/backup/util/helper/backup_helper.class.php b/backup/util/helper/backup_helper.class.php index dca3778054208..92473562b798e 100644 --- a/backup/util/helper/backup_helper.class.php +++ b/backup/util/helper/backup_helper.class.php @@ -182,7 +182,7 @@ static public function store_backup_file($backupid, $filepath) { // 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 @@ static public function store_backup_file($backupid, $filepath) { } // 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 @@ static public function store_backup_file($backupid, $filepath) { // 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 @@ static public function store_backup_file($backupid, $filepath) { // 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(); } diff --git a/backup/util/structure/backup_nested_element.class.php b/backup/util/structure/backup_nested_element.class.php index 274b6e642f99e..b69b21d472816 100644 --- a/backup/util/structure/backup_nested_element.class.php +++ b/backup/util/structure/backup_nested_element.class.php @@ -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 @@ public function __construct($name, $attributes = null, $final_elements = null) { $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 @@ public function set_source_alias($dbname, $finalelementname) { } } - 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 @@ public function annotate_ids($itemname, $elementname) { * @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() { diff --git a/backup/util/structure/backup_structure_processor.class.php b/backup/util/structure/backup_structure_processor.class.php index 3504d91ab4031..6d3e2f6be4767 100644 --- a/backup/util/structure/backup_structure_processor.class.php +++ b/backup/util/structure/backup_structure_processor.class.php @@ -67,13 +67,15 @@ public function pre_process_nested_element(base_nested_element $nested) { 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); + } } } } diff --git a/backup/util/structure/simpletest/testbackupstructures.php b/backup/util/structure/simpletest/testbackupstructures.php index 5a1f63fee6c33..e9cb1020adfaf 100644 --- a/backup/util/structure/simpletest/testbackupstructures.php +++ b/backup/util/structure/simpletest/testbackupstructures.php @@ -82,14 +82,14 @@ private function fill_records() { // 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 @@ private function fill_records() { $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 @@ function test_backup_structure_construct() { $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 @@ function test_backup_structure_wrong() { } // 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); diff --git a/backup/util/ui/backup_ui_stage.class.php b/backup/util/ui/backup_ui_stage.class.php index 37fb70492a398..ed49c1aef86b5 100644 --- a/backup/util/ui/backup_ui_stage.class.php +++ b/backup/util/ui/backup_ui_stage.class.php @@ -140,7 +140,7 @@ abstract protected function initialise_stage_form(); /** * 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 @@ protected function initialise_stage_form() { * * 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 @@ public function process(backup_moodleform $form = null) { return $changes; } else { return false; - } + } } /** * Creates the backup_schema_form instance for this stage @@ -439,7 +439,7 @@ protected function initialise_stage_form() { 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 @@ public function __construct(backup_ui $ui, array $params=null, array $results=nu */ 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() diff --git a/blocks/community/locallib.php b/blocks/community/locallib.php index d6e75e2d2cb98..2f843d186f17a 100644 --- a/blocks/community/locallib.php +++ b/blocks/community/locallib.php @@ -98,11 +98,12 @@ public function block_community_download_course_backup($course) { $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 diff --git a/blocks/course_summary/block_course_summary.php b/blocks/course_summary/block_course_summary.php index 94d7431ca7736..e223ca2c84d10 100644 --- a/blocks/course_summary/block_course_summary.php +++ b/blocks/course_summary/block_course_summary.php @@ -27,7 +27,7 @@ function get_content() { $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) { diff --git a/blocks/html/block_html.php b/blocks/html/block_html.php index 5e43ced74a08c..91910a0cbb146 100755 --- a/blocks/html/block_html.php +++ b/blocks/html/block_html.php @@ -1,5 +1,28 @@ . + +/** + * 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 @@ function get_content() { $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 @@ function instance_config_save($data, $nolongerused = false) { 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 @@ function instance_config_save($data, $nolongerused = false) { 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 @@ function decode_content_links_caller($restore) { 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); - } } diff --git a/blocks/html/edit_form.php b/blocks/html/edit_form.php index ece488b93cc55..e8ef73af8a4f8 100644 --- a/blocks/html/edit_form.php +++ b/blocks/html/edit_form.php @@ -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 @@ function set_data($defaults) { } 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 index 0000000000000..009eeafa8514f --- /dev/null +++ b/blocks/html/lib.php @@ -0,0 +1,49 @@ +. + +/** + * 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); +} diff --git a/blocks/private_files/block_private_files.php b/blocks/private_files/block_private_files.php index bbd6b5860612d..7f69be0d8f05e 100755 --- a/blocks/private_files/block_private_files.php +++ b/blocks/private_files/block_private_files.php @@ -19,8 +19,7 @@ /** * Manage user private area files * - * @package moodlecore - * @subpackage repository + * @package block_private_files * @copyright 2010 Dongsheng Cai * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -47,12 +46,14 @@ function instance_allow_multiple() { 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 @@ function get_content() { $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 index 0000000000000..687f92750e288 --- /dev/null +++ b/blocks/private_files/edit.php @@ -0,0 +1,58 @@ +. + +/** + * 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 index 0000000000000..81accb5f7d3ab --- /dev/null +++ b/blocks/private_files/edit_form.php @@ -0,0 +1,43 @@ +. + +/** + * 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); + } +} diff --git a/blog/edit.php b/blog/edit.php index a4e0257697d35..ba5bdfccf90d0 100755 --- a/blog/edit.php +++ b/blog/edit.php @@ -94,7 +94,7 @@ $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 @@ $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'); diff --git a/blog/locallib.php b/blog/locallib.php index da01dc5eac9ef..0135b0c2c55c8 100644 --- a/blog/locallib.php +++ b/blog/locallib.php @@ -110,7 +110,7 @@ public function print_html($return=false) { $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 @@ public function edit($params=array(), $form=null, $summaryoptions=array(), $atta $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 @@ public function remove_associations() { */ 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 @@ public function print_attachments($return=false) { 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 @@ public function print_attachments($return=false) { } $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); diff --git a/calendar/lib.php b/calendar/lib.php index a5da6f899cef1..fc78b9111f793 100644 --- a/calendar/lib.php +++ b/calendar/lib.php @@ -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 @@ protected function get_description() { } // 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 @@ public function update($data) { $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 @@ public function update($data) { // 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 @@ public function update($data) { $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 @@ public function delete($deleterepeated=false) { // 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 @@ public function properties($prepareeditor=false) { // 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; } diff --git a/course/category.php b/course/category.php index 2b9128ab41dd2..35dd01b692ae1 100644 --- a/course/category.php +++ b/course/category.php @@ -199,7 +199,7 @@ 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(); } diff --git a/course/edit.php b/course/edit.php index 2b2d9e48942fe..45dd3c0332f2e 100644 --- a/course/edit.php +++ b/course/edit.php @@ -74,10 +74,10 @@ } } $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 diff --git a/course/editcategory.php b/course/editcategory.php index ae4037f9a0047..34d66a1c5c53f 100644 --- a/course/editcategory.php +++ b/course/editcategory.php @@ -42,7 +42,7 @@ } $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 @@ 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(); diff --git a/course/editsection.php b/course/editsection.php index aa1c08ea85a23..1b562881e0164 100644 --- a/course/editsection.php +++ b/course/editsection.php @@ -40,7 +40,7 @@ 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 @@ } 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); diff --git a/course/format/topics/format.php b/course/format/topics/format.php index 834fc35e6a029..8ba44c6051c0d 100644 --- a/course/format/topics/format.php +++ b/course/format/topics/format.php @@ -104,7 +104,7 @@ echo '
'; $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 @@ echo '
'; 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); diff --git a/course/format/weeks/format.php b/course/format/weeks/format.php index 08cc37b23422b..f68247ff8e601 100644 --- a/course/format/weeks/format.php +++ b/course/format/weeks/format.php @@ -95,7 +95,7 @@ echo '
'; $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); @@ -225,7 +225,7 @@ } echo '
'; $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); diff --git a/course/info.php b/course/info.php index 9c0d32a685f6f..e62ccb9108fd8 100644 --- a/course/info.php +++ b/course/info.php @@ -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)) { diff --git a/course/lib.php b/course/lib.php index 8aeacf6393aba..34019ad87c7aa 100644 --- a/course/lib.php +++ b/course/lib.php @@ -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 @@ public static function prepare($data=null) { 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 @@ public static function prepare($data=null) { 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 @@ public static function create($data) { 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 @@ public function __construct($properties) { * @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 @@ public function approve() { 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 @@ public function reject($notice) { 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); - } - } - } } /** diff --git a/course/modedit.php b/course/modedit.php index 38ecd4ae281f1..e1bf0144eed7d 100644 --- a/course/modedit.php +++ b/course/modedit.php @@ -79,7 +79,7 @@ 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 (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 @@ // 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 @@ $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)); } diff --git a/course/publish/metadata.php b/course/publish/metadata.php index 247a6faff21e3..dc2d1f322763b 100644 --- a/course/publish/metadata.php +++ b/course/publish/metadata.php @@ -159,7 +159,7 @@ 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 @@ 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 @@ } 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))); } } diff --git a/course/scales.php b/course/scales.php index 08216f8cb7210..8be8272f2da42 100644 --- a/course/scales.php +++ b/course/scales.php @@ -84,7 +84,7 @@ 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 @@ 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); diff --git a/draftfile.php b/draftfile.php index de82ca43ab943..baeceaf7af762 100644 --- a/draftfile.php +++ b/draftfile.php @@ -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 @@ } $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 @@ 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(); diff --git a/file.php b/file.php index 8c29f48fe4e46..661453e646b7f 100644 --- a/file.php +++ b/file.php @@ -62,7 +62,7 @@ } $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 @@ } 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 @@ $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 index 95693019a7ccf..0000000000000 --- a/files/draftfiles.php +++ /dev/null @@ -1,206 +0,0 @@ -. - -/** - * 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.'&filepath='.rawurlencode($newdirname).'&subdirs='.$subdirs.'&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.'&filepath='.rawurlencode($filepath).'&subdirs='.$subdirs.'&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.'&filepath='.rawurlencode($parent->get_filepath()).'&subdirs='.$subdirs.'&maxbytes='.$maxbytes); - } else { - redirect('draftfiles.php?itemid='.$itemid.'&filepath='.rawurlencode($filepath).'&subdirs='.$subdirs.'&maxbytes='.$maxbytes); - } - } -} - -echo $OUTPUT->header(); - -if ($notice !== '') { - echo $OUTPUT->notification($notice); -} - -echo '
'; - -$strfolder = get_string('folder'); -$strfile = get_string('file'); -$strdownload = get_string('download'); -$strdelete = get_string('delete'); - -if ($parent) { - echo '
'; - echo ' '.get_string('parentfolder').''; - echo '
'; -} - -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 ''; - } - - } else { - $viewurl = file_encode_url("$CFG->wwwroot/draftfile.php", "/$contextid/user_draft/$itemid".$filepath.$filename, false, false); - echo ''; - } -} - -echo '
'; - -if ($maxbytes == 0 or $maxbytes > $totalbytes) { - echo '
'; - if ($maxbytes) { - echo ''; - } - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - 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 '
'; -} else { - //TODO: notify upload limit reached here - echo get_string('maxsize', '', display_size(get_max_upload_file_size($CFG->maxbytes, $maxbytes))); -} - -if ($subdirs) { - echo '
'; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo '
'; -} - -echo $OUTPUT->footer(); - - diff --git a/files/externallib.php b/files/externallib.php index c352f40da5c71..e1a488e00f417 100755 --- a/files/externallib.php +++ b/files/externallib.php @@ -38,8 +38,9 @@ public static function get_files_parameters() { 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 @@ public static function get_files_parameters() { * @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 @@ public static function get_files($fileinfo) { 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 @@ public static function get_files($fileinfo) { $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 @@ public static function get_files($fileinfo) { $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 @@ public static function get_files_returns() { 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 @@ public static function upload_parameters() { 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 @@ public static function upload($fileinfo) { 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 @@ public static function upload($fileinfo) { } else { $filepath = ''; } - + if (isset($fileinfo['itemid'])) { $itemid = $fileinfo['itemid']; } else { @@ -238,16 +255,21 @@ public static function upload($fileinfo) { $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 index 0000000000000..342fb380b0abc --- /dev/null +++ b/files/filebrowser_ajax.php @@ -0,0 +1,90 @@ +. + +/** + * File manager support + * + * @package core + * @subpackage file + * @copyright 2010 Dongsheng Cai + * @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 index 88c4beb1e6180..0000000000000 --- a/files/files_ajax.php +++ /dev/null @@ -1,264 +0,0 @@ -. - -/** - * File manager - * - * @package moodlecore - * @subpackage file - * @copyright 2010 Dongsheng Cai - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -require('../config.php'); -require_once($CFG->libdir.'/filelib.php'); -require_once($CFG->libdir.'/adminlib.php'); - -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; -} diff --git a/files/index.php b/files/index.php index bc9acbfdabf09..11e47a1138a09 100644 --- a/files/index.php +++ b/files/index.php @@ -18,7 +18,7 @@ /** * Moodle file tree viewer based on YUI2 Treeview * - * @package moodlecore + * @package core * @subpackage file * @copyright 2010 Dongsheng Cai * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later @@ -26,35 +26,19 @@ 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 @@ $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 @@ $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(); diff --git a/files/module.js b/files/module.js index 49274e18d738c..266540541a871 100644 --- a/files/module.js +++ b/files/module.js @@ -2,7 +2,7 @@ // Author: Dongsheng Cai 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 index 0000000000000..141b3bc432ce1 --- /dev/null +++ b/files/renderer.php @@ -0,0 +1,156 @@ +. // +// // +/////////////////////////////////////////////////////////////////////////// + +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 = '
'; + foreach($tree->path as $path) { + $html .= $path; + $html .= ' / '; + } + $html .= '
'; + + $html .= '
'; + if (empty($tree->tree)) { + $html .= get_string('nofilesavailable', 'repository'); + } else { + $this->page->requires->js_init_call('M.core_filetree.init'); + $html .= '
    '; + foreach($tree->tree as $node) { + $link_attributes = array(); + if (!empty($node['isdir'])) { + $class = ' class="file-tree-folder"'; + } else { + $class = ' class="file-tree-file"'; + $link_attributes['target'] = '_blank'; + } + $html .= '
  • '; + $html .= html_writer::link($node['url'], $node['filename'], $link_attributes); + $html .= '
  • '; + } + $html .= '
'; + } + $html .= '
'; + return $html; + } +} + + +/** + * 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; + } + } +} diff --git a/grade/edit/outcome/edit.php b/grade/edit/outcome/edit.php index 6d355b0246a35..abdd6ddac2c2c 100644 --- a/grade/edit/outcome/edit.php +++ b/grade/edit/outcome/edit.php @@ -96,9 +96,9 @@ $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 @@ } $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; diff --git a/grade/edit/scale/edit.php b/grade/edit/scale/edit.php index 66c2e8696a4b3..12d410ede332f 100644 --- a/grade/edit/scale/edit.php +++ b/grade/edit/scale/edit.php @@ -90,9 +90,9 @@ $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 @@ } $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; diff --git a/grade/edit/tree/grade_form.php b/grade/edit/tree/grade_form.php index ed4be5f4c8b9c..1cb771098cfcf 100755 --- a/grade/edit/tree/grade_form.php +++ b/grade/edit/tree/grade_form.php @@ -98,7 +98,7 @@ function definition() { $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 diff --git a/group/group.php b/group/group.php index 1830fc345a078..80f504aed10e2 100644 --- a/group/group.php +++ b/group/group.php @@ -85,9 +85,9 @@ // 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 diff --git a/group/grouping.php b/group/grouping.php index 131428f97a130..66359b4c8794d 100644 --- a/group/grouping.php +++ b/group/grouping.php @@ -80,9 +80,9 @@ // 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 diff --git a/group/lib.php b/group/lib.php index 9f6c66720ea07..6e97723dce732 100644 --- a/group/lib.php +++ b/group/lib.php @@ -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 diff --git a/group/overview.php b/group/overview.php index 1b9649f617bf5..85149ea26686b 100644 --- a/group/overview.php +++ b/group/overview.php @@ -159,7 +159,7 @@ } $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 @@ 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'); diff --git a/index.php b/index.php index a6a004d5b5c29..46b22049fc019 100644 --- 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 @@ -104,7 +104,7 @@ $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 @@ -116,7 +116,7 @@ } $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; @@ -139,13 +139,13 @@ } } - 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 @@ -177,7 +177,7 @@ } 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'); @@ -189,7 +189,7 @@ 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: diff --git a/lang/en/error.php b/lang/en/error.php index a24832e19f8ee..29f308476ee15 100755 --- a/lang/en/error.php +++ b/lang/en/error.php @@ -430,7 +430,7 @@ $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'; diff --git a/lang/en/portfolio.php b/lang/en/portfolio.php index 5be68692a1244..d1211a4d02822 100644 --- a/lang/en/portfolio.php +++ b/lang/en/portfolio.php @@ -110,7 +110,7 @@ $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'; diff --git a/lib/db/install.xml b/lib/db/install.xml index de44b62ec6789..cd337a0bec364 100644 --- a/lib/db/install.xml +++ b/lib/db/install.xml @@ -1,5 +1,5 @@ - @@ -2262,13 +2262,14 @@ - +
- - + + + @@ -2289,8 +2290,8 @@ - - + +
diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index 2555d1747b2bb..ab21857b3e789 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -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 @@ function xmldb_main_upgrade($oldversion) { 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; diff --git a/lib/db/upgradelib.php b/lib/db/upgradelib.php index 923c1d73a2958..547b2f0154ac9 100644 --- a/lib/db/upgradelib.php +++ b/lib/db/upgradelib.php @@ -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 index 752bd60c73215..0000000000000 --- a/lib/file/file_browser.php +++ /dev/null @@ -1,575 +0,0 @@ -. - - -/** - * 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 index 3cdd866a2c00d..0000000000000 --- a/lib/file/file_info_course.php +++ /dev/null @@ -1,125 +0,0 @@ -. - - -/** - * 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 index 0d1073f97e69e..0000000000000 --- a/lib/file/file_info_coursefile.php +++ /dev/null @@ -1,83 +0,0 @@ -. - - -/** - * 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 index d42f1ce2820f9..0000000000000 --- a/lib/file/file_info_coursesection.php +++ /dev/null @@ -1,106 +0,0 @@ -. - - -/** - * 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 index ae7664ab133a1..0000000000000 --- a/lib/file/file_info_coursesectionbackup.php +++ /dev/null @@ -1,106 +0,0 @@ -. - - -/** - * Utility class for browsing of course section files. - * - * @package moodlecore - * @subpackage file-browser - * @copyright 2010 Dongsheng Cai - * @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 index d32129dd4f056..0000000000000 --- a/lib/file/file_info_module.php +++ /dev/null @@ -1,105 +0,0 @@ -. - - -/** - * 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 index 91fb9fee3a71c..0000000000000 --- a/lib/file/file_info_user.php +++ /dev/null @@ -1,119 +0,0 @@ -. - - -/** - * 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 index 0000000000000..0c482c7f59522 --- /dev/null +++ b/lib/filebrowser/file_browser.php @@ -0,0 +1,228 @@ +. + + +/** + * 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); + } + +} diff --git a/lib/file/file_info.php b/lib/filebrowser/file_info.php similarity index 87% rename from lib/file/file_info.php rename to lib/filebrowser/file_info.php index 40c54dbd60d91..0c294f67f02df 100644 --- a/lib/file/file_info.php +++ b/lib/filebrowser/file_info.php @@ -19,14 +19,21 @@ /** * 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 @@ public function __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 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 @@ public function get_params_rawencoded() { $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 @@ public function get_sortorder() { * @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 @@ public function create_directory($newdirname, $userid=null) { * @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 @@ public function create_file_from_string($newfilename, $content, $userid=null) { * @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 @@ public function create_file_from_pathname($newfilename, $pathname, $userid=null) * @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 @@ public function delete() { /** * 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 index 0000000000000..b2e08d14c10f3 --- /dev/null +++ b/lib/filebrowser/file_info_context_course.php @@ -0,0 +1,540 @@ +. + + +/** + * 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); + } +} + + diff --git a/lib/file/file_info_coursecat.php b/lib/filebrowser/file_info_context_coursecat.php similarity index 51% rename from lib/file/file_info_coursecat.php rename to lib/filebrowser/file_info_context_coursecat.php index 97f7180e7547c..24ef22c0097ba 100644 --- a/lib/file/file_info_coursecat.php +++ b/lib/filebrowser/file_info_context_coursecat.php @@ -19,16 +19,23 @@ /** * 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 @@ public function __construct($browser, $context, $category) { } /** - * 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 @@ public function get_children() { $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 @@ public function get_children() { } } - $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 index 0000000000000..dc9cbb2325b84 --- /dev/null +++ b/lib/filebrowser/file_info_context_module.php @@ -0,0 +1,221 @@ +. + + +/** + * 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); + } +} diff --git a/lib/file/file_info_system.php b/lib/filebrowser/file_info_context_system.php similarity index 74% rename from lib/file/file_info_system.php rename to lib/filebrowser/file_info_context_system.php index 23d0016789027..a3908ef755bef 100644 --- a/lib/file/file_info_system.php +++ b/lib/filebrowser/file_info_context_system.php @@ -19,32 +19,42 @@ /** * 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 @@ public function get_children() { $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 @@ public function get_children() { } } - $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 index 0000000000000..c9f3a3efa7f74 --- /dev/null +++ b/lib/filebrowser/file_info_context_user.php @@ -0,0 +1,259 @@ +. + + +/** + * 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(); + } +} diff --git a/lib/file/file_info_stored.php b/lib/filebrowser/file_info_stored.php similarity index 80% rename from lib/file/file_info_stored.php rename to lib/filebrowser/file_info_stored.php index 830164e4da61a..5cf165e6f8aa3 100644 --- a/lib/file/file_info_stored.php +++ b/lib/filebrowser/file_info_stored.php @@ -19,15 +19,22 @@ /** * 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 @@ public function __construct($browser, $context, $storedfile, $urlbase, $topvisib * 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 @@ public function get_visible_name() { * @return string url */ public function get_url($forcedownload=false, $https=false) { - global $CFG; - if (!$this->is_readable()) { return null; } @@ -106,15 +125,16 @@ public function get_url($forcedownload=false, $https=false) { $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 @@ public function get_children() { $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 @@ public function get_parent() { 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 @@ public function get_parent() { $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 @@ public function get_parent() { * @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 @@ public function create_directory($newdirname, $userid=null) { $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 @@ public function create_directory($newdirname, $userid=null) { * @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 @@ public function create_file_from_string($newfilename, $content, $userid=null) { $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 @@ public function create_file_from_string($newfilename, $content, $userid=null) { $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 @@ public function create_file_from_string($newfilename, $content, $userid=null) { * @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 @@ public function create_file_from_pathname($newfilename, $pathname, $userid=null) $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 +393,7 @@ public function create_file_from_pathname($newfilename, $pathname, $userid=null) $newrecord->userid = $userid; if ($file = $fs->create_file_from_pathname($newrecord, $pathname)) { - 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; } @@ -384,7 +406,7 @@ public function create_file_from_pathname($newfilename, $pathname, $userid=null) * @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) { if (!$this->is_writable() or $this->lf->get_filename() !== '.') { return null; } @@ -400,12 +422,13 @@ public function create_file_from_storedfile($newfilename, $fid, $userid=null) { $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; } @@ -416,7 +439,7 @@ public function create_file_from_storedfile($newfilename, $fid, $userid=null) { $newrecord->userid = $userid; if ($file = $fs->create_file_from_storedfile($newrecord, $fid)) { - 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; } @@ -433,7 +456,7 @@ public function delete() { if ($this->is_directory()) { $filepath = $this->lf->get_filepath(); $fs = get_file_storage(); - $storedfiles = $fs->get_area_files($this->context->id, $this->lf->get_filearea(), $this->lf->get_itemid(), ""); + $storedfiles = $fs->get_area_files($this->context->id, $file->get_component(), $this->lf->get_filearea(), $this->lf->get_itemid(), ""); foreach ($storedfiles as $file) { if (strpos($file->get_filepath(), $filepath) === 0) { $file->delete(); @@ -453,16 +476,16 @@ public function delete() { * @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) { if (!$this->is_readable() or $this->is_directory()) { return false; } $fs = get_file_storage(); - if ($existing = $fs->get_file($contextid, $filearea, $itemid, $filepath, $filename)) { + if ($existing = $fs->get_file($contextid, $component, $filearea, $itemid, $filepath, $filename)) { $existing->delete(); } - $file_record = array('contextid'=>$contextid, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>$filepath, 'filename'=>$filename); + $file_record = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>$filepath, 'filename'=>$filename); $fs->create_file_from_storedfile($file_record, $this->lf); return true; diff --git a/lib/file/virtual_root_file.php b/lib/filebrowser/virtual_root_file.php similarity index 82% rename from lib/file/virtual_root_file.php rename to lib/filebrowser/virtual_root_file.php index bf3828acb225d..6170d6727f633 100644 --- a/lib/file/virtual_root_file.php +++ b/lib/filebrowser/virtual_root_file.php @@ -19,26 +19,35 @@ /** * Class simulating empty directories. * - * @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 root directory of an empty file area 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 virtual_root_file { protected $contextid; + protected $component; protected $filearea; protected $itemid; /** * Constructor */ - public function __construct($contextid, $filearea, $itemid) { + public function __construct($contextid, $component, $filearea, $itemid) { $this->contextid = $contextid; + $this->component = $component; $this->filearea = $filearea; $this->itemid = $itemid; } @@ -125,13 +134,14 @@ public function extract_to_pathname(file_packer $packer, $pathname) { * Extract file to given file path (real OS filesystem), existing files are overwrited * @param object $file_packer * @param int $contextid + * @param string $component * @param string $filearea * @param int $itemid * @param string $pathbase * @param int $userid * @return mixed list of processed files; false if error */ - public function extract_to_storage(file_packer $packer, $contextid, $filearea, $itemid, $pathbase, $userid=null) { + public function extract_to_storage(file_packer $packer, $contextid, $component, $filearea, $itemid, $pathbase, $userid = NULL) { return false; } @@ -157,6 +167,10 @@ public function get_contextid() { return $this->contextid; } + public function get_component() { + return $this->component; + } + public function get_filearea() { return $this->filearea; } @@ -206,7 +220,22 @@ public function get_contenthash() { } public function get_pathnamehash() { - return sha1($this->get_contextid().$this->get_filearea().$this->get_itemid().$this->get_filepath().$this->get_filename()); + return sha1('/'.$this->get_contextid().'/'.$this->get_component().'/'.$this->get_filearea().'/'.$this->get_itemid().$this->get_filepath().$this->get_filename()); + } + + public function get_license() { + return null; } + public function get_author() { + return null; + } + + public function get_source() { + return null; + } + + public function get_sortorder() { + return null; + } } diff --git a/lib/filelib.php b/lib/filelib.php index 658ad25f29ad3..fb501a6d5d166 100644 --- a/lib/filelib.php +++ b/lib/filelib.php @@ -24,14 +24,15 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +defined('MOODLE_INTERNAL') || die(); + /** @var string unique string constant. */ define('BYTESERVING_BOUNDARY', 's1k2o3d4a5k6s7'); -require_once("$CFG->libdir/file/file_exceptions.php"); -require_once("$CFG->libdir/file/file_storage.php"); -require_once("$CFG->libdir/file/file_browser.php"); - -require_once("$CFG->libdir/packer/zip_packer.php"); +require_once("$CFG->libdir/filestorage/file_exceptions.php"); +require_once("$CFG->libdir/filestorage/file_storage.php"); +require_once("$CFG->libdir/filestorage/zip_packer.php"); +require_once("$CFG->libdir/filebrowser/file_browser.php"); /** * Given a physical path to a file, returns the URL through which it can be reached in Moodle. @@ -46,6 +47,8 @@ function get_file_url($path, $options=null, $type='coursefile') { global $CFG, $HTTPSPAGEREQUIRED; + //TODO: deprecate this + $path = str_replace('//', '/', $path); $path = trim($path, '/'); // no leading and trailing slashes @@ -104,6 +107,18 @@ function get_file_url($path, $options=null, $type='coursefile') { return $ffurl; } +/** + * Returns a draft file url. + * + * @param int $draftid itemid of the draft area of current user + * @param string $filepath must start and end with / + * @param string $filename + */ +function file_draftfile_url($draftid, $filepath, $filename) { + global $CFG, $USER; + $usercontext = get_context_instance(CONTEXT_USER, $USER->id); + return file_encode_url("$CFG->wwwroot/draftfile.php", '/'.$usercontext->id.'/user/draft/'.$draftid.$filepath.$filename, false); +} /** * Encodes file serving url @@ -156,11 +171,12 @@ function file_encode_url($urlbase, $path, $forcedownload=false, $https=false) { * @param string $field the name of the database field that holds the html text with embedded media * @param array $options editor options (like maxifiles, maxbytes etc.) * @param object $context context of the editor + * @param string $component * @param string $filearea file area name * @param int $itemid item id, required if item exists * @return object modified data object */ -function file_prepare_standard_editor($data, $field, array $options, $context=null, $filearea=null, $itemid=null) { +function file_prepare_standard_editor($data, $field, array $options, $context=null, $component=null, $filearea=null, $itemid=null) { $options = (array)$options; if (!isset($options['trusttext'])) { $options['trusttext'] = false; @@ -208,7 +224,7 @@ function file_prepare_standard_editor($data, $field, array $options, $context=nu if ($options['maxfiles'] != 0) { $draftid_editor = file_get_submitted_draft_itemid($field); - $currenttext = file_prepare_draft_area($draftid_editor, $contextid, $filearea, $itemid, $options, $data->{$field}); + $currenttext = file_prepare_draft_area($draftid_editor, $contextid, $component, $filearea, $itemid, $options, $data->{$field}); $data->{$field.'_editor'} = array('text'=>$currenttext, 'format'=>$data->{$field.'format'}, 'itemid'=>$draftid_editor); } else { $data->{$field.'_editor'} = array('text'=>$data->{$field}, 'format'=>$data->{$field.'format'}, 'itemid'=>0); @@ -232,11 +248,12 @@ function file_prepare_standard_editor($data, $field, array $options, $context=nu * @param string $field name of the database field containing the html with embedded media files * @param array $options editor options (trusttext, subdirs, maxfiles, maxbytes etc.) * @param object $context context, required for existing data + * @param string component * @param string $filearea file area name * @param int $itemid item id, required if item exists * @return object modified data object */ -function file_postupdate_standard_editor($data, $field, array $options, $context, $filearea=null, $itemid=null) { +function file_postupdate_standard_editor($data, $field, array $options, $context, $component=null, $filearea=null, $itemid=null) { $options = (array)$options; if (!isset($options['trusttext'])) { $options['trusttext'] = false; @@ -265,7 +282,7 @@ function file_postupdate_standard_editor($data, $field, array $options, $context if ($options['maxfiles'] == 0 or is_null($filearea) or is_null($itemid) or empty($editor['itemid'])) { $data->{$field} = $editor['text']; } else { - $data->{$field} = file_save_draft_area_files($editor['itemid'], $context->id, $filearea, $itemid, $options, $editor['text'], $options['forcehttps']); + $data->{$field} = file_save_draft_area_files($editor['itemid'], $context->id, $component, $filearea, $itemid, $options, $editor['text'], $options['forcehttps']); } $data->{$field.'format'} = $editor['format']; @@ -279,11 +296,12 @@ function file_postupdate_standard_editor($data, $field, array $options, $context * @param string $field name of data field * @param array $options various options * @param object $context context - must already exist + * @param string $component * @param string $filearea file area name * @param int $itemid must already exist, usually means data is in db * @return object modified data obejct */ -function file_prepare_standard_filemanager($data, $field, array $options, $context=null, $filearea=null, $itemid=null) { +function file_prepare_standard_filemanager($data, $field, array $options, $context=null, $component=null, $filearea=null, $itemid=null) { $options = (array)$options; if (!isset($options['subdirs'])) { $options['subdirs'] = false; @@ -296,7 +314,7 @@ function file_prepare_standard_filemanager($data, $field, array $options, $conte } $draftid_editor = file_get_submitted_draft_itemid($field.'_filemanager'); - file_prepare_draft_area($draftid_editor, $contextid, $filearea, $itemid, $options); + file_prepare_draft_area($draftid_editor, $contextid, $component, $filearea, $itemid, $options); $data->{$field.'_filemanager'} = $draftid_editor; return $data; @@ -309,11 +327,12 @@ function file_prepare_standard_filemanager($data, $field, array $options, $conte * @param string $field name of data field * @param array $options various options * @param object $context context - must already exist + * @param string $component * @param string $filearea file area name * @param int $itemid must already exist, usually means data is in db * @return object modified data obejct */ -function file_postupdate_standard_filemanager($data, $field, array $options, $context, $filearea, $itemid) { +function file_postupdate_standard_filemanager($data, $field, array $options, $context, $component, $filearea, $itemid) { $options = (array)$options; if (!isset($options['subdirs'])) { $options['subdirs'] = false; @@ -329,11 +348,11 @@ function file_postupdate_standard_filemanager($data, $field, array $options, $co $data->$field = ''; } else { - file_save_draft_area_files($data->{$field.'_filemanager'}, $context->id, $filearea, $itemid, $options); + file_save_draft_area_files($data->{$field.'_filemanager'}, $context->id, $component, $filearea, $itemid, $options); $fs = get_file_storage(); - if ($fs->get_area_files($context->id, $filearea, $itemid)) { - $data->$field = '1'; // TODO: this is an ugly hack + if ($fs->get_area_files($context->id, $component, $filearea, $itemid)) { + $data->$field = '1'; // TODO: this is an ugly hack (skodak) } else { $data->$field = ''; } @@ -358,11 +377,10 @@ function file_get_unused_draft_itemid() { } $contextid = get_context_instance(CONTEXT_USER, $USER->id)->id; - $filearea = 'user_draft'; $fs = get_file_storage(); $draftitemid = rand(1, 999999999); - while ($files = $fs->get_area_files($contextid, $filearea, $draftitemid)) { + while ($files = $fs->get_area_files($contextid, 'user', 'draft', $draftitemid)) { $draftitemid = rand(1, 999999999); } @@ -378,13 +396,14 @@ function file_get_unused_draft_itemid() { * @global object * @param int &$draftitemid the id of the draft area to use, or 0 to create a new one, in which case this parameter is updated. * @param integer $contextid This parameter and the next two identify the file area to copy files from. + * @param string $component * @param string $filearea helps indentify the file area. * @param integer $itemid helps identify the file area. Can be null if there are no files yet. * @param array $options text and file options ('subdirs'=>false, 'forcehttps'=>false) * @param string $text some html content that needs to have embedded links rewritten to point to the draft area. * @return string if $text was passed in, the rewritten $text is returned. Otherwise NULL. */ -function file_prepare_draft_area(&$draftitemid, $contextid, $filearea, $itemid, array $options=null, $text=null) { +function file_prepare_draft_area(&$draftitemid, $contextid, $component, $filearea, $itemid, array $options=null, $text=null) { global $CFG, $USER; $options = (array)$options; @@ -401,9 +420,14 @@ function file_prepare_draft_area(&$draftitemid, $contextid, $filearea, $itemid, if (empty($draftitemid)) { // create a new area and copy existing files into $draftitemid = file_get_unused_draft_itemid(); - $file_record = array('contextid'=>$usercontext->id, 'filearea'=>'user_draft', 'itemid'=>$draftitemid); - if (!is_null($itemid) and $files = $fs->get_area_files($contextid, $filearea, $itemid)) { + $file_record = array('contextid'=>$usercontext->id, 'component'=>'user', 'filearea'=>'draft', 'itemid'=>$draftitemid); + if (!is_null($itemid) and $files = $fs->get_area_files($contextid, $component, $filearea, $itemid)) { foreach ($files as $file) { + if ($file->is_directory() and $file->get_filepath() === '/') { + // we need a way to mark the age of each draft area, + // by not copying the root dir we force it to be created automatically with current timestamp + continue; + } if (!$options['subdirs'] and ($file->is_directory() or $file->get_filepath() !== '/')) { continue; } @@ -419,7 +443,7 @@ function file_prepare_draft_area(&$draftitemid, $contextid, $filearea, $itemid, } // relink embedded files - editor can not handle @@PLUGINFILE@@ ! - return file_rewrite_pluginfile_urls($text, 'draftfile.php', $usercontext->id, 'user_draft', $draftitemid, $options); + return file_rewrite_pluginfile_urls($text, 'draftfile.php', $usercontext->id, 'user', 'draft', $draftitemid, $options); } /** @@ -429,12 +453,13 @@ function file_prepare_draft_area(&$draftitemid, $contextid, $filearea, $itemid, * @param string $text The content that may contain ULRs in need of rewriting. * @param string $file The script that should be used to serve these files. pluginfile.php, draftfile.php, etc. * @param integer $contextid This parameter and the next two identify the file area to use. + * @param string $component * @param string $filearea helps identify the file area. * @param integer $itemid helps identify the file area. * @param array $options text and file options ('forcehttps'=>false) * @return string the processed text. */ -function file_rewrite_pluginfile_urls($text, $file, $contextid, $filearea, $itemid, array $options=null) { +function file_rewrite_pluginfile_urls($text, $file, $contextid, $component, $filearea, $itemid, array $options=null) { global $CFG; $options = (array)$options; @@ -446,7 +471,7 @@ function file_rewrite_pluginfile_urls($text, $file, $contextid, $filearea, $item $file = $file . '?file='; } - $baseurl = "$CFG->wwwroot/$file/$contextid/$filearea/"; + $baseurl = "$CFG->wwwroot/$file/$contextid/$component/$filearea/"; if ($itemid !== null) { $baseurl .= "$itemid/"; @@ -478,22 +503,7 @@ function file_get_draft_area_info($draftitemid) { $results = array(); // The number of files - $draftfiles = $fs->get_area_files($usercontext->id, 'user_draft', $draftitemid, 'id', false); - $results['filecount'] = count($draftfiles); - - return $results; -} - -function file_get_user_area_info($draftitemid, $filearea = 'user_draft') { - global $CFG, $USER; - - $usercontext = get_context_instance(CONTEXT_USER, $USER->id); - $fs = get_file_storage(); - - $results = array(); - - // The number of files - $draftfiles = $fs->get_area_files($usercontext->id, $filearea, $draftitemid, 'id', false); + $draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id', false); $results['filecount'] = count($draftfiles); return $results; @@ -507,14 +517,11 @@ function file_get_user_used_space() { global $DB, $CFG, $USER; $usercontext = get_context_instance(CONTEXT_USER, $USER->id); - $fs = get_file_storage(); - - // only count files in user context - $conditions = array('contextid'=>$usercontext->id); $totalbytes = 0; $files = array(); - $file_records = $DB->get_records('files', $conditions); + //TODO: rewrite to true sql SUM(), this is goign to run out of memory if limits are hight! + $file_records = $DB->get_records('files', "contextid = ? AND component = 'user' AND filearea != 'draft'", array($usercontext->id)); foreach ($file_records as $file_record) { if ($file_record->filename === '.') { continue; @@ -534,7 +541,7 @@ function file_get_user_used_space() { * @param string $str * @return string path */ -function file_correct_filepath($str) { +function file_correct_filepath($str) { //TODO: what is this? (skodak) if ($str == '/' or empty($str)) { return '/'; } else { @@ -546,14 +553,14 @@ function file_correct_filepath($str) { * Generate a folder tree of draft area of current USER recursively * @param int $itemid * @param string $filepath - * @param mixed $data + * @param mixed $data //TODO: use normal return value instead, this does not fit the rest of api here (skodak) */ -function file_get_user_area_folders($draftitemid, $filepath, &$data, $filearea = 'user_draft') { +function file_get_drafarea_folders($draftitemid, $filepath, &$data) { global $USER, $OUTPUT, $CFG; $data->children = array(); $context = get_context_instance(CONTEXT_USER, $USER->id); $fs = get_file_storage(); - if ($files = $fs->get_directory_files($context->id, $filearea, $draftitemid, $filepath, false)) { + if ($files = $fs->get_directory_files($context->id, 'user', 'draft', $draftitemid, $filepath, false)) { foreach ($files as $file) { if ($file->is_directory()) { $item = new stdclass; @@ -564,7 +571,7 @@ function file_get_user_area_folders($draftitemid, $filepath, &$data, $filearea = $item->fullname = trim(array_pop($foldername), '/'); $item->id = uniqid(); - file_get_user_area_folders($draftitemid, $item->filepath, $item); + file_get_drafarea_folders($draftitemid, $item->filepath, $item); $data->children[] = $item; } else { continue; @@ -580,7 +587,7 @@ function file_get_user_area_folders($draftitemid, $filepath, &$data, $filearea = * @param string $filepath * @return mixed */ -function file_get_user_area_files($draftitemid, $filepath = '/', $filearea = 'user_draft') { +function file_get_drafarea_files($draftitemid, $filepath = '/') { global $USER, $OUTPUT, $CFG; $context = get_context_instance(CONTEXT_USER, $USER->id); @@ -605,7 +612,7 @@ function file_get_user_area_files($draftitemid, $filepath = '/', $filearea = 'us $list = array(); $maxlength = 12; - if ($files = $fs->get_directory_files($context->id, $filearea, $draftitemid, $filepath, false)) { + if ($files = $fs->get_directory_files($context->id, 'user', 'draft', $draftitemid, $filepath, false)) { foreach ($files as $file) { $item = new stdclass; $item->filename = $file->get_filename(); @@ -642,10 +649,8 @@ function file_get_user_area_files($draftitemid, $filepath = '/', $filearea = 'us $item->shortname = $item->fullname; } } else { - $fb = get_file_browser(); - $fileinfo = $fb->get_file_info($context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename()); - $item->url = $fileinfo->get_url(); - $item->sortorder = $fileinfo->get_sortorder(); + // do NOT use file browser here! + $item->url = file_draftfile_url($draftitemid, $item->filepath, $item->filename); } $list[] = $item; } @@ -686,6 +691,7 @@ function file_get_submitted_draft_itemid($elname) { * @param integer $draftitemid the id of the draft area to use. Normally obtained * from file_get_submitted_draft_itemid('elementname') or similar. * @param integer $contextid This parameter and the next two identify the file area to save to. + * @param string $component * @param string $filearea indentifies the file area. * @param integer $itemid helps identifies the file area. * @param array $options area options (subdirs=>false, maxfiles=-1, maxbytes=0) @@ -694,7 +700,7 @@ function file_get_submitted_draft_itemid($elname) { * @param boolean $forcehttps force https urls. * @return string if $text was passed in, the rewritten $text is returned. Otherwise NULL. */ -function file_save_draft_area_files($draftitemid, $contextid, $filearea, $itemid, array $options=null, $text=null, $forcehttps=false) { +function file_save_draft_area_files($draftitemid, $contextid, $component, $filearea, $itemid, array $options=null, $text=null, $forcehttps=false) { global $CFG, $USER; $usercontext = get_context_instance(CONTEXT_USER, $USER->id); @@ -711,17 +717,17 @@ function file_save_draft_area_files($draftitemid, $contextid, $filearea, $itemid $options['maxbytes'] = 0; // unlimited } - $draftfiles = $fs->get_area_files($usercontext->id, 'user_draft', $draftitemid, 'id'); - $oldfiles = $fs->get_area_files($contextid, $filearea, $itemid, 'id'); + $draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id'); + $oldfiles = $fs->get_area_files($contextid, $component, $filearea, $itemid, 'id'); if (count($draftfiles) < 2) { // means there are no files - one file means root dir only ;-) - $fs->delete_area_files($contextid, $filearea, $itemid); + $fs->delete_area_files($contextid, $component, $filearea, $itemid); } else if (count($oldfiles) < 2) { $filecount = 0; // there were no files before - one file means root dir only ;-) - $file_record = array('contextid'=>$contextid, 'filearea'=>$filearea, 'itemid'=>$itemid); + $file_record = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid); foreach ($draftfiles as $file) { if (!$options['subdirs']) { if ($file->get_filepath() !== '/' or $file->is_directory()) { @@ -744,17 +750,17 @@ function file_save_draft_area_files($draftitemid, $contextid, $filearea, $itemid } else { // we have to merge old and new files - we want to keep file ids for files that were not changed - $file_record = array('contextid'=>$contextid, 'filearea'=>$filearea, 'itemid'=>$itemid); + $file_record = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid); $newhashes = array(); foreach ($draftfiles as $file) { - $newhash = sha1($contextid.$filearea.$itemid.$file->get_filepath().$file->get_filename()); + $newhash = $fs->get_pathname_hash($contextid, $component, $filearea, $itemid, $file->get_filepath(), $file->get_filename()); $newhashes[$newhash] = $file; } $filecount = 0; foreach ($oldfiles as $file) { $oldhash = $file->get_pathnamehash(); - // check if sortorder, filename, filepath, filearea, itemid and contextid changed + // check if sortorder, filename, filepath if (isset($newhashes[$oldhash]) && $file->get_sortorder() == $newhashes[$oldhash]->get_sortorder()) { if (!$file->is_directory()) { $filecount++; @@ -762,7 +768,7 @@ function file_save_draft_area_files($draftitemid, $contextid, $filearea, $itemid // unchanged file already there unset($newhashes[$oldhash]); } else { - // delete files not needed any more + // delete files not needed any more - deleted by user $file->delete(); } } @@ -789,8 +795,8 @@ function file_save_draft_area_files($draftitemid, $contextid, $filearea, $itemid } } - // purge the draft area - $fs->delete_area_files($usercontext->id, 'user_draft', $draftitemid); + // note: do not purge the draft area - we clean up areas later in cron, + // the reason is that user might press submit twice and they would loose the files if (is_null($text)) { return null; @@ -798,9 +804,9 @@ function file_save_draft_area_files($draftitemid, $contextid, $filearea, $itemid // relink embedded files if text submitted - no absolute links allowed in database! if ($CFG->slasharguments) { - $draftbase = "$CFG->wwwroot/draftfile.php/$usercontext->id/user_draft/$draftitemid/"; + $draftbase = "$CFG->wwwroot/draftfile.php/$usercontext->id/user/draft/$draftitemid/"; } else { - $draftbase = "$CFG->wwwroot/draftfile.php?file=/$usercontext->id/user_draft/$draftitemid/"; + $draftbase = "$CFG->wwwroot/draftfile.php?file=/$usercontext->id/user/draft/$draftitemid/"; } if ($forcehttps) { @@ -816,6 +822,7 @@ function file_save_draft_area_files($draftitemid, $contextid, $filearea, $itemid * Set file sort order * @global object $DB * @param integer $contextid the context id + * @param string $component * @param string $filearea file area. * @param integer $itemid itemid. * @param string $filepath file path. @@ -823,9 +830,9 @@ function file_save_draft_area_files($draftitemid, $contextid, $filearea, $itemid * @param integer $sortorer the sort order of file. * @return boolean */ -function file_set_sortorder($contextid, $filearea, $itemid, $filepath, $filename, $sortorder) { +function file_set_sortorder($contextid, $component, $filearea, $itemid, $filepath, $filename, $sortorder) { global $DB; - $conditions = array('contextid'=>$contextid, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>$filepath, 'filename'=>$filename); + $conditions = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>$filepath, 'filename'=>$filename); if ($file_record = $DB->get_record('files', $conditions)) { $sortorder = (int)$sortorder; $file_record->sortorder = $sortorder; @@ -839,14 +846,15 @@ function file_set_sortorder($contextid, $filearea, $itemid, $filepath, $filename * reset file sort order number to 0 * @global object $DB * @param integer $contextid the context id + * @param string $component * @param string $filearea file area. * @param integer $itemid itemid. * @return boolean */ -function file_reset_sortorder($contextid, $filearea, $itemid=false) { +function file_reset_sortorder($contextid, $component, $filearea, $itemid=false) { global $DB; - $conditions = array('contextid'=>$contextid, 'filearea'=>$filearea); + $conditions = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea); if ($itemid !== false) { $conditions['itemid'] = $itemid; } @@ -2964,7 +2972,7 @@ class filetype_parser { public function __construct($file = '') { global $CFG; if (empty($file)) { - $this->file = $CFG->libdir.'/file/file_types.mm'; + $this->file = $CFG->libdir.'/filestorage/file_types.mm'; } else { $this->file = $file; } @@ -3041,7 +3049,7 @@ public function get_extensions($types) { } } } else { - exit('Failed to open file'); + exit('Failed to open file lib/filestorage/file_types.mm'); } return $this->result; } diff --git a/lib/packer/file_archive.php b/lib/filestorage/file_archive.php similarity index 94% rename from lib/packer/file_archive.php rename to lib/filestorage/file_archive.php index 8fbeea33edc7b..26d02d643c67a 100644 --- a/lib/packer/file_archive.php +++ b/lib/filestorage/file_archive.php @@ -19,12 +19,22 @@ /** * Abstraction of general file archives. * - * @package moodlecore - * @subpackage file-packer + * @package core + * @subpackage filestorage * @copyright 2008 Petr Skoda (http://skodak.org) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +defined('MOODLE_INTERNAL') || die(); + +/** + * Each file arcive type must extend this class. + * + * @package core + * @subpackage filestorage + * @copyright 2008 Petr Skoda (http://skodak.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ abstract class file_archive implements Iterator { /** Open archive if exists, fail if does not exist. */ diff --git a/lib/file/file_exceptions.php b/lib/filestorage/file_exceptions.php similarity index 61% rename from lib/file/file_exceptions.php rename to lib/filestorage/file_exceptions.php index 4c887b4a9a81a..a4e7f39604e72 100644 --- a/lib/file/file_exceptions.php +++ b/lib/filestorage/file_exceptions.php @@ -18,28 +18,41 @@ /** * File handling related exceptions. * - * @package moodlecore - * @subpackage file + * @package core + * @subpackage filestorage * @copyright 2008 Petr Skoda (http://skodak.org) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +defined('MOODLE_INTERNAL') || die(); + /** * Basic file related exception class + * + * @package core + * @subpackage filestorage + * @copyright 2008 Petr Skoda (http://skodak.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class file_exception extends moodle_exception { - function __construct($errorcode, $a=NULL, $debuginfo=null) { + function __construct($errorcode, $a=NULL, $debuginfo = NULL) { parent::__construct($errorcode, '', '', $a, $debuginfo); } } /** * Can not create file exception + * + * @package core + * @subpackage filestorage + * @copyright 2008 Petr Skoda (http://skodak.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class stored_file_creation_exception extends file_exception { - function __construct($contextid, $filearea, $itemid, $filepath, $filename, $debuginfo=null) { + function __construct($contextid, $component, $filearea, $itemid, $filepath, $filename, $debuginfo = NULL) { $a = new object(); $a->contextid = $contextid; + $a->component = $component; $a->filearea = $filearea; $a->itemid = $itemid; $a->filepath = $filepath; @@ -50,18 +63,28 @@ function __construct($contextid, $filearea, $itemid, $filepath, $filename, $debu /** * No file access exception. + * + * @package core + * @subpackage filestorage + * @copyright 2008 Petr Skoda (http://skodak.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class file_access_exception extends file_exception { - function __construct($debuginfo=null) { + function __construct($debuginfo = NULL) { parent::__construct('nopermissions', NULL, $debuginfo); } } /** * Hash file content problem exception. + * + * @package core + * @subpackage filestorage + * @copyright 2008 Petr Skoda (http://skodak.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class file_pool_content_exception extends file_exception { - function __construct($contenthash, $debuginfo=null) { + function __construct($contenthash, $debuginfo = NULL) { parent::__construct('hashpoolproblem', $contenthash, $debuginfo); } } diff --git a/lib/packer/file_packer.php b/lib/filestorage/file_packer.php similarity index 85% rename from lib/packer/file_packer.php rename to lib/filestorage/file_packer.php index 4936737d5c8ae..99aa281fab05b 100644 --- a/lib/packer/file_packer.php +++ b/lib/filestorage/file_packer.php @@ -19,14 +19,21 @@ /** * Abstraction of general file packer. * - * @package moodlecore - * @subpackage file-packer + * @package core + * @subpackage filestorage * @copyright 2008 Petr Skoda (http://skodak.org) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +defined('MOODLE_INTERNAL') || die(); + /** * Abstract class for archiving of files. + * + * @package core + * @subpackage filestorage + * @copyright 2008 Petr Skoda (http://skodak.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ abstract class file_packer { @@ -34,13 +41,14 @@ abstract class file_packer { * Archive files and store the result in file storage * @param array $files array with zip paths as keys (archivepath=>ospathname or archivepath=>stored_file) * @param int $contextid + * @param string $component * @param string $filearea * @param int $itemid * @param string $filepath * @param string $filename * @return mixed false if error stored file instance if ok */ - public abstract function archive_to_storage($files, $contextid, $filearea, $itemid, $filepath, $filename, $userid=null); + public abstract function archive_to_storage($files, $contextid, $component, $filearea, $itemid, $filepath, $filename, $userid = NULL); /** * Archive files and store the result in os file @@ -62,12 +70,13 @@ public abstract function extract_to_pathname($archivefile, $pathname); * Extract file to given file path (real OS filesystem), existing files are overwrited * @param mixed $archivefile full pathname of zip file or stored_file instance * @param int $contextid + * @param string $component * @param string $filearea * @param int $itemid * @param string $filepath * @return mixed list of processed files; false if error */ - public abstract function extract_to_storage($archivefile, $contextid, $filearea, $itemid, $pathbase, $userid=null); + public abstract function extract_to_storage($archivefile, $contextid, $component, $filearea, $itemid, $pathbase, $userid = NULL); /** * Returns array of info about all files in archive diff --git a/lib/file/file_storage.php b/lib/filestorage/file_storage.php similarity index 87% rename from lib/file/file_storage.php rename to lib/filestorage/file_storage.php index a6fe2bc596d26..089e35cf501dc 100644 --- a/lib/file/file_storage.php +++ b/lib/filestorage/file_storage.php @@ -19,13 +19,15 @@ /** * Core file storage class definition. * - * @package moodlecore - * @subpackage file-storage + * @package core + * @subpackage filestorage * @copyright 2008 Petr Skoda {@link http://skodak.org} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -require_once("$CFG->libdir/file/stored_file.php"); +defined('MOODLE_INTERNAL') || die(); + +require_once("$CFG->libdir/filestorage/stored_file.php"); /** * File storage class used for low level access to stored files. @@ -105,27 +107,29 @@ public function get_filedir() { * performance and overcome db index size limits. * * @param int $contextid + * @param string $component * @param string $filearea * @param int $itemid * @param string $filepath * @param string $filename * @return string sha1 hash */ - public static function get_pathname_hash($contextid, $filearea, $itemid, $filepath, $filename) { - return sha1($contextid.$filearea.$itemid.$filepath.$filename); + public static function get_pathname_hash($contextid, $component, $filearea, $itemid, $filepath, $filename) { + return sha1("/$contextid/$component/$filearea/$itemid".$filepath.$filename); } /** * Does this file exist? * * @param int $contextid + * @param string $component * @param string $filearea * @param int $itemid * @param string $filepath * @param string $filename * @return bool */ - public function file_exists($contextid, $filearea, $itemid, $filepath, $filename) { + public function file_exists($contextid, $component, $filearea, $itemid, $filepath, $filename) { $filepath = clean_param($filepath, PARAM_PATH); $filename = clean_param($filename, PARAM_FILE); @@ -133,7 +137,7 @@ public function file_exists($contextid, $filearea, $itemid, $filepath, $filename $filename = '.'; } - $pathnamehash = $this->get_pathname_hash($contextid, $filearea, $itemid, $filepath, $filename); + $pathnamehash = $this->get_pathname_hash($contextid, $component, $filearea, $itemid, $filepath, $filename); return $this->file_exists_by_hash($pathnamehash); } @@ -188,13 +192,14 @@ public function get_file_by_hash($pathnamehash) { * Fetch locally stored file. * * @param int $contextid + * @param string $component * @param string $filearea * @param int $itemid * @param string $filepath * @param string $filename * @return stored_file instance if exists, false if not */ - public function get_file($contextid, $filearea, $itemid, $filepath, $filename) { + public function get_file($contextid, $component, $filearea, $itemid, $filepath, $filename) { global $DB; $filepath = clean_param($filepath, PARAM_PATH); @@ -204,7 +209,7 @@ public function get_file($contextid, $filearea, $itemid, $filepath, $filename) { $filename = '.'; } - $pathnamehash = $this->get_pathname_hash($contextid, $filearea, $itemid, $filepath, $filename); + $pathnamehash = $this->get_pathname_hash($contextid, $component, $filearea, $itemid, $filepath, $filename); return $this->get_file_by_hash($pathnamehash); } @@ -212,16 +217,17 @@ public function get_file($contextid, $filearea, $itemid, $filepath, $filename) { * Returns all area files (optionally limited by itemid) * * @param int $contextid + * @param string $component * @param string $filearea * @param int $itemid (all files if not specified) * @param string $sort * @param bool $includedirs * @return array of stored_files indexed by pathanmehash */ - public function get_area_files($contextid, $filearea, $itemid=false, $sort="sortorder, itemid, filepath, filename", $includedirs = true) { + public function get_area_files($contextid, $component, $filearea, $itemid=false, $sort="sortorder, itemid, filepath, filename", $includedirs = true) { global $DB; - $conditions = array('contextid'=>$contextid, 'filearea'=>$filearea); + $conditions = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea); if ($itemid !== false) { $conditions['itemid'] = $itemid; } @@ -241,13 +247,14 @@ public function get_area_files($contextid, $filearea, $itemid=false, $sort="sort * Returns array based tree structure of area files * * @param int $contextid + * @param string $component * @param string $filearea * @param int $itemid * @return array each dir represented by dirname, subdirs, files and dirfile array elements */ - public function get_area_tree($contextid, $filearea, $itemid) { + public function get_area_tree($contextid, $component, $filearea, $itemid) { $result = array('dirname'=>'', 'dirfile'=>null, 'subdirs'=>array(), 'files'=>array()); - $files = $this->get_area_files($contextid, $filearea, $itemid, $sort="sortorder, itemid, filepath, filename", true); + $files = $this->get_area_files($contextid, $component, $filearea, $itemid, $sort="sortorder, itemid, filepath, filename", true); // first create directory structure foreach ($files as $hash=>$dir) { if (!$dir->is_directory()) { @@ -291,6 +298,7 @@ public function get_area_tree($contextid, $filearea, $itemid) { * Returns all files and optionally directories * * @param int $contextid + * @param string $component * @param string $filearea * @param int $itemid * @param int $filepath directory path @@ -299,10 +307,10 @@ public function get_area_tree($contextid, $filearea, $itemid) { * @param string $sort * @return array of stored_files indexed by pathanmehash */ - public function get_directory_files($contextid, $filearea, $itemid, $filepath, $recursive = false, $includedirs = true, $sort = "filepath, filename") { + public function get_directory_files($contextid, $component, $filearea, $itemid, $filepath, $recursive = false, $includedirs = true, $sort = "filepath, filename") { global $DB; - if (!$directory = $this->get_file($contextid, $filearea, $itemid, $filepath, '.')) { + if (!$directory = $this->get_file($contextid, $component, $filearea, $itemid, $filepath, '.')) { return array(); } @@ -313,12 +321,12 @@ public function get_directory_files($contextid, $filearea, $itemid, $filepath, $ $sql = "SELECT * FROM {files} - WHERE contextid = :contextid AND filearea = :filearea AND itemid = :itemid + WHERE contextid = :contextid AND component = :component AND filearea = :filearea AND itemid = :itemid AND ".$DB->sql_substr("filepath", 1, $length)." = :filepath AND id <> :dirid $dirs ORDER BY $sort"; - $params = array('contextid'=>$contextid, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>$filepath, 'dirid'=>$directory->get_id()); + $params = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>$filepath, 'dirid'=>$directory->get_id()); $files = array(); $dirs = array(); @@ -334,14 +342,14 @@ public function get_directory_files($contextid, $filearea, $itemid, $filepath, $ } else { $result = array(); - $params = array('contextid'=>$contextid, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>$filepath, 'dirid'=>$directory->get_id()); + $params = array('contextid'=>$contextid, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid, 'filepath'=>$filepath, 'dirid'=>$directory->get_id()); $length = textlib_get_instance()->strlen($filepath); if ($includedirs) { $sql = "SELECT * FROM {files} - WHERE contextid = :contextid AND filearea = :filearea + WHERE contextid = :contextid AND component = :component AND filearea = :filearea AND itemid = :itemid AND filename = '.' AND ".$DB->sql_substr("filepath", 1, $length)." = :filepath AND id <> :dirid @@ -358,7 +366,7 @@ public function get_directory_files($contextid, $filearea, $itemid, $filepath, $ $sql = "SELECT * FROM {files} - WHERE contextid = :contextid AND filearea = :filearea AND itemid = :itemid + WHERE contextid = :contextid AND component = :component AND filearea = :filearea AND itemid = :itemid AND filepath = :filepath AND filename <> '.' ORDER BY $sort"; @@ -375,14 +383,18 @@ public function get_directory_files($contextid, $filearea, $itemid, $filepath, $ * Delete all area files (optionally limited by itemid). * * @param int $contextid + * @param string $component * @param string $filearea (all areas in context if not specified) * @param int $itemid (all files if not specified) * @return bool success */ - public function delete_area_files($contextid, $filearea = false, $itemid = false) { + public function delete_area_files($contextid, $component = false, $filearea = false, $itemid = false) { global $DB; $conditions = array('contextid'=>$contextid); + if ($component !== false) { + $conditions['component'] = $component; + } if ($filearea !== false) { $conditions['filearea'] = $filearea; } @@ -403,13 +415,14 @@ public function delete_area_files($contextid, $filearea = false, $itemid = false * Recursively creates directory. * * @param int $contextid + * @param string $component * @param string $filearea * @param int $itemid * @param string $filepath * @param string $filename * @return bool success */ - public function create_directory($contextid, $filearea, $itemid, $filepath, $userid = null) { + public function create_directory($contextid, $component, $filearea, $itemid, $filepath, $userid = null) { global $DB; // validate all parameters, we do not want any rubbish stored in database, right? @@ -417,8 +430,11 @@ public function create_directory($contextid, $filearea, $itemid, $filepath, $use throw new file_exception('storedfileproblem', 'Invalid contextid'); } - $filearea = clean_param($filearea, PARAM_ALPHAEXT); - if ($filearea === '') { + if ($component === '' or $component !== clean_param($component, PARAM_ALPHAEXT)) { + throw new file_exception('storedfileproblem', 'Invalid component'); + } + + if ($filearea === '' or $filearea !== clean_param($filearea, PARAM_ALPHAEXT)) { throw new file_exception('storedfileproblem', 'Invalid filearea'); } @@ -432,7 +448,7 @@ public function create_directory($contextid, $filearea, $itemid, $filepath, $use throw new file_exception('storedfileproblem', 'Invalid file path'); } - $pathnamehash = $this->get_pathname_hash($contextid, $filearea, $itemid, $filepath, '.'); + $pathnamehash = $this->get_pathname_hash($contextid, $component, $filearea, $itemid, $filepath, '.'); if ($dir_info = $this->get_file_by_hash($pathnamehash)) { return $dir_info; @@ -448,6 +464,7 @@ public function create_directory($contextid, $filearea, $itemid, $filepath, $use $dir_record = new object(); $dir_record->contextid = $contextid; + $dir_record->component = $component; $dir_record->filearea = $filearea; $dir_record->itemid = $itemid; $dir_record->filepath = $filepath; @@ -472,7 +489,7 @@ public function create_directory($contextid, $filearea, $itemid, $filepath, $use array_pop($filepath); $filepath = implode('/', $filepath); $filepath = ($filepath === '') ? '/' : "/$filepath/"; - $this->create_directory($contextid, $filearea, $itemid, $filepath, $userid); + $this->create_directory($contextid, $component, $filearea, $itemid, $filepath, $userid); } return $dir_info; @@ -515,9 +532,14 @@ public function create_file_from_storedfile($file_record, $fileorid) { throw new file_exception('storedfileproblem', 'Invalid contextid'); } + if ($key == 'component') { + if ($value === '' or $value !== clean_param($value, PARAM_ALPHAEXT)) { + throw new file_exception('storedfileproblem', 'Invalid component'); + } + } + if ($key == 'filearea') { - $value = clean_param($value, PARAM_ALPHAEXT); - if ($value === '') { + if ($value === '' or $value !== clean_param($value, PARAM_ALPHAEXT)) { throw new file_exception('storedfileproblem', 'Invalid filearea'); } } @@ -546,11 +568,11 @@ public function create_file_from_storedfile($file_record, $fileorid) { $newrecord->$key = $value; } - $newrecord->pathnamehash = $this->get_pathname_hash($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename); + $newrecord->pathnamehash = $this->get_pathname_hash($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename); if ($newrecord->filename === '.') { // special case - only this function supports directories ;-) - $directory = $this->create_directory($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid); + $directory = $this->create_directory($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid); // update the existing directory with the new data $newrecord->id = $directory->get_id(); $DB->update_record('files', $newrecord); @@ -564,11 +586,11 @@ public function create_file_from_storedfile($file_record, $fileorid) { } if (!$newrecord->id) { - throw new stored_file_creation_exception($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, + throw new stored_file_creation_exception($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename); } - $this->create_directory($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid); + $this->create_directory($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid); return new stored_file($this, $newrecord); } @@ -645,8 +667,11 @@ public function create_file_from_pathname($file_record, $pathname) { throw new file_exception('storedfileproblem', 'Invalid contextid'); } - $file_record->filearea = clean_param($file_record->filearea, PARAM_ALPHAEXT); - if ($file_record->filearea === '') { + if ($file_record->component === '' or $file_record->component !== clean_param($file_record->component, PARAM_ALPHAEXT)) { + throw new file_exception('storedfileproblem', 'Invalid component'); + } + + if ($file_record->filearea === '' or $file_record->filearea !== clean_param($file_record->filearea, PARAM_ALPHAEXT)) { throw new file_exception('storedfileproblem', 'Invalid filearea'); } @@ -679,6 +704,7 @@ public function create_file_from_pathname($file_record, $pathname) { $newrecord = new object(); $newrecord->contextid = $file_record->contextid; + $newrecord->component = $file_record->component; $newrecord->filearea = $file_record->filearea; $newrecord->itemid = $file_record->itemid; $newrecord->filepath = $file_record->filepath; @@ -695,7 +721,7 @@ public function create_file_from_pathname($file_record, $pathname) { list($newrecord->contenthash, $newrecord->filesize, $newfile) = $this->add_file_to_pool($pathname); - $newrecord->pathnamehash = $this->get_pathname_hash($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename); + $newrecord->pathnamehash = $this->get_pathname_hash($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename); try { $newrecord->id = $DB->insert_record('files', $newrecord); @@ -707,11 +733,11 @@ public function create_file_from_pathname($file_record, $pathname) { if ($newfile) { $this->deleted_file_cleanup($newrecord->contenthash); } - throw new stored_file_creation_exception($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, + throw new stored_file_creation_exception($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename); } - $this->create_directory($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid); + $this->create_directory($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid); return new stored_file($this, $newrecord); } @@ -734,8 +760,11 @@ public function create_file_from_string($file_record, $content) { throw new file_exception('storedfileproblem', 'Invalid contextid'); } - $file_record->filearea = clean_param($file_record->filearea, PARAM_ALPHAEXT); - if ($file_record->filearea === '') { + if ($file_record->component === '' or $file_record->component !== clean_param($file_record->component, PARAM_ALPHAEXT)) { + throw new file_exception('storedfileproblem', 'Invalid component'); + } + + if ($file_record->filearea === '' or $file_record->filearea !== clean_param($file_record->filearea, PARAM_ALPHAEXT)) { throw new file_exception('storedfileproblem', 'Invalid filearea'); } @@ -768,6 +797,7 @@ public function create_file_from_string($file_record, $content) { $newrecord = new object(); $newrecord->contextid = $file_record->contextid; + $newrecord->component = $file_record->component; $newrecord->filearea = $file_record->filearea; $newrecord->itemid = $file_record->itemid; $newrecord->filepath = $file_record->filepath; @@ -784,7 +814,7 @@ public function create_file_from_string($file_record, $content) { list($newrecord->contenthash, $newrecord->filesize, $newfile) = $this->add_string_to_pool($content); - $newrecord->pathnamehash = $this->get_pathname_hash($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename); + $newrecord->pathnamehash = $this->get_pathname_hash($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename); try { $newrecord->id = $DB->insert_record('files', $newrecord); @@ -796,11 +826,11 @@ public function create_file_from_string($file_record, $content) { if ($newfile) { $this->deleted_file_cleanup($newrecord->contenthash); } - throw new stored_file_creation_exception($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, + throw new stored_file_creation_exception($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename); } - $this->create_directory($newrecord->contextid, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid); + $this->create_directory($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->userid); return new stored_file($this, $newrecord); } @@ -1118,6 +1148,10 @@ public function deleted_file_cleanup($contenthash) { */ public function cron() { global $CFG, $DB; + //TODO: find out all stale draft areas (older than 1 day) and purge them + // those are identified by time stamp of the /. root dir + + // remove trash pool files once a day // if you want to disable purging of trash put $CFG->fileslastcleanup=time(); into config.php if (empty($CFG->fileslastcleanup) or $CFG->fileslastcleanup < time() - 60*60*24) { diff --git a/lib/file/file_types.mm b/lib/filestorage/file_types.mm similarity index 100% rename from lib/file/file_types.mm rename to lib/filestorage/file_types.mm diff --git a/lib/file/stored_file.php b/lib/filestorage/stored_file.php similarity index 92% rename from lib/file/stored_file.php rename to lib/filestorage/stored_file.php index d002f809c2c91..125d8e35962f3 100644 --- a/lib/file/stored_file.php +++ b/lib/filestorage/stored_file.php @@ -19,13 +19,15 @@ /** * Definition of a class stored_file. * - * @package moodlecore - * @subpackage file-storage + * @package core + * @subpackage filestorage * @copyright 2008 Petr Skoda {@link http://skodak.org} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -require_once("$CFG->libdir/file/stored_file.php"); +defined('MOODLE_INTERNAL') || die(); + +require_once("$CFG->libdir/filestorage/stored_file.php"); /** * Class representing local files stored in a sha1 file pool. @@ -201,15 +203,16 @@ public function extract_to_pathname(file_packer $packer, $pathname) { * * @param file_packer $file_packer * @param int $contextid + * @param string $component * @param string $filearea * @param int $itemid * @param string $pathbase * @param int $userid * @return array|bool list of processed files; false if error */ - public function extract_to_storage(file_packer $packer, $contextid, $filearea, $itemid, $pathbase, $userid = NULL) { + public function extract_to_storage(file_packer $packer, $contextid, $component, $filearea, $itemid, $pathbase, $userid = NULL) { $archivefile = $this->get_content_file_location(); - return $packer->extract_to_storage($archivefile, $contextid, $filearea, $itemid, $pathbase); + return $packer->extract_to_storage($archivefile, $contextid, $component, $filearea, $itemid, $pathbase); } /** @@ -282,7 +285,7 @@ public function get_parent_directory() { } if ($this->file_record->filename !== '.') { - return $this->fs->create_directory($this->file_record->contextid, $this->file_record->filearea, $this->file_record->itemid, $this->file_record->filepath); + return $this->fs->create_directory($this->file_record->contextid, $this->file_record->component, $this->file_record->filearea, $this->file_record->itemid, $this->file_record->filepath); } $filepath = $this->file_record->filepath; @@ -292,7 +295,7 @@ public function get_parent_directory() { $filepath = implode('/', $dirs); $filepath = ($filepath === '') ? '/' : "/$filepath/"; - return $this->fs->create_directory($this->file_record->contextid, $this->file_record->filearea, $this->file_record->itemid, $filepath); + return $this->fs->create_directory($this->file_record->contextid, $this->file_record->component, $this->file_record->filearea, $this->file_record->itemid, $filepath); } /** @@ -305,8 +308,18 @@ public function get_contextid() { } /** - * Returns file area name, the areas do not have to be unique, - * but usually have form component_typeofarea such as forum_attachments. + * Returns component name - this is the owner of the areas, + * nothing else is allowed to read or modify the files directly!! + * + * @return string + */ + public function get_component() { + return $this->file_record->component; + } + + /** + * Returns file area name, this divides files of one component into groups with different access control. + * All files in one area have the same access control. * * @return string */ @@ -414,7 +427,7 @@ public function get_contenthash() { } /** - * Returns sha1 hash of all file path components sha1("contextid/filearea/itemid/dir/dir/filename.ext"). + * Returns sha1 hash of all file path components sha1("contextid/component/filearea/itemid/dir/dir/filename.ext"). * * @return string */ diff --git a/lib/packer/zip_archive.php b/lib/filestorage/zip_archive.php similarity index 96% rename from lib/packer/zip_archive.php rename to lib/filestorage/zip_archive.php index 4abd0c6caa3b4..4c3b37fe128a9 100644 --- a/lib/packer/zip_archive.php +++ b/lib/filestorage/zip_archive.php @@ -19,14 +19,24 @@ /** * Implementation of zip file archive. * - * @package moodlecore - * @subpackage file-packer + * @package core + * @subpackage filestorage * @copyright 2008 Petr Skoda (http://skodak.org) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -require_once("$CFG->libdir/packer/file_archive.php"); +defined('MOODLE_INTERNAL') || die(); +require_once("$CFG->libdir/filestorage/file_archive.php"); + +/** + * zip file archive class. + * + * @package core + * @subpackage filestorage + * @copyright 2008 Petr Skoda (http://skodak.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ class zip_archive extends file_archive { /** Pathname of archive */ diff --git a/lib/packer/zip_packer.php b/lib/filestorage/zip_packer.php similarity index 91% rename from lib/packer/zip_packer.php rename to lib/filestorage/zip_packer.php index b6aa754520958..cf4e4185b4f6d 100644 --- a/lib/packer/zip_packer.php +++ b/lib/filestorage/zip_packer.php @@ -19,17 +19,24 @@ /** * Implementation of zip packer. * - * @package moodlecore - * @subpackage file-packer + * @package core + * @subpackage filestorage * @copyright 2008 Petr Skoda (http://skodak.org) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -require_once("$CFG->libdir/packer/file_packer.php"); -require_once("$CFG->libdir/packer/zip_archive.php"); +defined('MOODLE_INTERNAL') || die(); + +require_once("$CFG->libdir/filestorage/file_packer.php"); +require_once("$CFG->libdir/filestorage/zip_archive.php"); /** * Utility class - handles all zipping and unzipping operations. + * + * @package core + * @subpackage filestorage + * @copyright 2008 Petr Skoda (http://skodak.org) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class zip_packer extends file_packer { @@ -37,13 +44,14 @@ class zip_packer extends file_packer { * Zip files and store the result in file storage * @param array $files array with full zip paths (including directory information) as keys (archivepath=>ospathname or archivepath/subdir=>stored_file) * @param int $contextid + * @param string $component * @param string $filearea * @param int $itemid * @param string $filepath * @param string $filename * @return mixed false if error stored file instance if ok */ - public function archive_to_storage($files, $contextid, $filearea, $itemid, $filepath, $filename, $userid=null) { + public function archive_to_storage($files, $contextid, $component, $filearea, $itemid, $filepath, $filename, $userid = NULL) { global $CFG; $fs = get_file_storage(); @@ -52,7 +60,7 @@ public function archive_to_storage($files, $contextid, $filearea, $itemid, $file $tmpfile = tempnam($CFG->dataroot.'/temp/zip', 'zipstor'); if ($result = $this->archive_to_pathname($files, $tmpfile)) { - if ($file = $fs->get_file($contextid, $filearea, $itemid, $filepath, $filename)) { + if ($file = $fs->get_file($contextid, $component, $filearea, $itemid, $filepath, $filename)) { if (!$file->delete()) { @unlink($tmpfile); return false; @@ -60,6 +68,7 @@ public function archive_to_storage($files, $contextid, $filearea, $itemid, $file } $file_record = new object(); $file_record->contextid = $contextid; + $file_record->component = $component; $file_record->filearea = $filearea; $file_record->itemid = $itemid; $file_record->filepath = $filepath; @@ -118,7 +127,7 @@ private function archive_stored($ziparch, $archivepath, $file) { $baselength = strlen($file->get_filepath()); $fs = get_file_storage(); - $files = $fs->get_directory_files($file->get_contextid(), $file->get_filearea(), $file->get_itemid(), + $files = $fs->get_directory_files($file->get_contextid(), $file->get_component(), $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), true, true); foreach ($files as $file) { $path = $file->get_filepath(); @@ -257,16 +266,17 @@ public function extract_to_pathname($archivefile, $pathname) { * Unzip file to given file path (real OS filesystem), existing files are overwrited * @param mixed $archivefile full pathname of zip file or stored_file instance * @param int $contextid + * @param string $component * @param string $filearea * @param int $itemid * @param string $filepath * @return mixed list of processed files; false if error */ - public function extract_to_storage($archivefile, $contextid, $filearea, $itemid, $pathbase, $userid=null) { + public function extract_to_storage($archivefile, $contextid, $component, $filearea, $itemid, $pathbase, $userid = NULL) { global $CFG; if (!is_string($archivefile)) { - return $archivefile->extract_to_pathname($this, $contextid, $filearea, $itemid, $pathbase, $userid); + return $archivefile->extract_to_pathname($this, $contextid, $component, $filearea, $itemid, $pathbase, $userid); } check_dir_exists($CFG->dataroot.'/temp/zip', true, true); @@ -293,7 +303,7 @@ public function extract_to_storage($archivefile, $contextid, $filearea, $itemid, if ($info->is_directory) { $newfilepath = $pathbase.$name.'/'; - $fs->create_directory($contextid, $filearea, $itemid, $newfilepath, $userid); + $fs->create_directory($contextid, $component, $filearea, $itemid, $newfilepath, $userid); $processed[$name] = true; continue; } @@ -323,7 +333,7 @@ public function extract_to_storage($archivefile, $contextid, $filearea, $itemid, continue; } - if ($file = $fs->get_file($contextid, $filearea, $itemid, $filepath, $filename)) { + if ($file = $fs->get_file($contextid, $component, $filearea, $itemid, $filepath, $filename)) { if (!$file->delete()) { $processed[$name] = 'Can not delete existing file'; // TODO: localise continue; @@ -331,6 +341,7 @@ public function extract_to_storage($archivefile, $contextid, $filearea, $itemid, } $file_record = new object(); $file_record->contextid = $contextid; + $file_record->component = $component; $file_record->filearea = $filearea; $file_record->itemid = $itemid; $file_record->filepath = $filepath; @@ -370,7 +381,7 @@ public function extract_to_storage($archivefile, $contextid, $filearea, $itemid, continue; } - if ($file = $fs->get_file($contextid, $filearea, $itemid, $filepath, $filename)) { + if ($file = $fs->get_file($contextid, $component, $filearea, $itemid, $filepath, $filename)) { if (!$file->delete()) { @unlink($tmpfile); $processed[$name] = 'Can not delete existing file'; // TODO: localise @@ -379,6 +390,7 @@ public function extract_to_storage($archivefile, $contextid, $filearea, $itemid, } $file_record = new object(); $file_record->contextid = $contextid; + $file_record->component = $component; $file_record->filearea = $filearea; $file_record->itemid = $itemid; $file_record->filepath = $filepath; diff --git a/lib/form/filemanager.js b/lib/form/filemanager.js index ba1e6768abf5e..5c74d9bce23bc 100644 --- a/lib/form/filemanager.js +++ b/lib/form/filemanager.js @@ -50,7 +50,7 @@ M.form_filemanager.init = function(Y, options) { }; Y.extend(FileManagerHelper, Y.Base, { - api: M.cfg.wwwroot+'/files/files_ajax.php', + api: M.cfg.wwwroot+'/repository/draftfiles_ajax.php', menus: {}, initializer: function(options) { this.options = options; @@ -67,10 +67,8 @@ M.form_filemanager.init = function(Y, options) { this.filepicker_options.maxfiles = this.maxfiles; this.filepicker_options.maxbytes = this.maxbytes; this.filepicker_options.env = 'filemanager'; - this.filepicker_options.filearea = options.filearea; this.filepicker_options.itemid = options.itemid; - this.filearea = options.filearea?options.filearea:'user_draft'; if (options.filecount) { this.filecount = options.filecount; } else { @@ -104,7 +102,6 @@ M.form_filemanager.init = function(Y, options) { scope = args['scope']; } params['sesskey'] = M.cfg.sesskey; - params['filearea'] = this.filearea; params['client_id'] = this.client_id; params['filepath'] = this.currentpath; params['itemid'] = this.options.itemid?this.options.itemid:0; diff --git a/lib/form/filemanager.php b/lib/form/filemanager.php index c0a24e0853b3e..184ff1a1f598f 100644 --- a/lib/form/filemanager.php +++ b/lib/form/filemanager.php @@ -137,7 +137,6 @@ function toHtml() { // filemanager options $options = new stdclass; $options->mainfile = $this->_options['mainfile']; - $options->filearea = 'user_draft'; $options->maxbytes = $this->_options['maxbytes']; $options->maxfiles = $this->getMaxfiles(); $options->client_id = $client_id; @@ -149,7 +148,7 @@ function toHtml() { $options->context = $PAGE->context; $html = $this->_getTabs(); - $html .= $OUTPUT->file_manager($options); + $html .= form_filemanager_render($options); $html .= ''; // label element needs 'for' attribute work @@ -158,3 +157,183 @@ function toHtml() { return $html; } } + + + +/** + * Data structure representing a file manager. + * + * @copyright 2010 Dongsheng Cai + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class form_filemanaer_x { + //TODO: do not use this abstraction (skodak) + + public $options; + public function __construct(stdClass $options) { + global $CFG, $USER, $PAGE; + require_once($CFG->dirroot. '/repository/lib.php'); + $defaults = array( + 'maxbytes'=>-1, + 'maxfiles'=>-1, + 'itemid'=>0, + 'subdirs'=>0, + 'client_id'=>uniqid(), + 'accepted_types'=>'*', + 'return_types'=>FILE_INTERNAL, + 'context'=>$PAGE->context + ); + foreach ($defaults as $key=>$value) { + if (empty($options->$key)) { + $options->$key = $value; + } + } + + $fs = get_file_storage(); + + // initilise options, getting files in root path + $this->options = file_get_drafarea_files($options->itemid, '/'); + + // calculate file count + $usercontext = get_context_instance(CONTEXT_USER, $USER->id); + $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $options->itemid, 'id', false); + $filecount = count($files); + $this->options->filecount = $filecount; + + // copying other options + foreach ($options as $name=>$value) { + $this->options->$name = $value; + } + + // building file picker options + $params = new stdclass; + $params->accepted_types = $options->accepted_types; + $params->return_types = $options->return_types; + $params->context = $options->context; + $params->env = 'filemanager'; + $params->disable_types = !empty($options->disable_types)?$options->disable_types:array(); + $filepicker_options = initialise_filepicker($params); + $this->options->filepicker = $filepicker_options; + } +} + +/** + * Print the file manager + * + *
+ * $OUTPUT->file_manager($options);
+ * 
+ * + * @param array $options associative array with file manager options + * options are: + * maxbytes=>-1, + * maxfiles=>-1, + * itemid=>0, + * subdirs=>false, + * client_id=>uniqid(), + * acepted_types=>'*', + * return_types=>FILE_INTERNAL, + * context=>$PAGE->context + * @return string HTML fragment + */ +function form_filemanager_render($options) { + global $CFG, $OUTPUT, $PAGE; + + $fm = new form_filemanaer_x($options); //TODO: this is unnecessary here, the nested options are getting too complex + + static $filemanagertemplateloaded; + + $html = ''; + $nonjsfilemanager = optional_param('usenonjsfilemanager', 0, PARAM_INT); + $options = $fm->options; + $options->usenonjs = $nonjsfilemanager; + $straddfile = get_string('add', 'repository') . '...'; + $strmakedir = get_string('makeafolder', 'moodle'); + $strdownload = get_string('downloadfolder', 'repository'); + $strloading = get_string('loading', 'repository'); + + $icon_add_file = $OUTPUT->pix_icon('t/addfile', $straddfile).''; + $icon_add_folder = $OUTPUT->pix_icon('t/adddir', $strmakedir).''; + $icon_download = $OUTPUT->pix_icon('t/download', $strdownload).''; + $icon_progress = $OUTPUT->pix_icon('i/loading_small', $strloading).''; + + $client_id = $options->client_id; + $itemid = $options->itemid; + + if (empty($options->filecount)) { + $extra = ' style="display:none"'; + } else { + $extra = ''; + } + + $html .= << +$icon_progress +
+ +
+FMHTML; + if (empty($filemanagertemplateloaded)) { + $filemanagertemplateloaded = true; + $html .= <<
+FMHTML; + } + + $filemanagerurl = new moodle_url('/repository/filepicker.php', array( + 'env'=>'filemanager', + 'action'=>'embedded', + 'itemid'=>$itemid, + 'subdirs'=>'/', + 'maxbytes'=>$options->maxbytes, + 'ctx_id'=>$PAGE->context->id, + 'course'=>$PAGE->course->id, + )); + + $module = array( + 'name'=>'form_filemanager', + 'fullpath'=>'/lib/form/filemanager.js', + 'requires' => array('core_filepicker', 'base', 'io', 'node', 'json', 'yui2-button', 'yui2-container', 'yui2-layout', 'yui2-menu', 'yui2-treeview'), + 'strings' => array(array('loading', 'repository'), array('nomorefiles', 'repository'), array('confirmdeletefile', 'repository'), + array('add', 'repository'), array('accessiblefilepicker', 'repository'), array('move', 'moodle'), + array('cancel', 'moodle'), array('download', 'moodle'), array('ok', 'moodle'), + array('emptylist', 'repository'), array('nofilesattached', 'repository'), array('entername', 'repository'), array('enternewname', 'repository'), + array('zip', 'editor'), array('unzip', 'moodle'), array('rename', 'moodle'), array('delete', 'moodle'), + array('cannotdeletefile', 'error'), array('confirmdeletefile', 'repository'), + array('nopathselected', 'repository'), array('popupblockeddownload', 'repository'), + array('draftareanofiles', 'repository'), array('path', 'moodle'), array('setmainfile', 'repository') + ) + ); + $PAGE->requires->js_module($module); + $PAGE->requires->js_init_call('M.form_filemanager.init', array($options), true, $module); + + // non javascript file manager + if (!empty($nonjsfilemanager)) { + $html = '
'; + $html .= <<Error +NONJS; + $html .= '
'; + } else { + $url = new moodle_url($PAGE->url, array('usenonjsfilemanager'=>1)); + $html .= '
'; + $html .= html_writer::link($url, get_string('usenonjsfilemanager', 'repository')); + $html .= '
'; + } + + + return $html; +} diff --git a/lib/form/filepicker.php b/lib/form/filepicker.php index b68d6dfc7fe2b..f54d7bd315f9d 100644 --- a/lib/form/filepicker.php +++ b/lib/form/filepicker.php @@ -96,7 +96,7 @@ function exportValue(&$submitValues, $assoc = false) { if ($draftitemid = $submitValues[$this->_attributes['name']]) { $fs = get_file_storage(); $usercontext = get_context_instance(CONTEXT_USER, $USER->id); - if ($files = $fs->get_area_files($usercontext->id, 'user_draft', $draftitemid, 'id DESC', false)) { + if ($files = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id DESC', false)) { $file = array_shift($files); if ($this->_options['maxbytes'] and $file->get_filesize() > $this->_options['maxbytes']) { // bad luck, somebody tries to sneak in oversized file diff --git a/lib/form/htmleditor.php b/lib/form/htmleditor.php index f260a6c4e2de1..0dbc0b737a2d5 100644 --- a/lib/form/htmleditor.php +++ b/lib/form/htmleditor.php @@ -11,7 +11,7 @@ class MoodleQuickForm_htmleditor extends MoodleQuickForm_textarea{ var $_type; var $_canUseHtmlEditor; - var $_options=array('canUseHtmlEditor'=>'detect','rows'=>10, 'cols'=>45, 'width'=>0,'height'=>0, 'filearea'=>''); + var $_options=array('canUseHtmlEditor'=>'detect','rows'=>10, 'cols'=>45, 'width'=>0,'height'=>0); function MoodleQuickForm_htmleditor($elementName=null, $elementLabel=null, $options=array(), $attributes=null){ parent::MoodleQuickForm_textarea($elementName, $elementLabel, $attributes); // set the options, do not bother setting bogus ones @@ -60,7 +60,6 @@ function toHtml(){ return $this->getFrozenHtml(); } else { return $this->_getTabs() . - ''."\n". print_textarea($this->_canUseHtmlEditor, $this->_options['rows'], $this->_options['cols'], diff --git a/lib/formslib.php b/lib/formslib.php index 1c06a611842b4..e0e29a4f3e24e 100644 --- a/lib/formslib.php +++ b/lib/formslib.php @@ -562,7 +562,7 @@ function get_new_filename($elname=null) { $draftid = $values[$elname]; $fs = get_file_storage(); $context = get_context_instance(CONTEXT_USER, $USER->id); - if (!$files = $fs->get_area_files($context->id, 'user_draft', $draftid, 'id DESC', false)) { + if (!$files = $fs->get_area_files($context->id, 'user', 'draft', $draftid, 'id DESC', false)) { return false; } $file = reset($files); @@ -612,7 +612,7 @@ function save_file($elname, $pathname, $override=false) { $draftid = $values[$elname]; $fs = get_file_storage(); $context = get_context_instance(CONTEXT_USER, $USER->id); - if (!$files = $fs->get_area_files($context->id, 'user_draft', $draftid, 'id DESC', false)) { + if (!$files = $fs->get_area_files($context->id, 'user', 'draft', $draftid, 'id DESC', false)) { return false; } $file = reset($files); @@ -651,7 +651,7 @@ protected function get_draft_files($elname) { $draftid = $values[$elname]; $fs = get_file_storage(); $context = get_context_instance(CONTEXT_USER, $USER->id); - if (!$files = $fs->get_area_files($context->id, 'user_draft', $draftid, 'id DESC', false)) { + if (!$files = $fs->get_area_files($context->id, 'user', 'draft', $draftid, 'id DESC', false)) { return null; } return $files; @@ -659,33 +659,6 @@ protected function get_draft_files($elname) { return null; } - /** - * Dispose form element draft files - * - * @global object $USER - * @param string $elname name of element - */ - function dispose($elname) { - global $USER; - - if (!$this->is_submitted() or !$this->is_validated()) { - return false; - } - - $element = $this->_form->getElement($elname); - - if ($element instanceof MoodleQuickForm_filepicker || $element instanceof MoodleQuickForm_filemanager) { - $values = $this->_form->exportValues($elname); - if (empty($values[$elname])) { - return false; - } - $draftid = $values[$elname]; - $fs = get_file_storage(); - $context = get_context_instance(CONTEXT_USER, $USER->id); - $fs->delete_area_files($context->id, 'user_draft', $draftid); - } - } - /** * Save file to local filesystem pool * @@ -699,7 +672,7 @@ function dispose($elname) { * @param int $newuserid - new userid if required * @return mixed stored_file object or false if error; may throw exception if duplicate found */ - function save_stored_file($elname, $newcontextid, $newfilearea, $newitemid, $newfilepath='/', + function save_stored_file($elname, $newcontextid, $newcomponent, $newfilearea, $newitemid, $newfilepath='/', $newfilename=null, $overwrite=false, $newuserid=null) { global $USER; @@ -721,7 +694,7 @@ function save_stored_file($elname, $newcontextid, $newfilearea, $newitemid, $new } $draftid = $values[$elname]; $context = get_context_instance(CONTEXT_USER, $USER->id); - if (!$files = $fs->get_area_files($context->id, 'user_draft', $draftid, 'id DESC', false)) { + if (!$files = $fs->get_area_files($context->id, 'user' ,'draft', $draftid, 'id DESC', false)) { return false; } $file = reset($files); @@ -730,14 +703,14 @@ function save_stored_file($elname, $newcontextid, $newfilearea, $newitemid, $new } if ($overwrite) { - if ($oldfile = $fs->get_file($newcontextid, $newfilearea, $newitemid, $newfilepath, $newfilename)) { + if ($oldfile = $fs->get_file($newcontextid, $newcomponent, $newfilearea, $newitemid, $newfilepath, $newfilename)) { if (!$oldfile->delete()) { return false; } } } - $file_record = array('contextid'=>$newcontextid, 'filearea'=>$newfilearea, 'itemid'=>$newitemid, + $file_record = array('contextid'=>$newcontextid, 'component'=>$newcomponent, 'filearea'=>$newfilearea, 'itemid'=>$newitemid, 'filepath'=>$newfilepath, 'filename'=>$newfilename, 'userid'=>$newuserid); return $fs->create_file_from_storedfile($file_record, $file); @@ -745,14 +718,14 @@ function save_stored_file($elname, $newcontextid, $newfilearea, $newitemid, $new $filename = is_null($newfilename) ? $_FILES[$elname]['name'] : $newfilename; if ($overwrite) { - if ($oldfile = $fs->get_file($newcontextid, $newfilearea, $newitemid, $newfilepath, $newfilename)) { + if ($oldfile = $fs->get_file($newcontextid, $newcomponent, $newfilearea, $newitemid, $newfilepath, $newfilename)) { if (!$oldfile->delete()) { return false; } } } - $file_record = array('contextid'=>$newcontextid, 'filearea'=>$newfilearea, 'itemid'=>$newitemid, + $file_record = array('contextid'=>$newcontextid, 'component'=>$newcomponent, 'filearea'=>$newfilearea, 'itemid'=>$newitemid, 'filepath'=>$newfilepath, 'filename'=>$newfilename, 'userid'=>$newuserid); return $fs->create_file_from_pathname($file_record, $_FILES[$elname]['tmp_name']); } @@ -784,7 +757,7 @@ function get_file_content($elname) { $draftid = $values[$elname]; $fs = get_file_storage(); $context = get_context_instance(CONTEXT_USER, $USER->id); - if (!$files = $fs->get_area_files($context->id, 'user_draft', $draftid, 'id DESC', false)) { + if (!$files = $fs->get_area_files($context->id, 'user', 'draft', $draftid, 'id DESC', false)) { return false; } $file = reset($files); diff --git a/lib/grade/grade_outcome.php b/lib/grade/grade_outcome.php index 4c388ca04c736..37cec7fe92db0 100644 --- a/lib/grade/grade_outcome.php +++ b/lib/grade/grade_outcome.php @@ -98,7 +98,7 @@ public function delete($source=null) { if (parent::delete($source)) { $context = get_context_instance(CONTEXT_SYSTEM); $fs = get_file_storage(); - $files = $fs->get_area_files($context->id, 'grade_outcome', $this->id); + $files = $fs->get_area_files($context->id, 'grade', 'outcome', $this->id); foreach ($files as $file) { $file->delete(); } @@ -277,7 +277,7 @@ public function get_description() { $options = new stdClass; $options->noclean = true; $systemcontext = get_context_instance(CONTEXT_SYSTEM); - $description = file_rewrite_pluginfile_urls($this->description, 'pluginfile.php', $systemcontext->id, 'grade_outcome', $this->id); + $description = file_rewrite_pluginfile_urls($this->description, 'pluginfile.php', $systemcontext->id, 'grade', 'outcome', $this->id); return format_text($description, $this->descriptionformat, $options); } diff --git a/lib/grade/grade_scale.php b/lib/grade/grade_scale.php index 268bf9ca7343e..ed524e1ea8179 100644 --- a/lib/grade/grade_scale.php +++ b/lib/grade/grade_scale.php @@ -129,7 +129,7 @@ public function delete($source=null) { if (parent::delete($source)) { $context = get_context_instance(CONTEXT_SYSTEM); $fs = get_file_storage(); - $files = $fs->get_area_files($context->id, 'grade_scale', $this->id); + $files = $fs->get_area_files($context->id, 'grade', 'scale', $this->id); foreach ($files as $file) { $file->delete(); } @@ -314,7 +314,7 @@ public function get_description() { $systemcontext = get_context_instance(CONTEXT_SYSTEM); $options = new stdClass; $options->noclean = true; - $description = file_rewrite_pluginfile_urls($this->description, 'pluginfile.php', $systemcontext->id, 'grade_scale', $this->id); + $description = file_rewrite_pluginfile_urls($this->description, 'pluginfile.php', $systemcontext->id, 'grade', 'scale', $this->id); return format_text($description, $this->descriptionformat, $options); } } diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 15b780ea45ab8..c7b0a759a6000 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -5057,7 +5057,7 @@ function get_file_packer($mimetype='application/zip') { return false; } - require_once("$CFG->libdir/packer/$classname.php"); + require_once("$CFG->libdir/filestorage/$classname.php"); $fp[$mimetype] = new $classname(); return $fp[$mimetype]; @@ -6905,6 +6905,7 @@ function get_core_subsystems() { 'enrol' => 'enrol', 'error' => NULL, 'filepicker' => NULL, + 'files' => 'files', 'filters' => NULL, 'flashdetect' => NULL, 'fonts' => NULL, diff --git a/lib/navigationlib.php b/lib/navigationlib.php index 0e6e2ece616f9..7e5c9ca66e864 100644 --- a/lib/navigationlib.php +++ b/lib/navigationlib.php @@ -2669,7 +2669,7 @@ protected function load_course_settings($forceopen = false) { // Restore to this course if (has_capability('moodle/restore:restorecourse', $coursecontext)) { - $url = new moodle_url('/files/index.php', array('id'=>$course->id, 'wdir'=>'/backupdata')); + $url = new moodle_url('/files/index.php', array('contextid'=>$coursecontext->id, 'itemid'=>0, 'component' => 'backup', 'filearea'=>'course')); $url = null; // Disabled until restore is implemented. MDL-21432 $coursenode->add(get_string('restore'), $url, self::TYPE_SETTING, null, 'restore', new pix_icon('i/restore', '')); } @@ -2707,7 +2707,7 @@ protected function load_course_settings($forceopen = false) { // Manage files if ($course->legacyfiles == 2 and has_capability('moodle/course:managefiles', $coursecontext)) { - $url = new moodle_url('/files/index.php', array('contextid'=>$coursecontext->id, 'itemid'=>0, 'filearea'=>'course_content')); + $url = new moodle_url('/files/index.php', array('contextid'=>$coursecontext->id, 'itemid'=>0, 'component' => 'course', 'filearea'=>'legacy')); $coursenode->add(get_string('files'), $url, self::TYPE_SETTING, null, 'coursefiles', new pix_icon('i/files', '')); } @@ -3327,7 +3327,8 @@ protected function load_front_page_settings($forceopen = false) { // Restore to this course if (has_capability('moodle/restore:restorecourse', $coursecontext)) { - $url = new moodle_url('/files/index.php', array('id'=>$course->id, 'wdir'=>'/backupdata')); + $url = new moodle_url('/files/index.php', array('contextid'=>$coursecontext->id, 'itemid'=>0, 'component' => 'backup', 'filearea'=>'course')); + $url = null; // Disabled until restore is implemented. MDL-21432 $frontpage->add(get_string('restore'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/restore', '')); } @@ -3352,7 +3353,8 @@ protected function load_front_page_settings($forceopen = false) { // Manage files if (has_capability('moodle/course:managefiles', $this->context)) { - $url = new moodle_url('/files/index.php', array('id'=>$course->id)); + //TODO: hide in new installs + $url = new moodle_url('/files/index.php', array('contextid'=>$coursecontext->id, 'itemid'=>0, 'component' => 'course', 'filearea'=>'legacy')); $frontpage->add(get_string('files'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/files', '')); } return $frontpage; diff --git a/lib/outputcomponents.php b/lib/outputcomponents.php index f4626f82140df..05621e45d978f 100644 --- a/lib/outputcomponents.php +++ b/lib/outputcomponents.php @@ -35,144 +35,6 @@ interface renderable { // intentionally empty } -/** - * Data structure representing a area file tree viewer - * - * @copyright 2010 Dongsheng Cai - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @since Moodle 2.0 - */ -class area_file_tree_viewer implements renderable { - public $dir; - public $result; - public $filearea; - /** - * Constructor of area_file_tree_viewer class - * @param int $contextid - * @param string $area, file area - * @param int $itemid - * @param string $urlbase, file serving url base - */ - public function __construct($contextid, $area, $itemid, $urlbase='') { - global $CFG; - $fs = get_file_storage(); - if (empty($urlbase)) { - $this->urlbase = "$CFG->wwwroot/pluginfile.php"; - } else { - $this->urlbase = $urlbase; - } - $this->contextid = $contextid; - $this->filearea = $area; - $this->itemid = $itemid; - $this->dir = $fs->get_area_tree($contextid, $area, $itemid); - $this->tree_view_parser($this->dir); - } - /** - * Pre-process file tree, generate file url - * @param array $dir file tree - */ - public function tree_view_parser($dir) { - if (empty($dir['subdirs']) and empty($dir['files'])) { - return null; - } - foreach ($dir['subdirs'] as $subdir) { - $this->tree_view_parser($subdir); - } - foreach ($dir['files'] as $file) { - $path = '/'.$this->contextid.'/'.$this->filearea.'/'.$this->itemid.$file->get_filepath().$file->get_filename(); - $downloadurl = file_encode_url($this->urlbase, $path, true); - $file->fileurl = $downloadurl; - } - } -} - -/** - * Data structure representing a general moodle file tree viewer - * - * @copyright 2010 Dongsheng Cai - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @since Moodle 2.0 - */ -class moodle_file_tree_viewer implements renderable { - public $tree; - public $path; - private $enabled_fileareas; - /** - * Constructor of moodle_file_tree_viewer class - * @param int $contextid - * @param string $area, file area - * @param int $itemid - * @param string $urlbase, file serving url base - */ - public function __construct($contextid, $filearea, $itemid, $filepath, $options=array()) { - global $CFG, $OUTPUT; - $this->tree = array(); - $browser = get_file_browser(); - $fs = get_file_storage(); - $fileinfo = $browser->get_file_info(get_context_instance_by_id($contextid), $filearea, $itemid, $filepath); - $children = $fileinfo->get_children(); - $parent_info = $fileinfo->get_parent(); - if (!empty($options['enabled_fileareas']) && is_array($options['enabled_fileareas'])) { - $this->enabled_fileareas = $options['enabled_fileareas']; - } else { - unset($this->enabled_fileareas); - } - - $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[] = $fileinfo->get_visible_name(); - - foreach ($children as $child) { - $filedate = $child->get_timemodified(); - $filesize = $child->get_filesize(); - $mimetype = $child->get_mimetype(); - $params = $child->get_params(); - $url = new moodle_url('/files/index.php', $params); - $fileitem = array( - 'params'=>$params, - 'filename'=>$child->get_visible_name(), - 'filedate'=>$filedate ? userdate($filedate) : '', - 'filesize'=>$filesize ? display_size($filesize) : '' - ); - if ($child->is_directory()) { - $fileitem['isdir'] = true; - $fileitem['url'] = $url->out(false); - if (isset($this->enabled_fileareas)) { - if (!in_array($params['filearea'], $this->enabled_fileareas)) { - continue; - } else { - if (!empty($params['itemid'])) { - $itemid = $params['itemid']; - } else { - $itemid = false; - } - $draftfiles = $fs->get_area_files($contextid, $params['filearea'], $itemid, 'id', false); - if (count($draftfiles) == 0) { - continue; - } - } - } - } else { - $fileitem['url'] = $child->get_url(); - } - $this->tree[] = $fileitem; - } - - } -} - /** * Data structure representing a file picker. * @@ -187,7 +49,7 @@ public function __construct(stdClass $options) { require_once($CFG->dirroot. '/repository/lib.php'); $defaults = array( 'accepted_types'=>'*', - 'context'=>$PAGE->context, + 'context'=>$PAGE->context, //TODO: no PAGE in components allowed!! (skodak) 'return_types'=>FILE_INTERNAL, 'env' => 'filepicker', 'client_id' => uniqid(), @@ -206,14 +68,14 @@ public function __construct(stdClass $options) { $fs = get_file_storage(); $usercontext = get_context_instance(CONTEXT_USER, $USER->id); if (empty($options->filename)) { - if ($files = $fs->get_area_files($usercontext->id, 'user_draft', $options->itemid, 'id DESC', false)) { + if ($files = $fs->get_area_files($usercontext->id, 'user', 'draft', $options->itemid, 'id DESC', false)) { $file = reset($files); } } else { - $file = $fs->get_file($usercontext->id, 'user_draft', $options->itemid, $options->filepath, $options->filename); + $file = $fs->get_file($usercontext->id, 'user', 'draft', $options->itemid, $options->filepath, $options->filename); } if (!empty($file)) { - $options->currentfile = html_writer::link(file_encode_url($CFG->wwwroot.'/draftfile.php/', $usercontext->id.'/user_draft/'.$file->get_itemid().'/'.$file->get_filename()), $file->get_filename()); + $options->currentfile = html_writer::link(file_draftfile_url($file->get_itemid(), $file->get_filename(), $file->get_filename()), $file->get_filename()); } } @@ -227,63 +89,6 @@ public function __construct(stdClass $options) { } } -/** - * Data structure representing a file manager. - * - * @copyright 2010 Dongsheng Cai - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @since Moodle 2.0 - */ -class file_manager implements renderable { - public $options; - public function __construct(stdClass $options) { - global $CFG, $USER, $PAGE; - require_once($CFG->dirroot. '/repository/lib.php'); - $defaults = array( - 'maxbytes'=>-1, - 'maxfiles'=>-1, - 'filearea'=>'user_draft', - 'itemid'=>0, - 'subdirs'=>0, - 'client_id'=>uniqid(), - 'accepted_types'=>'*', - 'return_types'=>FILE_INTERNAL, - 'context'=>$PAGE->context - ); - foreach ($defaults as $key=>$value) { - if (empty($options->$key)) { - $options->$key = $value; - } - } - - $fs = get_file_storage(); - - // initilise options, getting files in root path - $this->options = file_get_user_area_files($options->itemid, '/', $options->filearea); - - // calculate file count - $usercontext = get_context_instance(CONTEXT_USER, $USER->id); - $files = $fs->get_area_files($usercontext->id, $options->filearea, $options->itemid, 'id', false); - $filecount = count($files); - $this->options->filecount = $filecount; - - // copying other options - foreach ($options as $name=>$value) { - $this->options->$name = $value; - } - - // building file picker options - $params = new stdclass; - $params->accepted_types = $options->accepted_types; - $params->return_types = $options->return_types; - $params->context = $options->context; - $params->env = 'filemanager'; - $params->disable_types = !empty($options->disable_types)?$options->disable_types:array(); - $filepicker_options = initialise_filepicker($params); - $this->options->filepicker = $filepicker_options; - } -} - /** * Data structure representing a user picture. * diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php index 89b7c7f392a7a..1a3c7a7f408e3 100644 --- a/lib/outputrenderers.php +++ b/lib/outputrenderers.php @@ -1769,88 +1769,6 @@ protected function render_user_picture(user_picture $userpicture) { return html_writer::tag('a', $output, $attributes); } - - /** - * General moodle file tree viwer - * - *
-     * $OUTPUT->moodle_file_tree_viewer($contextid, $filearea, $itemid, $filepath);
-     * 
- * - * @param int $contextid - * @param string $area - * @param int $itemid - * @param string $filepath - * @return string HTML fragment - */ - public function moodle_file_tree_viewer($contextid, $filearea, $itemid, $filepath, $options = array()) { - $tree = new moodle_file_tree_viewer($contextid, $filearea, $itemid, $filepath, $options); - return $this->render($tree); - } - public function render_moodle_file_tree_viewer(moodle_file_tree_viewer $tree) { - $html = '
'; - foreach($tree->path as $path) { - $html .= $path; - $html .= ' / '; - } - $html .= '
'; - - $html .= '
'; - if (empty($tree->tree)) { - $html .= get_string('nofilesavailable', 'repository'); - } else { - $this->page->requires->js_init_call('M.core_filetree.init'); - $html .= '
    '; - foreach($tree->tree as $node) { - $link_attributes = array(); - if (!empty($node['isdir'])) { - $class = ' class="file-tree-folder"'; - } else { - $class = ' class="file-tree-file"'; - $link_attributes['target'] = '_blank'; - } - $html .= '
  • '; - $html .= html_writer::link($node['url'], $node['filename'], $link_attributes); - $html .= '
  • '; - } - $html .= '
'; - } - $html .= '
'; - return $html; - } - - /** - * Print the area file tree viewer - * - *
-     * $OUTPUT->area_file_tree_viewer($contextid, $filearea, $itemid, $urlbase);
-     * 
- * - * @param int $contextid - * @param string $area - * @param int $itemid - * @param string $urlbase - * @return string HTML fragment - */ - public function area_file_tree_viewer($contextid, $area, $itemid, $urlbase='') { - $tree = new area_file_tree_viewer($contextid, $area, $itemid, $urlbase); - return $this->render($tree); - } - - /** - * Internal implementation of area file tree viewer rendering. - * @param area_file_tree_viewer $tree - * @return string - */ - public function render_area_file_tree_viewer(area_file_tree_viewer $tree) { - $this->page->requires->js_init_call('M.mod_folder.init_tree', array(true)); - $html = ''; - $html .= '
'; - $html .= $this->htmllize_file_tree($tree->dir); - $html .= '
'; - return $html; - } - /** * Internal implementation of file tree viewer items rendering. * @param array $dir @@ -1929,135 +1847,6 @@ public function render_file_picker(file_picker $fp) { return $html; } - /** - * Print the file manager - * - *
-     * $OUTPUT->file_manager($options);
-     * 
- * - * @param array $options associative array with file manager options - * options are: - * maxbytes=>-1, - * maxfiles=>-1, - * filearea=>'user_draft', - * itemid=>0, - * subdirs=>false, - * client_id=>uniqid(), - * acepted_types=>'*', - * return_types=>FILE_INTERNAL, - * context=>$PAGE->context - * @return string HTML fragment - */ - public function file_manager($options) { - $fm = new file_manager($options); - return $this->render($fm); - } - - /** - * Internal implementation of file manager rendering. - * @param file_manager $fm - * @return string - */ - public function render_file_manager(file_manager $fm) { - global $CFG, $OUTPUT; - static $filemanagertemplateloaded; - $html = ''; - $nonjsfilemanager = optional_param('usenonjsfilemanager', 0, PARAM_INT); - $options = $fm->options; - $options->usenonjs = $nonjsfilemanager; - $straddfile = get_string('add', 'repository') . '...'; - $strmakedir = get_string('makeafolder', 'moodle'); - $strdownload = get_string('downloadfolder', 'repository'); - $strloading = get_string('loading', 'repository'); - - $icon_add_file = $OUTPUT->pix_icon('t/addfile', $straddfile).''; - $icon_add_folder = $OUTPUT->pix_icon('t/adddir', $strmakedir).''; - $icon_download = $OUTPUT->pix_icon('t/download', $strdownload).''; - $icon_progress = $OUTPUT->pix_icon('i/loading_small', $strloading).''; - - $client_id = $options->client_id; - $itemid = $options->itemid; - $filearea = $options->filearea; - - if (empty($options->filecount)) { - $extra = ' style="display:none"'; - } else { - $extra = ''; - } - - $html .= << -$icon_progress -
- -
-FMHTML; - if (empty($filemanagertemplateloaded)) { - $filemanagertemplateloaded = true; - $html .= <<
-FMHTML; - } - - $filemanagerurl = new moodle_url('/repository/filepicker.php', array( - 'filearea'=>$filearea, - 'env'=>'filemanager', - 'action'=>'embedded', - 'itemid'=>$itemid, - 'subdirs'=>'/', - 'maxbytes'=>$options->maxbytes, - 'ctx_id'=>$this->page->context->id, - 'course'=>$this->page->course->id, - )); - - $module = array( - 'name'=>'form_filemanager', - 'fullpath'=>'/lib/form/filemanager.js', - 'requires' => array('core_filepicker', 'base', 'io', 'node', 'json', 'yui2-button', 'yui2-container', 'yui2-layout', 'yui2-menu', 'yui2-treeview'), - 'strings' => array(array('loading', 'repository'), array('nomorefiles', 'repository'), array('confirmdeletefile', 'repository'), - array('add', 'repository'), array('accessiblefilepicker', 'repository'), array('move', 'moodle'), - array('cancel', 'moodle'), array('download', 'moodle'), array('ok', 'moodle'), - array('emptylist', 'repository'), array('nofilesattached', 'repository'), array('entername', 'repository'), array('enternewname', 'repository'), - array('zip', 'editor'), array('unzip', 'moodle'), array('rename', 'moodle'), array('delete', 'moodle'), - array('cannotdeletefile', 'error'), array('confirmdeletefile', 'repository'), - array('nopathselected', 'repository'), array('popupblockeddownload', 'repository'), - array('draftareanofiles', 'repository'), array('path', 'moodle'), array('setmainfile', 'repository') - ) - ); - $this->page->requires->js_module($module); - $this->page->requires->js_init_call('M.form_filemanager.init', array($options), true, $module); - - // non javascript file manager - if (!empty($nonjsfilemanager)) { - $html = '
'; - $html .= <<Error -NONJS; - $html .= '
'; - } else { - $url = new moodle_url($this->page->url, array('usenonjsfilemanager'=>1)); - $html .= '
'; - $html .= html_writer::link($url, get_string('usenonjsfilemanager', 'repository')); - $html .= '
'; - } - - - return $html; - } - /** * Prints the 'Update this Modulename' button that appears on module pages. * diff --git a/lib/portfolio/caller.php b/lib/portfolio/caller.php index b5e25ece64167..d5e4d80f25857 100644 --- a/lib/portfolio/caller.php +++ b/lib/portfolio/caller.php @@ -376,6 +376,7 @@ public abstract function load_data(); * - array of file ids or stored_file objects * - null * @param int $contextid (optional), passed to {@link see file_storage::get_area_files} + * @param string $component (optional), passed to {@link see file_storage::get_area_files} * @param string $filearea (optional), passed to {@link see file_storage::get_area_files} * @param int $itemid (optional), passed to {@link see file_storage::get_area_files} * @param string $sort (optional), passed to {@link see file_storage::get_area_files} @@ -401,7 +402,7 @@ public function set_file_and_format_data($ids=null /* ..pass arguments to area f } } } else if (count($args) != 0) { - if (count($args) < 3) { + if (count($args) < 4) { throw new portfolio_caller_exception('invalidfileareaargs', 'portfolio'); } $files = array_values(call_user_func_array(array($fs, 'get_area_files'), $args)); diff --git a/lib/portfolio/exporter.php b/lib/portfolio/exporter.php index 5502306f3bf75..046d9b6968628 100644 --- a/lib/portfolio/exporter.php +++ b/lib/portfolio/exporter.php @@ -493,7 +493,7 @@ public function process_stage_cleanup($pullok=false) { } $DB->delete_records('portfolio_tempdata', array('id' => $this->id)); $fs = get_file_storage(); - $fs->delete_area_files(SYSCONTEXTID, 'portfolio_exporter', $this->id); + $fs->delete_area_files(SYSCONTEXTID, 'portfolio', 'exporter', $this->id); $this->deleted = true; return true; } @@ -805,7 +805,7 @@ public function zip_tempfiles($filename='portfolio-export.zip', $filepath='/fina */ public function get_tempfiles($skipfile='portfolio-export.zip') { $fs = get_file_storage(); - $files = $fs->get_area_files(SYSCONTEXTID, 'portfolio_exporter', $this->id, '', false); + $files = $fs->get_area_files(SYSCONTEXTID, 'portfolio', 'exporter', $this->id, '', false); if (empty($files)) { return array(); } @@ -831,8 +831,9 @@ public function get_tempfiles($skipfile='portfolio-export.zip') { public function get_base_filearea() { return array( 'contextid' => SYSCONTEXTID, - 'filearea' => 'portfolio_exporter', - 'itemid' => $this->id, + 'component' => 'portfolio', + 'filearea' => 'exporter', + 'itemid' => $this->id, ); } diff --git a/lib/portfoliolib.php b/lib/portfoliolib.php index c0f2aac73fdad..8cd9e9bc7b5a3 100644 --- a/lib/portfoliolib.php +++ b/lib/portfoliolib.php @@ -1181,7 +1181,7 @@ function portfolio_existing_exports_by_plugin($userid) { * callback function from {@link portfolio_rewrite_pluginfile_urls} * looks through preg_replace matches and replaces content with whatever the active portfolio export format says */ -function portfolio_rewrite_pluginfile_url_callback($contextid, $filearea, $itemid, $format, $options, $matches) { +function portfolio_rewrite_pluginfile_url_callback($contextid, $component, $filearea, $itemid, $format, $options, $matches) { $matches = $matches[0]; // no internal matching $dom = new DomDocument(); if (!$dom->loadXML($matches)) { @@ -1208,8 +1208,8 @@ function portfolio_rewrite_pluginfile_url_callback($contextid, $filearea, $item $filename = array_pop($bits); $filepath = implode('/', $bits); } - if (!$file = $fs->get_file($contextid, $filearea, $itemid, $filepath, $filename)) { - debugging("Couldn\t find a file from the embedded path info context $contextid filearea $filearea itemid $itemid filepath $filepath name $filename"); + if (!$file = $fs->get_file($contextid, $component, $filearea, $itemid, $filepath, $filename)) { + debugging("Couldn\t find a file from the embedded path info context $contextid component $component filearea $filearea itemid $itemid filepath $filepath name $filename"); return $matches; } if (empty($options)) { @@ -1227,6 +1227,7 @@ function portfolio_rewrite_pluginfile_url_callback($contextid, $filearea, $item * * @param string $text the text to search through * @param int $contextid normal file_area arguments + * @param string $component * @param string $filearea normal file_area arguments * @param int $itemid normal file_area arguments * @param portfolio_format $format the portfolio export format @@ -1234,9 +1235,9 @@ function portfolio_rewrite_pluginfile_url_callback($contextid, $filearea, $item * * @return string */ -function portfolio_rewrite_pluginfile_urls($text, $contextid, $filearea, $itemid, $format, $options=null) { +function portfolio_rewrite_pluginfile_urls($text, $contextid, $component, $filearea, $itemid, $format, $options=null) { $pattern = '/(<[^<]*?="@@PLUGINFILE@@\/[^>]*?(?:\/>|>.*?<\/[^>]*?>))/'; - $callback = partial('portfolio_rewrite_pluginfile_url_callback', $contextid, $filearea, $itemid, $format, $options); + $callback = partial('portfolio_rewrite_pluginfile_url_callback', $contextid, $component, $filearea, $itemid, $format, $options); return preg_replace_callback($pattern, $callback, $text); } // this function has to go last, because the regexp screws up syntax highlighting in some editors diff --git a/lib/resourcelib.php b/lib/resourcelib.php index 3f21d96c055e3..264196f6e068c 100644 --- a/lib/resourcelib.php +++ b/lib/resourcelib.php @@ -51,11 +51,12 @@ * @param string $filepath old file path * @param int $cmid migrated course module if * @param int $courseid + * @param string $component * @param string $filearea new file area * @param int $itemid migrated file item id * @return mixed, false if not found, stored_file instance if migrated to new area */ -function resourcelib_try_file_migration($filepath, $cmid, $courseid, $filearea, $itemid) { +function resourcelib_try_file_migration($filepath, $cmid, $courseid, $component, $filearea, $itemid) { $fs = get_file_storage(); if (stripos($filepath, '/backupdata/') === 0 or stripos($filepath, '/moddata/') === 0) { @@ -70,13 +71,13 @@ function resourcelib_try_file_migration($filepath, $cmid, $courseid, $filearea, return false; } - $pathnamehash = sha1($coursecontext->id.'course_content0'.$filepath); + $pathnamehash = sha1("/$coursecontext->id/course/legacy/0".$filepath); if (!$file = $fs->get_file_by_hash($pathnamehash)) { return false; } // copy and keep the same path, name, etc. - $file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>$itemid); + $file_record = array('contextid'=>$context->id, 'component'=>$component, 'filearea'=>$filearea, 'itemid'=>$itemid); try { return $fs->create_file_from_storedfile($file_record, $file); } catch (Exception $e) { diff --git a/lib/setuplib.php b/lib/setuplib.php index 1bc9d3fdc1194..1b0cbb39de8cc 100644 --- a/lib/setuplib.php +++ b/lib/setuplib.php @@ -800,7 +800,7 @@ function get_real_size($size=0) { */ function redirect_if_major_upgrade_required() { global $CFG; - $lastmajordbchanges = 2010061600; + $lastmajordbchanges = 2010070300; if (empty($CFG->version) or (int)$CFG->version < $lastmajordbchanges or during_initial_install() or !empty($CFG->adminsetuppending)) { try { diff --git a/lib/simpletest/broken_testfilelib.php b/lib/simpletest/broken_testfilelib.php index ea25b91cd543d..f1ae83b1c1de2 100644 --- a/lib/simpletest/broken_testfilelib.php +++ b/lib/simpletest/broken_testfilelib.php @@ -28,8 +28,6 @@ } require_once($CFG->libdir.'/filelib.php'); -require_once($CFG->libdir.'/file/file_browser.php'); -require_once($CFG->libdir.'/file/file_info_course.php'); require_once($CFG->dirroot.'/user/lib.php'); require_once($CFG->dirroot.'/mod/forum/lib.php'); @@ -259,19 +257,19 @@ public function test_encodepath() { } } -class test_file_info_system extends filelib_test { +class test_file_info_context_system extends filelib_test { public function test_get_children() { $context = get_context_instance(CONTEXT_SYSTEM); - $fis = new file_info_system(new file_browser(), $context); + $fis = new file_info_context_system(new file_browser(), $context); $children = $fis->get_children(); $found_coursecat = false; $context_coursecat = get_context_instance(CONTEXT_COURSECAT, $this->coursecat->id); - $file_info_coursecat = new file_info_coursecat(new file_browser(), $context_coursecat, $this->coursecat); + $file_info_context_coursecat = new file_info_context_coursecat(new file_browser(), $context_coursecat, $this->coursecat); foreach ($children as $child) { - if ($child == $file_info_coursecat) { + if ($child == $file_info_context_coursecat) { $found_coursecat = true; } } @@ -279,13 +277,13 @@ public function test_get_children() { } } -class test_file_info_coursecat extends filelib_test { +class test_file_info_context_coursecat extends filelib_test { private $fileinfo; public function setup() { parent::setup(); $context = get_context_instance(CONTEXT_COURSECAT, $this->coursecat->id); - $this->fileinfo = new file_info_coursecat(new file_browser(), $context, $this->coursecat); + $this->fileinfo = new file_info_context_coursecat(new file_browser(), $context, $this->coursecat); } public function test_get_children() { @@ -298,25 +296,25 @@ public function test_get_children() { $this->assertEqual('file_info_stored', get_class($children[0])); $context_course = get_context_instance(CONTEXT_COURSE, $this->course->id); - $fic = new file_info_course(new file_browser(), $context_course, $this->course); + $fic = new file_info_context_course(new file_browser(), $context_course, $this->course); $this->assertEqual($fic, $children[1]); } public function test_get_parent() { $context = get_context_instance(CONTEXT_SYSTEM); - $fis = new file_info_system(new file_browser(), $context); + $fis = new file_info_context_system(new file_browser(), $context); $parent = $this->fileinfo->get_parent(); $this->assertEqual($parent, $fis); } } -class test_file_info_course extends filelib_test { +class test_file_info_context_course extends filelib_test { private $fileinfo; public function setup() { parent::setup(); $context = get_context_instance(CONTEXT_COURSE, $this->course->id); - $this->fileinfo = new file_info_course(new file_browser(), $context, $this->course); + $this->fileinfo = new file_info_context_course(new file_browser(), $context, $this->course); } public function test_get_children() { @@ -330,7 +328,7 @@ public function test_get_children() { $this->assertEqual('file_info_stored', get_class($children[0])); $context_course = get_context_instance(CONTEXT_COURSE, $this->course->id); - $fics = new file_info_coursesection(new file_browser(), $context_course, $this->course); + $fics = new file_info_area_course_section(new file_browser(), $context_course, $this->course); $this->assertEqual($fics, $children[1]); $this->assertEqual('Backups', $children[2]->get_visible_name()); @@ -339,30 +337,30 @@ public function test_get_children() { $this->assertEqual('Course files', $children[3]->get_visible_name()); $this->assertEqual('', $children[3]->get_url()); - $this->assertEqual('file_info_coursefile', get_class($children[3])); + $this->assertEqual('file_info_area_course_legacy', get_class($children[3])); } public function test_get_parent() { $context = get_context_instance(CONTEXT_COURSECAT, $this->coursecat->id); - $fic = new file_info_coursecat(new file_browser(), $context, $this->coursecat); + $fic = new file_info_context_coursecat(new file_browser(), $context, $this->coursecat); $parent = $this->fileinfo->get_parent(); $this->assertEqual($parent, $fic); } } -class test_file_info_user extends filelib_test { +class test_file_info_context_user extends filelib_test { private $fileinfo; public function setup() { parent::setup(); $context = get_context_instance(CONTEXT_USER, $this->user->id); - $this->fileinfo = new file_info_user(new file_browser(), $context, $this->user); + $this->fileinfo = new file_info_context_user(new file_browser(), $context, $this->user); } public function test_get_parent() { $context = get_context_instance(CONTEXT_SYSTEM); - $fic = new file_info_system(new file_browser(), $context); + $fic = new file_info_context_system(new file_browser(), $context); $parent = $this->fileinfo->get_parent(); $this->assertEqual($parent, $fic); } @@ -381,19 +379,19 @@ public function test_get_children() { } } -class test_file_info_module extends filelib_test { +class test_file_info_context_module extends filelib_test { private $fileinfo; public function setup() { global $DB; parent::setup(); $context = get_context_instance(CONTEXT_MODULE, $DB->get_field('course_modules', 'id', array('instance' => $this->module->instance))); - $this->fileinfo = new file_info_module(new file_browser(), $this->course, $this->module->instance, $context, array()); + $this->fileinfo = new file_info_context_module(new file_browser(), $this->course, $this->module->instance, $context, array()); } public function test_get_parent() { $context = get_context_instance(CONTEXT_COURSE, $this->course->id); - $fic = new file_info_course(new file_browser(), $context, $this->course); + $fic = new file_info_context_course(new file_browser(), $context, $this->course); $parent = $this->fileinfo->get_parent(); $this->assertEqual($parent, $fic); } diff --git a/lib/weblib.php b/lib/weblib.php index 7ba7170e8d8b8..7d312b476d2e6 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -701,7 +701,7 @@ public static function make_draftfile_url($itemid, $pathname, $filename, $forced $urlbase = "$CFG->httpswwwroot/draftfile.php"; $context = get_context_instance(CONTEXT_USER, $USER->id); - return self::make_file_url($urlbase, '/'.$context->id.'/user_draft/'.$itemid.$pathname.$filename, $forcedownload); + return self::make_file_url($urlbase, '/'.$context->id.'/user/draft/'.$itemid.$pathname.$filename, $forcedownload); } /** @@ -1356,7 +1356,7 @@ function format_module_intro($module, $activity, $cmid, $filter=true) { require_once("$CFG->libdir/filelib.php"); $options = (object)array('noclean'=>true, 'para'=>false, 'filter'=>false); $context = get_context_instance(CONTEXT_MODULE, $cmid); - $intro = file_rewrite_pluginfile_urls($activity->intro, 'pluginfile.php', $context->id, $module.'_intro', null); + $intro = file_rewrite_pluginfile_urls($activity->intro, 'pluginfile.php', $context->id, 'mod_'.$module, 'intro', null); return trim(format_text($intro, $activity->introformat, $options)); } diff --git a/mod/assignment/backup/moodle2/backup_assignment_stepslib.php b/mod/assignment/backup/moodle2/backup_assignment_stepslib.php index 9bcb3c52dca3c..f7ec8f874e166 100644 --- a/mod/assignment/backup/moodle2/backup_assignment_stepslib.php +++ b/mod/assignment/backup/moodle2/backup_assignment_stepslib.php @@ -77,8 +77,8 @@ protected function define_structure() { $submission->annotate_ids('user', 'teacher'); // Define file annotations - $assignment->annotate_files(array('assignment_intro'), null); // This file area hasn't itemid - $submission->annotate_files(array('assignment_submission'), 'id'); + $assignment->annotate_files('mod_assignment', 'intro', null); // This file area hasn't itemid + $submission->annotate_files('mod_assignment', 'submission', 'id'); // Return the root element (assignment), wrapped into standard activity structure return $this->prepare_activity_structure($assignment); diff --git a/mod/assignment/db/upgrade.php b/mod/assignment/db/upgrade.php index 6d2046a5534a6..f8f6da1f15be1 100644 --- a/mod/assignment/db/upgrade.php +++ b/mod/assignment/db/upgrade.php @@ -69,7 +69,6 @@ function xmldb_assignment_upgrade($oldversion) { // migrate submitted files first $path = $basepath; - $filearea = 'assignment_submission'; $items = new DirectoryIterator($path); foreach ($items as $item) { if (!$item->isFile()) { @@ -83,8 +82,8 @@ function xmldb_assignment_upgrade($oldversion) { if ($filename === '') { continue; } - if (!$fs->file_exists($context->id, $filearea, $submission->id, '/', $filename)) { - $file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>$submission->id, 'filepath'=>'/', 'filename'=>$filename, 'userid'=>$submission->userid); + if (!$fs->file_exists($context->id, 'mod_assignment', 'submission', $submission->id, '/', $filename)) { + $file_record = array('contextid'=>$context->id, 'component'=>'mod_assignment', 'filearea'=>'submission', 'itemid'=>$submission->id, 'filepath'=>'/', 'filename'=>$filename, 'userid'=>$submission->userid); if ($fs->create_file_from_pathname($file_record, $path.$item->getFilename())) { unlink($path.$item->getFilename()); } @@ -92,10 +91,9 @@ function xmldb_assignment_upgrade($oldversion) { } unset($items); //release file handles - // migrate teacher response files + // migrate teacher response files for "upload" subtype, unfortunately we do not $path = $basepath.'responses/'; if (file_exists($path)) { - $filearea = 'assignment_response'; $items = new DirectoryIterator($path); foreach ($items as $item) { if (!$item->isFile()) { @@ -105,8 +103,8 @@ function xmldb_assignment_upgrade($oldversion) { if ($filename === '') { continue; } - if (!$fs->file_exists($context->id, $filearea, $submission->id, '/', $filename)) { - $file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>$submission->id, 'filepath'=>'/', 'filename'=>$filename, + if (!$fs->file_exists($context->id, 'mod_assignment', 'response', $submission->id, '/', $filename)) { + $file_record = array('contextid'=>$context->id, 'component'=>'mod_assignment', 'filearea'=>'response', 'itemid'=>$submission->id, 'filepath'=>'/', 'filename'=>$filename, 'timecreated'=>$item->getCTime(), 'timemodified'=>$item->getMTime()); if ($submission->teacher) { $file_record['userid'] = $submission->teacher; diff --git a/mod/assignment/lib.php b/mod/assignment/lib.php index 581fe0b567d2e..3b24714f440b9 100644 --- a/mod/assignment/lib.php +++ b/mod/assignment/lib.php @@ -262,7 +262,7 @@ function view_feedback($submission=NULL) { global $USER, $CFG, $DB, $OUTPUT; require_once($CFG->libdir.'/gradelib.php'); - if (!has_capability('mod/assignment:submit', $this->context, $USER->id, false)) { + if (!is_enrolled($this->context, $USER, 'mod/assignment:submit')) { // can not submit assignments -> no feedback return; } @@ -903,7 +903,7 @@ function display_submission($offset=-1,$userid =-1) { /// Get all ppl that can submit assignments $currentgroup = groups_get_activity_group($cm); - if ($users = get_users_by_capability($context, 'mod/assignment:submit', 'u.id', '', '', '', $currentgroup, '', false)) { + if ($users = get_enrolled_users($context, 'mod/assignment:submit', $currentgroup, 'u.id')) { $users = array_keys($users); } @@ -1094,7 +1094,7 @@ function display_submissions($message='') { groups_print_activity_menu($cm, $CFG->wwwroot . '/mod/assignment/submissions.php?id=' . $this->cm->id); /// Get all ppl that are allowed to submit assignments - if ($users = get_users_by_capability($context, 'mod/assignment:submit', 'u.id', '', '', '', $currentgroup, '', false)) { + if ($users = get_enrolled_users($context, 'mod/assignment:submit', $currentgroup, 'u.id')) { $users = array_keys($users); } @@ -1165,7 +1165,7 @@ function display_submissions($message='') { echo ''; return true; } - if ($this->assignment->assignmenttype=='upload' || $this->assignment->assignmenttype=='online' || $this->assignment->assignmenttype=='uploadsingle') { + if ($this->assignment->assignmenttype=='upload' || $this->assignment->assignmenttype=='online' || $this->assignment->assignmenttype=='uploadsingle') { //TODO: this is an ugly hack, where is the plugin spirit? (skodak) echo '
'.get_string('downloadall', 'assignment').'
'; } /// Construct the SQL @@ -1727,11 +1727,10 @@ function print_user_files($userid=0, $return=false) { $output = ''; $fs = get_file_storage(); - $browser = get_file_browser(); $found = false; - if ($files = $fs->get_area_files($this->context->id, 'assignment_submission', $userid, "timemodified", false)) { + if ($files = $fs->get_area_files($this->context->id, 'mod_assignment', 'submission', $userid, "timemodified", false)) { require_once($CFG->libdir.'/portfoliolib.php'); require_once($CFG->dirroot . '/mod/assignment/locallib.php'); $button = new portfolio_add_button(); @@ -1739,7 +1738,7 @@ function print_user_files($userid=0, $return=false) { $filename = $file->get_filename(); $found = true; $mimetype = $file->get_mimetype(); - $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_submission/'.$userid.'/'.$filename); + $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/mod_assignment/submission/'.$userid.'/'.$filename); $output .= ''.$mimetype.''.s($filename).''; if ($this->portfolio_exportable() && has_capability('mod/assignment:exportownsubmission', $this->context)) { $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id, 'fileid' => $file->get_id()), '/mod/assignment/locallib.php'); @@ -1769,7 +1768,7 @@ function print_user_files($userid=0, $return=false) { */ function count_user_files($userid) { $fs = get_file_storage(); - $files = $fs->get_area_files($this->context->id, 'assignment_submission', $userid, "id", false); + $files = $fs->get_area_files($this->context->id, 'mod_assignment', 'submission', $userid, "id", false); return count($files); } @@ -1837,9 +1836,8 @@ function user_complete($user, $grade=null) { if ($submission = $this->get_submission($user->id)) { $fs = get_file_storage(); - $browser = get_file_browser(); - if ($files = $fs->get_area_files($this->context->id, 'assignment_submission', $user->id, "timemodified", false)) { + if ($files = $fs->get_area_files($this->context->id, 'mod_assignment', 'submission', $user->id, "timemodified", false)) { $countfiles = count($files)." ".get_string("uploadedfiles", "assignment"); foreach ($files as $file) { $countfiles .= "; ".$file->get_filename(); @@ -1946,8 +1944,8 @@ function reset_userdata($data) { continue; } $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $fs->delete_area_files($context->id, 'assignment_submission'); - $fs->delete_area_files($context->id, 'assignment_response'); + $fs->delete_area_files($context->id, 'mod_assignment', 'submission'); + $fs->delete_area_files($context->id, 'mod_assignment', 'response'); } } @@ -2067,7 +2065,7 @@ function definition() { } -class mod_assignment_online_grading_form extends moodleform { +class mod_assignment_online_grading_form extends moodleform { // TODO: why "online" in the name of this class? (skodak) function definition() { global $OUTPUT; @@ -2224,9 +2222,10 @@ function add_submission_content() { protected function get_editor_options() { $editoroptions = array(); - $editoroptions['filearea'] = 'assignment_online_submission'; + $editoroptions['component'] = 'mod_assignment'; + $editoroptions['filearea'] = 'feedback'; $editoroptions['noclean'] = false; - $editoroptions['maxfiles'] = 0; //TODO: no files for now, we need to first implement assignment_feedback area + $editoroptions['maxfiles'] = 0; //TODO: no files for now, we need to first implement assignment_feedback area, integration with gradebook, files support in quickgrading, etc. (skodak) $editoroptions['maxbytes'] = $this->_customdata->maxbytes; return $editoroptions; } @@ -2248,7 +2247,7 @@ public function set_data($data) { $itemid = null; } - $data = file_prepare_standard_editor($data, 'submissioncomment', $editoroptions, $this->_customdata->context, $editoroptions['filearea'], $itemid); + $data = file_prepare_standard_editor($data, 'submissioncomment', $editoroptions, $this->_customdata->context, $editoroptions['component'], $editoroptions['filearea'], $itemid); return parent::set_data($data); } @@ -2258,12 +2257,12 @@ public function get_data() { if (!empty($this->_customdata->submission->id)) { $itemid = $this->_customdata->submission->id; } else { - $itemid = null; + $itemid = null; //TODO: this is wrong, itemid MUST be known when saving files!! (skodak) } if ($data) { $editoroptions = $this->get_editor_options(); - $data = file_postupdate_standard_editor($data, 'submissioncomment', $editoroptions, $this->_customdata->context, $editoroptions['filearea'], $itemid); + $data = file_postupdate_standard_editor($data, 'submissioncomment', $editoroptions, $this->_customdata->context, $editoroptions['component'], $editoroptions['filearea'], $itemid); $data->format = $data->textformat; } return $data; @@ -2665,28 +2664,29 @@ function assignment_get_participants($assignmentid) { } /** - * Serves assingment submissions and otehr files. + * Serves assignment submissions and other files. * * @param object $course - * @param object $cminfo + * @param object $cm * @param object $context * @param string $filearea * @param array $args * @param bool $forcedownload - * @return bool false if file not found, does not return if found - justsend the file + * @return bool false if file not found, does not return if found - just send the file */ -function assignment_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) { +function assignment_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG, $DB; - if (!$assignment = $DB->get_record('assignment', array('id'=>$cminfo->instance))) { - return false; - } - if (!$cm = get_coursemodule_from_instance('assignment', $assignment->id, $course->id)) { + if ($context->contextlevel != CONTEXT_MODULE) { return false; } require_login($course, false, $cm); + if (!$assignment = $DB->get_record('assignment', array('id'=>$cm->instance))) { + return false; + } + require_once($CFG->dirroot.'/mod/assignment/type/'.$assignment->assignmenttype.'/assignment.class.php'); $assignmentclass = 'assignment_'.$assignment->assignmenttype; $assignmentinstance = new $assignmentclass($cm->id, $assignment, $cm, $course); @@ -3096,7 +3096,7 @@ function assignment_count_real_submissions($cm, $groupid=0) { $context = get_context_instance(CONTEXT_MODULE, $cm->id); // this is all the users with this capability set, in this context or higher - if ($users = get_users_by_capability($context, 'mod/assignment:submit', 'u.id', '', '', '', $groupid, '', false)) { + if ($users = get_enrolled_users($context, 'mod/assignment:submit', $groupid, 'u.id')) { $users = array_keys($users); } @@ -3303,7 +3303,7 @@ function assignment_print_overview($courses, &$htmlarray) { // count how many people can submit $submissions = 0; // init - if ($students = get_users_by_capability($context, 'mod/assignment:submit', 'u.id', '', '', '', 0, '', false)) { + if ($users = get_enrolled_users($context, 'mod/assignment:submit', 0, 'u.id')) { foreach ($students as $student) { if (isset($unmarkedsubmissions[$assignment->id][$student->id])) { $submissions++; @@ -3586,7 +3586,7 @@ function assignment_create_temp_dir($dir, $prefix='', $mode=0700) { function assignment_get_file_areas($course, $cm, $context) { $areas = array(); if (has_capability('moodle/course:managefiles', $context)) { - $areas['assignment_submission'] = get_string('assignmentsubmission', 'assignment'); + $areas['submission'] = get_string('assignmentsubmission', 'assignment'); } return $areas; } diff --git a/mod/assignment/locallib.php b/mod/assignment/locallib.php index 9d234a5a0a25f..4362f4489c026 100644 --- a/mod/assignment/locallib.php +++ b/mod/assignment/locallib.php @@ -73,7 +73,7 @@ public function load_data() { if (is_callable(array($this->assignment, 'portfolio_load_data'))) { return $this->assignment->portfolio_load_data($this); } - $this->set_file_and_format_data($this->fileid, $this->assignment->context->id, 'assignment_submission', $this->user->id, 'timemodified', false); + $this->set_file_and_format_data($this->fileid, $this->assignment->context->id, 'mod_assignment', 'submission', $this->user->id, 'timemodified', false); } public function prepare_package() { diff --git a/mod/assignment/type/online/assignment.class.php b/mod/assignment/type/online/assignment.class.php index 7fee30b35416c..41cb9c950d370 100644 --- a/mod/assignment/type/online/assignment.class.php +++ b/mod/assignment/type/online/assignment.class.php @@ -25,7 +25,7 @@ function view() { $submission = $this->get_submission($USER->id, false); //Guest can not submit nor edit an assignment (bug: 4604) - if (!has_capability('mod/assignment:submit', $context)) { + if (!is_enrolled($this->context, $USER, 'mod/assignment:submit')) { $editable = false; } else { $editable = $this->isopen() && (!$submission || $this->assignment->resubmit || !$submission->timemarked); @@ -49,7 +49,7 @@ function view() { $data->textformat = NULL; } - $data = file_prepare_standard_editor($data, 'text', $editoroptions, $this->context, 'assignment_online_submission', $data->sid); + $data = file_prepare_standard_editor($data, 'text', $editoroptions, $this->context, 'mod_assignment', 'online_submission', $data->sid); $mform = new mod_assignment_online_edit_form(null, array($data, $editoroptions)); @@ -60,7 +60,7 @@ function view() { if ($data = $mform->get_data()) { $submission = $this->get_submission($USER->id, true); //create the submission if needed & its id - $data = file_postupdate_standard_editor($data, 'text', $editoroptions, $this->context, 'assignment_online_submission', $submission->id); + $data = file_postupdate_standard_editor($data, 'text', $editoroptions, $this->context, 'mod_assignment', 'online_submission', $submission->id); $submission = $this->update_submission($data); @@ -90,29 +90,27 @@ function view() { echo $OUTPUT->notification(get_string('submissionsaved', 'assignment'), 'notifysuccess'); } - if (has_capability('mod/assignment:submit', $context)) { + if (is_enrolled($this->context, $USER, 'mod/assignment:submit')) { if ($editmode) { echo $OUTPUT->box_start('generalbox', 'onlineenter'); $mform->display(); } else { echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter', 'online'); if ($submission && has_capability('mod/assignment:exportownsubmission', $this->context)) { - $text = file_rewrite_pluginfile_urls($submission->data1, 'pluginfile.php', $this->context->id, 'assignment_online_submission', $submission->id); + $text = file_rewrite_pluginfile_urls($submission->data1, 'pluginfile.php', $this->context->id, 'mod_assignment', 'online_submission', $submission->id); echo format_text($text, $submission->data2); if ($CFG->enableportfolios) { require_once($CFG->libdir . '/portfoliolib.php'); $button = new portfolio_add_button(); $button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id), '/mod/assignment/locallib.php'); $fs = get_file_storage(); - if ($files = $fs->get_area_files($this->context->id, 'assignment_online_submission', $submission->id, "timemodified", false)) { + if ($files = $fs->get_area_files($this->context->id, 'mod_assignment', 'online_submission', $submission->id, "timemodified", false)) { $button->set_formats(PORTFOLIO_FORMAT_RICHHTML); } else { $button->set_formats(PORTFOLIO_FORMAT_PLAINHTML); } $button->render(); } - } else if (!has_capability('mod/assignment:submit', $context)) { //fix for #4604 - echo '
'. get_string('guestnosubmit', 'assignment').'
'; } else if ($this->isopen()){ //fix for #4206 echo '
'.get_string('emptysubmission', 'assignment').'
'; } @@ -232,7 +230,7 @@ function print_user_files($userid, $return=false) { } $wordcount .= '

'; - $text = file_rewrite_pluginfile_urls($submission->data1, 'pluginfile.php', $this->context->id, 'assignment_online_submission', $submission->id); + $text = file_rewrite_pluginfile_urls($submission->data1, 'pluginfile.php', $this->context->id, 'mod_assignment', 'online_submission', $submission->id); return $wordcount . format_text($text, $submission->data2); @@ -278,7 +276,7 @@ function portfolio_exportable() { function portfolio_load_data($caller) { $submission = $this->get_submission(); $fs = get_file_storage(); - if ($files = $fs->get_area_files($this->context->id, 'assignment_online_submission', $submission->id, "timemodified", false)) { + if ($files = $fs->get_area_files($this->context->id, 'mod_assignment', 'online_submission', $submission->id, "timemodified", false)) { $caller->set('multifiles', $files); } } @@ -296,7 +294,7 @@ function portfolio_get_sha1($caller) { function portfolio_prepare_package($exporter, $user) { $submission = $this->get_submission($user->id); $html = format_text($submission->data1, $submission->data2); - $html = portfolio_rewrite_pluginfile_urls($html, $this->context->id, 'assignment_online_submission', $submission->id, $exporter->get('format')); + $html = portfolio_rewrite_pluginfile_urls($html, $this->context->id, 'mod_assignment', 'online_submission', $submission->id, $exporter->get('format')); if (in_array($exporter->get('formatclass'), array(PORTFOLIO_FORMAT_PLAINHTML, PORTFOLIO_FORMAT_RICHHTML))) { if ($files = $exporter->get('caller')->get('multifiles')) { foreach ($files as $f) { @@ -329,7 +327,7 @@ function extend_settings_navigation($node) { // get users submission if there is one $submission = $this->get_submission(); - if (has_capability('mod/assignment:submit', $PAGE->cm->context)) { + if (is_enrolled($PAGE->cm->context, $USER, 'mod/assignment:submit')) { $editable = $this->isopen() && (!$submission || $this->assignment->resubmit || !$submission->timemarked); } else { $editable = false; @@ -364,7 +362,7 @@ public function send_file($filearea, $args) { global $USER; require_capability('mod/assignment:view', $this->context); - $fullpath = $this->context->id.$filearea.implode('/', $args); + $fullpath = "/{$this->context->id}/mod_assignment/$filearea/".implode('/', $args); $fs = get_file_storage(); if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { diff --git a/mod/assignment/type/online/file.php b/mod/assignment/type/online/file.php index 9827f566f210f..10da8990aba2c 100644 --- a/mod/assignment/type/online/file.php +++ b/mod/assignment/type/online/file.php @@ -59,7 +59,7 @@ echo ''; echo $OUTPUT->box_end(); - $text = file_rewrite_pluginfile_urls($submission->data1, 'pluginfile.php', $context->id, 'assignment_online_submission', $submission->id); + $text = file_rewrite_pluginfile_urls($submission->data1, 'pluginfile.php', $context->id, 'mod_assignment', 'online_submission', $submission->id); echo $OUTPUT->box(format_text($text, $submission->data2), 'generalbox boxaligncenter boxwidthwide'); echo $OUTPUT->close_window_button(); echo $OUTPUT->footer(); diff --git a/mod/assignment/type/upload/assignment.class.php b/mod/assignment/type/upload/assignment.class.php index b9408548fb720..bc1d760dcdc93 100644 --- a/mod/assignment/type/upload/assignment.class.php +++ b/mod/assignment/type/upload/assignment.class.php @@ -37,9 +37,12 @@ function view() { $this->view_dates(); - if (has_capability('mod/assignment:submit', $this->context)) { - $submission = $this->get_submission($USER->id); - $filecount = $this->count_user_files($submission->id); + if (is_enrolled($this->context, $USER, 'mod/assignment:submit')) { + if ($submission = $this->get_submission($USER->id)) { + $filecount = $this->count_user_files($submission->id); + } else { + $filecount = 0; + } $this->view_feedback(); @@ -285,13 +288,13 @@ function print_student_answer($userid, $return=false){ $fs = get_file_storage(); $browser = get_file_browser(); - if ($files = $fs->get_area_files($this->context->id, 'assignment_submission', $userid, "timemodified", false)) { + if ($files = $fs->get_area_files($this->context->id, 'mod_assignment', 'submission', $submission->id, "timemodified", false)) { foreach ($files as $file) { $filename = $file->get_filename(); $found = true; $mimetype = $file->get_mimetype(); - $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_submission/'.$userid.'/'.$filename); + $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/mod_assignment/submission/'.$submission->id.'/'.$filename); $output .= ''.$mimetype.''.s($filename).' '; } @@ -344,12 +347,12 @@ function print_user_files($userid=0, $return=false) { $fs = get_file_storage(); $browser = get_file_browser(); - if ($files = $fs->get_area_files($this->context->id, 'assignment_submission', $submission->id, "timemodified", false)) { + if ($files = $fs->get_area_files($this->context->id, 'mod_assignment', 'submission', $submission->id, "timemodified", false)) { $button = new portfolio_add_button(); foreach ($files as $file) { $filename = $file->get_filename(); $mimetype = $file->get_mimetype(); - $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_submission/'.$submission->id.'/'.$filename); + $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/mod_assignment/submission/'.$submission->id.'/'.$filename); $output .= ''.$mimetype.''.s($filename).''; if ($candelete) { @@ -405,26 +408,28 @@ function print_responsefiles($userid, $return=false) { $fs = get_file_storage(); $browser = get_file_browser(); - if ($files = $fs->get_area_files($this->context->id, 'assignment_response', $userid, "timemodified", false)) { - foreach ($files as $file) { - $filename = $file->get_filename(); - $found = true; - $mimetype = $file->get_mimetype(); - $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_response/'.$userid.'/'.$filename); + if ($submission = $this->get_submission($userid)) { + if ($files = $fs->get_area_files($this->context->id, 'mod_assignment', 'response', $submission->id, "timemodified", false)) { + foreach ($files as $file) { + $filename = $file->get_filename(); + $found = true; + $mimetype = $file->get_mimetype(); + $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/mod_assignment/response/'.$submission->id.'/'.$filename); - $output .= ''.$mimetype.''.$filename.''; + $output .= ''.$mimetype.''.$filename.''; - if ($candelete) { - $delurl = "$CFG->wwwroot/mod/assignment/delete.php?id={$this->cm->id}&file=".rawurlencode($filename)."&userid=$userid&mode=$mode&offset=$offset&action=response"; + if ($candelete) { + $delurl = "$CFG->wwwroot/mod/assignment/delete.php?id={$this->cm->id}&file=".rawurlencode($filename)."&userid=$userid&mode=$mode&offset=$offset&action=response"; - $output .= ' ' - .' '; + $output .= ' ' + .' '; + } + + $output .= ' '; } - $output .= ' '; + $output = '
'.$output.'
'; } - - $output = '
'.$output.'
'; } if ($return) { @@ -539,8 +544,9 @@ function upload_responsefile() { $fs = get_file_storage(); $filename = $mform->get_new_filename('newfile'); if ($filename !== false) { - if (!$fs->file_exists($this->context->id, 'assignment_response', $userid, '/', $filename)) { - if ($file = $mform->save_stored_file('newfile', $this->context->id, 'assignment_response', $userid, '/', $filename, false, $USER->id)) { + $submission = $this->get_submission($userid, true, true); + if (!$fs->file_exists($this->context->id, 'mod_assignment', 'response', $submission->id, '/', $filename)) { + if ($file = $mform->save_stored_file('newfile', $this->context->id, 'mod_assignment', 'response', $submission->id, '/', $filename, false, $USER->id)) { redirect($returnurl); } } @@ -576,8 +582,8 @@ function upload_file() { $filename = $mform->get_new_filename('newfile'); if ($filename !== false) { $submission = $this->get_submission($USER->id, true); //create new submission if needed - if (!$fs->file_exists($this->context->id, 'assignment_submission', $submission->id, '/', $filename)) { - if ($file = $mform->save_stored_file('newfile', $this->context->id, 'assignment_submission', $submission->id, '/', $filename, false, $USER->id)) { + if (!$fs->file_exists($this->context->id, 'mod_assignment', 'submission', $submission->id, '/', $filename)) { + if ($file = $mform->save_stored_file('newfile', $this->context->id, 'mod_assignment', 'submission', $submission->id, '/', $filename, false, $USER->id)) { $updates = new object(); $updates->id = $submission->id; $updates->timemodified = time(); @@ -620,31 +626,48 @@ function send_file($filearea, $args) { require_login($this->course, false, $this->cm); - $userid = (int)array_shift($args); - $relativepath = '/'.implode('/', $args); - $fullpath = $this->context->id.$filearea.$userid.$relativepath; + if ($filearea === 'submission') { + $submissionid = (int)array_shift($args); - $fs = get_file_storage(); + if (!$submission = $DB->get_record('assignment_submissions', array('assignment'=>$this->assignment->id, 'id'=>$submissionid))) { + return false; + } - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { - return false; - } + if ($USER->id != $submission->userid and !has_capability('mod/assignment:grade', $this->context)) { + return false; + } + + $relativepath = implode('/', $args); + $fullpath = "/{$this->context->id}/mod_assignment/submission/$submission->id/$relativepath"; - if ($filearea === 'assignment_submission') { - if ($USER->id != $userid and !has_capability('mod/assignment:grade', $this->context)) { + $fs = get_file_storage(); + if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { return false; } + send_stored_file($file, 0, 0, true); // download MUST be forced - security! + + } else if ($filearea === 'response') { + $submissionid = (int)array_shift($args); - } else if ($filearea === 'assignment_response') { - if ($USER->id != $userid and !has_capability('mod/assignment:grade', $this->context)) { + if (!$submission = $DB->get_record('assignment_submissions', array('assignment'=>$this->assignment->id, 'id'=>$submissionid))) { return false; } - } else { - return false; + if ($USER->id != $submission->userid and !has_capability('mod/assignment:grade', $this->context)) { + return false; + } + + $relativepath = implode('/', $args); + $fullpath = "/{$this->context->id}/mod_assignment/response/$submission->id/$relativepath"; + + $fs = get_file_storage(); + if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + return false; + } + send_stored_file($file, 0, 0, true); } - send_stored_file($file, 0, 0, true); // download MUST be forced - security! + return false; } function finalize() { @@ -802,21 +825,13 @@ function delete_responsefile() { die; } - $fs = get_file_storage(); - if ($file = $fs->get_file($this->context->id, 'assignment_submission', $userid, '/', $file)) { - if ($file->delete()) { - redirect($returnurl); + if ($submission = $this->get_submission($userid)) { + $fs = get_file_storage(); + if ($file = $fs->get_file($this->context->id, 'mod_assignment', 'response', $submission->id, '/', $file)) { + $file->delete(); } } - - // print delete error - $PAGE->set_title(get_string('delete')); - echo $OUTPUT->header(); - echo $OUTPUT->notification(get_string('deletefilefailed', 'assignment')); - echo $OUTPUT->continue_button($returnurl); - echo $OUTPUT->footer(); - die; - + redirect($returnurl); } @@ -825,7 +840,6 @@ function delete_file() { $file = required_param('file', PARAM_FILE); $userid = required_param('userid', PARAM_INT); - $submissionid = required_param('submissionid', PARAM_INT); $confirm = optional_param('confirm', 0, PARAM_BOOL); $mode = optional_param('mode', '', PARAM_ALPHA); $offset = optional_param('offset', 0, PARAM_INT); @@ -852,7 +866,7 @@ function delete_file() { } if (!data_submitted() or !$confirm or !confirm_sesskey()) { - $optionsyes = array ('id'=>$this->cm->id, 'file'=>$file, 'userid'=>$userid, 'submissionid'=>$submissionid, 'confirm'=>1, 'sesskey'=>sesskey(), 'mode'=>$mode, 'offset'=>$offset, 'sesskey'=>sesskey()); + $optionsyes = array ('id'=>$this->cm->id, 'file'=>$file, 'userid'=>$userid, 'confirm'=>1, 'sesskey'=>sesskey(), 'mode'=>$mode, 'offset'=>$offset, 'sesskey'=>sesskey()); if (empty($mode)) { $this->view_header(get_string('delete')); } else { @@ -870,40 +884,22 @@ function delete_file() { } $fs = get_file_storage(); - if ($file = $fs->get_file($this->context->id, 'assignment_submission', $submissionid, '/', $file)) { - if ($file->delete()) { - $submission->timemodified = time(); - if ($DB->update_record('assignment_submissions', $submission)) { - add_to_log($this->course->id, 'assignment', 'upload', //TODO: add delete action to log - 'view.php?a='.$this->assignment->id, $this->assignment->id, $this->cm->id); - $this->update_grade($submission); - } - redirect($returnurl); - } - } - - // print delete error - if (empty($mode)) { - $this->view_header(get_string('delete')); - } else { - $PAGE->set_title(get_string('delete')); - echo $OUTPUT->header(); - } - echo $OUTPUT->notification(get_string('deletefilefailed', 'assignment')); - echo $OUTPUT->continue_button($returnurl); - if (empty($mode)) { - $this->view_footer(); - } else { - echo $OUTPUT->footer(); + if ($file = $fs->get_file($this->context->id, 'mod_assignment', 'submission', $submission->id, '/', $file)) { + $file->delete(); + $submission->timemodified = time(); + $DB->update_record('assignment_submissions', $submission); + add_to_log($this->course->id, 'assignment', 'upload', //TODO: add delete action to log + 'view.php?a='.$this->assignment->id, $this->assignment->id, $this->cm->id); + $this->update_grade($submission); } - die; + redirect($returnurl); } function can_upload_file($submission) { global $USER; - if (has_capability('mod/assignment:submit', $this->context) // can submit + if (is_enrolled($this->context, $USER, 'mod/assignment:submit') and $this->isopen() // assignment not closed yet and (empty($submission) or $submission->userid == $USER->id) // his/her own submission and $this->count_user_files($USER->id) < $this->assignment->var1 // file limit not reached @@ -929,7 +925,7 @@ function can_delete_files($submission) { return true; } - if (has_capability('mod/assignment:submit', $this->context) + if (is_enrolled($this->context, $USER, 'mod/assignment:submit') and $this->isopen() // assignment not closed yet and $this->assignment->resubmit // deleting allowed and $USER->id == $submission->userid // his/her own submission @@ -990,7 +986,7 @@ function can_finalize($submission) { if (has_capability('mod/assignment:grade', $this->context)) { return true; - } else if (has_capability('mod/assignment:submit', $this->context) // can submit + } else if (is_enrolled($this->context, $USER, 'mod/assignment:submit') and $this->isopen() // assignment not closed yet and !empty($submission) // submission must exist and $submission->userid == $USER->id // his/her own submission @@ -1006,7 +1002,7 @@ function can_finalize($submission) { function can_update_notes($submission) { global $USER; - if (has_capability('mod/assignment:submit', $this->context) + if (is_enrolled($this->context, $USER, 'mod/assignment:submit') and $this->notes_allowed() // notesd must be allowed and $this->isopen() // assignment not closed yet and (empty($submission) or $USER->id == $submission->userid) // his/her own submission @@ -1022,9 +1018,13 @@ function notes_allowed() { } function count_responsefiles($userid) { - $fs = get_file_storage(); - $files = $fs->get_area_files($this->context->id, 'assignment_response', $userid, "id", false); - return count($files); + if ($submission = $this->get_submission($userid)) { + $fs = get_file_storage(); + $files = $fs->get_area_files($this->context->id, 'mod_assignment', 'response', $submission->id, "id", false); + return count($files); + } else { + return 0; + } } function setup_elements(&$mform) { @@ -1076,7 +1076,7 @@ function extend_settings_navigation($node) { // get users submission if there is one $submission = $this->get_submission(); - if (has_capability('mod/assignment:submit', get_context_instance(CONTEXT_MODULE, $this->cm->id))) { + if (is_enrolled($this->context, $USER, 'mod/assignment:submit')) { $editable = $this->isopen() && (!$submission || $this->assignment->resubmit || !$submission->timemarked); } else { $editable = false; @@ -1100,9 +1100,9 @@ function extend_settings_navigation($node) { } // Check if the user has uploaded any files, if so we can add some more stuff to the settings nav - if ($submission && has_capability('mod/assignment:submit', $this->context) && $this->count_user_files($USER->id)) { + if ($submission && is_enrolled($this->context, $USER, 'mod/assignment:submit') && $this->count_user_files($USER->id)) { $fs = get_file_storage(); - if ($files = $fs->get_area_files($this->context->id, 'assignment_submission', $USER->id, "timemodified", false)) { + if ($files = $fs->get_area_files($this->context->id, 'mod_assignment', 'submission', $submission->id, "timemodified", false)) { if (!$this->drafts_tracked() or !$this->isopen() or $this->is_finalized($submission)) { $filenode = $node->add(get_string('submission', 'assignment')); } else { @@ -1111,7 +1111,7 @@ function extend_settings_navigation($node) { foreach ($files as $file) { $filename = $file->get_filename(); $mimetype = $file->get_mimetype(); - $link = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_submission/'.$USER->id.'/'.$filename); + $link = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/mod_assignment/submission/'.$submission->id.'/'.$filename); $filenode->add($filename, $link, navigation_node::TYPE_SETTING, null, null, new pix_icon(file_mimetype_icon($mimetype),'')); } } @@ -1152,8 +1152,8 @@ public function download_submissions() { if ((groups_is_member($groupid,$a_userid)or !$groupmode or !$groupid)) { $a_assignid = $submission->assignment; //get name of this assignment for use in the file names. $a_user = $DB->get_record("user", array("id"=>$a_userid),'id,username,firstname,lastname'); //get user firstname/lastname - - $files = $fs->get_area_files($this->context->id, 'assignment_submission', $a_userid, "timemodified", false); + + $files = $fs->get_area_files($this->context->id, 'mod_assignment', 'submission', $submission->id, "timemodified", false); foreach ($files as $file) { //get files new name. $fileforzipname = $a_user->username . "_" . $filenewname . "_" . $file->get_filename(); diff --git a/mod/assignment/type/uploadsingle/assignment.class.php b/mod/assignment/type/uploadsingle/assignment.class.php index 321c43939db60..94539dfcb7f6f 100644 --- a/mod/assignment/type/uploadsingle/assignment.class.php +++ b/mod/assignment/type/uploadsingle/assignment.class.php @@ -15,14 +15,15 @@ function print_student_answer($userid, $return=false){ $output = ''; - if ($files = $fs->get_area_files($this->context->id, 'assignment_submission', $userid, "timemodified", false)) { - - foreach ($files as $file) { - $filename = $file->get_filename(); - $found = true; - $mimetype = $file->get_mimetype(); - $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_submission/'.$userid.'/'.$filename); - $output .= ''.$mimetype.''.s($filename).'
'; + if ($submission = $this->get_submission($USER->id)) { + if ($files = $fs->get_area_files($this->context->id, 'mod_assignment', 'submission', $submission->id, "timemodified", false)) { + foreach ($files as $file) { + $filename = $file->get_filename(); + $found = true; + $mimetype = $file->get_mimetype(); + $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/mod_assignment/submission/'.$submission->id.'/'.$filename); + $output .= ''.$mimetype.''.s($filename).'
'; + } } } @@ -62,7 +63,7 @@ function view() { } } - if (has_capability('mod/assignment:submit', $context) && $this->isopen() && (!$filecount || $this->assignment->resubmit || !$submission->timemarked)) { + if (is_enrolled($this->context, $USER, 'mod/assignment:submit') && $this->isopen() && (!$filecount || $this->assignment->resubmit || !$submission->timemarked)) { $this->view_upload_form(); } @@ -81,7 +82,9 @@ function view_upload_form() { function upload() { global $CFG, $USER, $DB, $OUTPUT; - require_capability('mod/assignment:submit', get_context_instance(CONTEXT_MODULE, $this->cm->id)); + if (!is_enrolled($this->context, $USER, 'mod/assignment:submit')) { + redirect('view.php?id='.$this->cm->id); + } $filecount = $this->count_user_files($USER->id); $submission = $this->get_submission($USER->id); @@ -98,37 +101,30 @@ function upload() { $fs = get_file_storage(); $filename = $mform->get_new_filename('newfile'); if ($filename !== false) { - $fs->delete_area_files($this->context->id, 'assignment_submission', $submission->id); + $submission = $this->get_submission($USER->id, true); //create new submission if needed + $fs->delete_area_files($this->context->id, 'mod_assignment', 'submission', $submission->id); - if (empty($submission->id)) { - $submission = $this->get_submission($USER->id, true); //create new submission if needed - } - - if ($file = $mform->save_stored_file('newfile', $this->context->id, 'assignment_submission', $submission->id, '/', $filename, false, $USER->id)) { + if ($file = $mform->save_stored_file('newfile', $this->context->id, 'mod_assignment', 'submission', $submission->id, '/', $filename, false, $USER->id)) { $updates = new object(); //just enough data for updating the submission $updates->timemodified = time(); $updates->numfiles = 1; $updates->id = $submission->id; - if ($DB->update_record('assignment_submissions', $updates)) { - add_to_log($this->course->id, 'assignment', 'upload', - 'view.php?a='.$this->assignment->id, $this->assignment->id, $this->cm->id); - $this->update_grade($submission); - $this->email_teachers($submission); - //trigger event with information about this file. - $eventdata = new object(); - $eventdata->component = 'mod/assignment'; - $eventdata->course = $this->course; - $eventdata->assignment = $this->assignment; - $eventdata->cm = $this->cm; - $eventdata->user = $USER; - $eventdata->file = $file; - events_trigger('assignment_file_sent', $eventdata); - - redirect('view.php?id='.$this->cm->id, get_string('uploadedfile')); - } else { - $file->delete(); - redirect('view.php?id='.$this->cm->id, get_string('uploadnotregistered', 'assignment', $newfile_name)); - } + $DB->update_record('assignment_submissions', $updates); + add_to_log($this->course->id, 'assignment', 'upload', + 'view.php?a='.$this->assignment->id, $this->assignment->id, $this->cm->id); + $this->update_grade($submission); + $this->email_teachers($submission); + //trigger event with information about this file. + $eventdata = new object(); + $eventdata->component = 'mod/assignment'; + $eventdata->course = $this->course; + $eventdata->assignment = $this->assignment; + $eventdata->cm = $this->cm; + $eventdata->user = $USER; + $eventdata->file = $file; + events_trigger('assignment_file_sent', $eventdata); + + redirect('view.php?id='.$this->cm->id, get_string('uploadedfile')); } } } else { @@ -169,22 +165,26 @@ function send_file($filearea, $args) { require_login($this->course, false, $this->cm); - $userid = (int)array_shift($args); - $relativepath = '/'.implode('/', $args); - $fullpath = $this->context->id.$filearea.$userid.$relativepath; + if ($filearea !== 'submission') { + return false; + } - $fs = get_file_storage(); + $submissionid = (int)array_shift($args); - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + if (!$submission = $DB->get_record('assignment_submissions', array('assignment'=>$this->assignment->id, 'id'=>$submissionid))) { return false; } - if ($filearea === 'assignment_submission') { - if ($USER->id != $userid and !has_capability('mod/assignment:grade', $this->context)) { - return false; - } + if ($USER->id != $submission->userid and !has_capability('mod/assignment:grade', $this->context)) { + return false; + } - } else { + $relativepath = implode('/', $args); + $fullpath = "/$this->context->id/mod_assignment/submission/$submissionid/$relativepath"; + + $fs = get_file_storage(); + + if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { return false; } @@ -196,7 +196,7 @@ function extend_settings_navigation($node) { // get users submission if there is one $submission = $this->get_submission(); - if (has_capability('mod/assignment:submit', get_context_instance(CONTEXT_MODULE, $this->cm->id))) { + if (is_enrolled($this->context, $USER, 'mod/assignment:submit')) { $editable = $this->isopen() && (!$submission || $this->assignment->resubmit || !$submission->timemarked); } else { $editable = false; @@ -220,14 +220,14 @@ function extend_settings_navigation($node) { } // Check if the user has uploaded any files, if so we can add some more stuff to the settings nav - if ($submission && has_capability('mod/assignment:submit', $this->context) && $this->count_user_files($USER->id)) { + if ($submission && is_enrolled($this->context, $USER, 'mod/assignment:submit') && $this->count_user_files($USER->id)) { $fs = get_file_storage(); - if ($files = $fs->get_area_files($this->context->id, 'assignment_submission', $USER->id, "timemodified", false)) { + if ($files = $fs->get_area_files($this->context->id, 'mod_assignment', 'submission', $submission->id, "timemodified", false)) { $filenode = $node->add(get_string('submission', 'assignment')); foreach ($files as $file) { $filename = $file->get_filename(); $mimetype = $file->get_mimetype(); - $link = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/assignment_submission/'.$USER->id.'/'.$filename); + $link = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/mod_assignment', 'submission/'.$submission->id.'/'.$filename); $filenode->add($filename, $link, navigation_node::TYPE_SETTING, null, null, new pix_icon(file_mimetype_icon($mimetype), '')); } } @@ -263,8 +263,8 @@ function download_submissions() { if ((groups_is_member($groupid,$a_userid)or !$groupmode or !$groupid)) { $a_assignid = $submission->assignment; //get name of this assignment for use in the file names. $a_user = $DB->get_record("user", array("id"=>$a_userid),'id,username,firstname,lastname'); //get user firstname/lastname - - $files = $fs->get_area_files($this->context->id, 'assignment_submission', $a_userid, "timemodified", false); + + $files = $fs->get_area_files($this->context->id, 'mod_assignment', 'submission', $submission->id, "timemodified", false); foreach ($files as $file) { //get files new name. $fileforzipname = $a_user->username . "_" . $filenewname . "_" . $file->get_filename(); diff --git a/mod/chat/backup/moodle2/backup_chat_stepslib.php b/mod/chat/backup/moodle2/backup_chat_stepslib.php index 09f358e76054e..6ed82154be0e1 100644 --- a/mod/chat/backup/moodle2/backup_chat_stepslib.php +++ b/mod/chat/backup/moodle2/backup_chat_stepslib.php @@ -57,7 +57,7 @@ protected function define_structure() { $message->annotate_ids('group', 'groupid'); // Annotate the file areas in chat module - $chat->annotate_files(array('chat_intro'), null); // chat_intro area don't use itemid + $chat->annotate_files('mod_chat', 'intro', null); // chat_intro area don't use itemid // Return the root element (chat), wrapped into standard activity structure return $this->prepare_activity_structure($chat); diff --git a/mod/choice/backup/moodle2/backup_choice_stepslib.php b/mod/choice/backup/moodle2/backup_choice_stepslib.php index 30eba5456abe8..b90b584d4a351 100644 --- a/mod/choice/backup/moodle2/backup_choice_stepslib.php +++ b/mod/choice/backup/moodle2/backup_choice_stepslib.php @@ -77,7 +77,7 @@ protected function define_structure() { $answer->annotate_ids('user', 'userid'); // Define file annotations - $choice->annotate_files(array('choice_intro'), null); // This file area hasn't itemid + $choice->annotate_files('mod_choice', 'intro', null); // This file area hasn't itemid // Return the root element (choice), wrapped into standard activity structure return $this->prepare_activity_structure($choice); diff --git a/mod/data/db/upgrade.php b/mod/data/db/upgrade.php index 8c461e016a0c0..c2421de895ef4 100644 --- a/mod/data/db/upgrade.php +++ b/mod/data/db/upgrade.php @@ -107,14 +107,14 @@ function xmldb_data_upgrade($oldversion) { continue; } - $filearea = 'data_content'; + $filearea = 'content'; $oldfilename = $content->content; $filename = clean_param($oldfilename, PARAM_FILE); if ($filename === '') { continue; } - if (!$fs->file_exists($context->id, $filearea, $content->id, '/', $filename)) { - $file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>$content->id, 'filepath'=>'/', 'filename'=>$filename, 'userid'=>$content->userid); + if (!$fs->file_exists($context->id, 'mod_data', $filearea, $content->id, '/', $filename)) { + $file_record = array('contextid'=>$context->id, 'component'=>'mod_data', 'filearea'=>$filearea, 'itemid'=>$content->id, 'filepath'=>'/', 'filename'=>$filename, 'userid'=>$content->userid); if ($fs->create_file_from_pathname($file_record, $filepath)) { unlink($filepath); if ($oldfilename !== $filename) { @@ -124,7 +124,7 @@ function xmldb_data_upgrade($oldversion) { if ($content->type == 'picture') { // migrate thumb $filepath = "$CFG->dataroot/$content->course/$CFG->moddata/data/$content->dataid/$content->fieldid/$content->recordid/thumb/$content->content"; - if (!$fs->file_exists($context->id, $filearea, $content->id, '/', 'thumb_'.$filename)) { + if (!$fs->file_exists($context->id, 'mod_data', $filearea, $content->id, '/', 'thumb_'.$filename)) { $file_record['filename'] = 'thumb_'.$file_record['filename']; $fs->create_file_from_pathname($file_record, $filepath); unlink($filepath); diff --git a/mod/data/field/file/field.class.php b/mod/data/field/file/field.class.php index 0a7f38a818625..eb543994b6b6a 100755 --- a/mod/data/field/file/field.class.php +++ b/mod/data/field/file/field.class.php @@ -39,18 +39,17 @@ function display_add_field($recordid=0) { if ($recordid){ if ($content = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) { - file_prepare_draft_area($itemid, $this->context->id, 'data_content', $content->id); + file_prepare_draft_area($itemid, $this->context->id, 'mod_data', 'content', $content->id); if (!empty($content->content)) { - if ($file = $fs->get_file($this->context->id, 'data_content', $content->id, '/', $content->content)) { + if ($file = $fs->get_file($this->context->id, 'mod_data', 'content', $content->id, '/', $content->content)) { $usercontext = get_context_instance(CONTEXT_USER, $USER->id); - if (!$files = $fs->get_area_files($usercontext->id, 'user_draft', $itemid, 'id DESC', false)) { + if (!$files = $fs->get_area_files($usercontext->id, 'user', 'draft', $itemid, 'id DESC', false)) { return false; } if (empty($content->content1)) { // Print icon if file already exists - $browser = get_file_browser(); - $src = file_encode_url($CFG->wwwroot.'/draftfile.php/', $usercontext->id.'/user_draft/'.$itemid.'/'.$file->get_filename()); + $src = file_draftfile_url($itemid, '/', $file->get_filename()); $displayname = ''.$file->get_mimetype().''. ''.s($file->get_filename()).''; } else { @@ -118,7 +117,7 @@ function get_file($recordid, $content=null) { } } $fs = get_file_storage(); - if (!$file = $fs->get_file($this->context->id, 'data_content', $content->id, '/', $content->content)) { + if (!$file = $fs->get_file($this->context->id, 'mod_data', 'content', $content->id, '/', $content->content)) { return null; } @@ -136,13 +135,12 @@ function display_browse_field($recordid, $template) { return ''; } - $browser = get_file_browser(); if (!$file = $this->get_file($recordid, $content)) { return ''; } $name = empty($content->content1) ? $file->get_filename() : $content->content1; - $src = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/data_content/'.$content->id.'/'.$file->get_filename()); + $src = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/mod_data/content/'.$content->id.'/'.$file->get_filename()); $width = $this->field->param1 ? ' width = "'.s($this->field->param1).'" ':' '; $height = $this->field->param2 ? ' height = "'.s($this->field->param2).'" ':' '; @@ -168,17 +166,17 @@ function update_content($recordid, $value, $name) { } // delete existing files - $fs->delete_area_files($this->context->id, 'data_content', $content->id); + $fs->delete_area_files($this->context->id, 'mod_data', 'content', $content->id); $usercontext = get_context_instance(CONTEXT_USER, $USER->id); - $files = $fs->get_area_files($usercontext->id, 'user_draft', $value); + $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $value); if (count($files)<2) { // no file } else { $count = 0; foreach ($files as $draftfile) { - $file_record = array('contextid'=>$this->context->id, 'itemid'=>$content->id, 'filepath'=>'/', 'filearea'=>'data_content'); + $file_record = array('contextid'=>$this->context->id, 'component'=>'mod_data', 'filearea'=>'content', 'itemid'=>$content->id, 'filepath'=>'/'); if (!$draftfile->is_directory()) { $file_record['filename'] = $draftfile->get_filename(); diff --git a/mod/data/field/picture/field.class.php b/mod/data/field/picture/field.class.php index db820c60f9581..bcd0eb3df5ce1 100755 --- a/mod/data/field/picture/field.class.php +++ b/mod/data/field/picture/field.class.php @@ -39,20 +39,19 @@ function display_add_field($recordid=0) { if ($recordid) { if ($content = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) { - file_prepare_draft_area($itemid, $this->context->id, 'data_content', $content->id); + file_prepare_draft_area($itemid, $this->context->id, 'mod_data', 'content', $content->id); if (!empty($content->content)) { - if ($file = $fs->get_file($this->context->id, 'data_content', $content->id, '/', $content->content)) { + if ($file = $fs->get_file($this->context->id, 'mod_data', 'content', $content->id, '/', $content->content)) { $usercontext = get_context_instance(CONTEXT_USER, $USER->id); - if (!$files = $fs->get_area_files($usercontext->id, 'user_draft', $itemid, 'id DESC', false)) { + if (!$files = $fs->get_area_files($usercontext->id, 'user', 'draft', $itemid, 'id DESC', false)) { return false; } - if ($thumbfile = $fs->get_file($usercontext->id, 'user_draft', $itemid, '/', 'thumb_'.$content->content)) { + if ($thumbfile = $fs->get_file($usercontext->id, 'user', 'draft', $itemid, '/', 'thumb_'.$content->content)) { $thumbfile->delete(); } if (empty($content->content1)) { // Print icon if file already exists - $browser = get_file_browser(); - $src = file_encode_url($CFG->wwwroot.'/draftfile.php/', $usercontext->id.'/user_draft/'.$itemid.'/'.$file->get_filename()); + $src = file_draftfile_url($itemid, '/', $file->get_filename()); $displayname = ''.$file->get_mimetype().''. ''.s($file->get_filename()).''; } else { @@ -69,7 +68,7 @@ function display_add_field($recordid=0) { $str = '
'; $str .= '
'.$this->field->name.''; if ($file) { - $src = file_encode_url($CFG->wwwroot.'/pluginfile.php/', $this->context->id.'/data_content/'.$content->id.'/'.$file->get_filename()); + $src = file_encode_url($CFG->wwwroot.'/pluginfile.php/', $this->context->id.'/mod_data/content/'.$content->id.'/'.$file->get_filename()); $str .= ''; } @@ -111,7 +110,7 @@ function get_file($recordid, $content=null) { } } $fs = get_file_storage(); - if (!$file = $fs->get_file($this->context->id, 'data_content', $content->id, '/', $content->content)) { + if (!$file = $fs->get_file($this->context->id, 'mod_data', 'content', $content->id, '/', $content->content)) { return null; } @@ -148,18 +147,16 @@ function display_browse_field($recordid, $template) { return ''; } - $browser = get_file_browser(); - $alt = $content->content1; $title = $alt; if ($template == 'listtemplate') { - $src = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/data_content/'.$content->id.'/'.'thumb_'.$content->content); + $src = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/mod_data/content/'.$content->id.'/'.'thumb_'.$content->content); // no need to add width/height, because the thumb is resized properly $str = ''.s($alt).''; } else { - $src = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/data_content/'.$content->id.'/'.$content->content); + $src = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/mod_data/content/'.$content->id.'/'.$content->content); $width = $this->field->param1 ? ' width="'.s($this->field->param1).'" ':' '; $height = $this->field->param2 ? ' height="'.s($this->field->param2).'" ':' '; $str = ''.s($alt).''; @@ -187,10 +184,10 @@ function update_field() { ob_flush(); } foreach ($contents as $content) { - if (!$file = $fs->get_file($this->context->id, 'data_content', $content->id, '/', $content->content)) { + if (!$file = $fs->get_file($this->context->id, 'mod_data', 'content', $content->id, '/', $content->content)) { continue; } - if ($thumbfile = $fs->get_file($this->context->id, 'data_content', $content->id, '/', 'thumb_'.$content->content)) { + if ($thumbfile = $fs->get_file($this->context->id, 'mod_data', 'content', $content->id, '/', 'thumb_'.$content->content)) { $thumbfile->delete(); } @set_time_limit(300); @@ -218,15 +215,15 @@ function update_content($recordid, $value, $name) { switch ($names[2]) { case 'file': $fs = get_file_storage(); - $fs->delete_area_files($this->context->id, 'data_content', $content->id); + $fs->delete_area_files($this->context->id, 'mod_data', 'content', $content->id); $usercontext = get_context_instance(CONTEXT_USER, $USER->id); - $files = $fs->get_area_files($usercontext->id, 'user_draft', $value); + $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $value); if (count($files)<2) { // no file } else { $count = 0; foreach ($files as $draftfile) { - $file_record = array('contextid'=>$this->context->id, 'itemid'=>$content->id, 'filepath'=>'/', 'filearea'=>'data_content'); + $file_record = array('contextid'=>$this->context->id, 'component'=>'mod_data', 'filearea'=>'content', 'itemid'=>$content->id, 'filepath'=>'/'); if (!$draftfile->is_directory()) { $file_record['filename'] = $draftfile->get_filename(); @@ -263,7 +260,7 @@ function update_thumbnail($content, $file) { // If thumbnail width and height are BOTH not specified then no thumbnail is generated, and // additionally an attempted delete of the existing thumbnail takes place. $fs = get_file_storage(); - $file_record = array('contextid'=>$file->get_contextid(), 'filearea'=>$file->get_filearea(), + $file_record = array('contextid'=>$file->get_contextid(), 'component'=>$file->get_component(), 'filearea'=>$file->get_filearea(), 'itemid'=>$file->get_itemid(), 'filepath'=>$file->get_filepath(), 'filename'=>'thumb_'.$file->get_filename(), 'userid'=>$file->get_userid()); try { diff --git a/mod/data/lib.php b/mod/data/lib.php index 41c1e03fcc965..0b460e28cda26 100755 --- a/mod/data/lib.php +++ b/mod/data/lib.php @@ -359,7 +359,7 @@ function delete_content($recordid=0) { if ($rs = $DB->get_recordset('data_content', $conditions)) { $fs = get_file_storage(); foreach ($rs as $content) { - $fs->delete_area_files($this->context->id, 'data_content', $content->id); + $fs->delete_area_files($this->context->id, 'mod_data', 'content', $content->id); } $rs->close(); } @@ -902,7 +902,7 @@ function data_delete_instance($id) { // takes the dataid // files $fs = get_file_storage(); - $fs->delete_area_files($context->id, 'data_content'); + $fs->delete_area_files($context->id, 'mod_data'); // get all the records in this data $sql = "SELECT r.id @@ -2710,24 +2710,26 @@ function data_get_file_areas($course, $cm, $context) { * Serves the data attachments. Implements needed access control ;-) * * @param object $course - * @param object $cminfo + * @param object $cm * @param object $context * @param string $filearea * @param array $args * @param bool $forcedownload * @return bool false if file not found, does not return if found - justsend the file */ -function data_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) { +function data_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG, $DB; - if (!$cminfo->uservisible) { + if ($context->contextlevel != CONTEXT_MODULE) { return false; } - if ($filearea === 'data_content') { + require_login($course, false, $cm); + + if ($filearea === 'content') { $contentid = (int)array_shift($args); - if (!$cm = get_coursemodule_from_instance('data', $cminfo->instance, $course->id)) { + if (!$cm = get_coursemodule_from_instance('data', $cm->instance, $course->id)) { return false; } @@ -2766,8 +2768,8 @@ function data_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedow $fieldobj = data_get_field($field, $data, $cm); - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.'data_content'.$content->id.$relativepath; + $relativepath = implode('/', $args); + $fullpath = "/$context->id/mod_data/content/$content->id/$relativepath"; if (!$fieldobj->file_ok($relativepath)) { return false; diff --git a/mod/feedback/backup/moodle2/backup_feedback_stepslib.php b/mod/feedback/backup/moodle2/backup_feedback_stepslib.php index 12b728d000bc9..099125676f74a 100644 --- a/mod/feedback/backup/moodle2/backup_feedback_stepslib.php +++ b/mod/feedback/backup/moodle2/backup_feedback_stepslib.php @@ -129,9 +129,9 @@ protected function define_structure() { // Define file annotations - $feedback->annotate_files(array('feedback_intro'), null); // This file area hasn't itemid + $feedback->annotate_files('mod_feedback', 'intro', null); // This file area hasn't itemid - $item->annotate_files(array('feedback_item'), 'id'); + $item->annotate_files('mod_feedback', 'item', 'id'); // Return the root element (feedback), wrapped into standard activity structure return $this->prepare_activity_structure($feedback); diff --git a/mod/feedback/item/label/lib.php b/mod/feedback/item/label/lib.php index cb7aa798a5254..4ca4632a6a9a3 100644 --- a/mod/feedback/item/label/lib.php +++ b/mod/feedback/item/label/lib.php @@ -9,7 +9,7 @@ class feedback_item_label extends feedback_item_base { var $item_form; var $context; var $item; - + function init() { global $CFG; $this->presentationoptions = array('maxfiles' => EDITOR_UNLIMITED_FILES, 'trusttext'=>true); @@ -43,8 +43,8 @@ function build_editform($item, $feedback, $cm) { 'feedback'=>$feedback->id); $this->context = get_context_instance(CONTEXT_MODULE, $cm->id); - - + + //preparing the editor for new file-api $item->presentationformat = FORMAT_HTML; $item->presentationtrust = 1; @@ -52,18 +52,19 @@ function build_editform($item, $feedback, $cm) { 'presentation', //name of the form element $this->presentationoptions, $this->context, - 'feedback_item', //the filearea + 'mod_feedback', + 'item', //the filearea $item->id); - + //build the form $this->item_form = new feedback_label_form('edit_item.php', array('item'=>$item, 'common'=>$commonparams, 'positionlist'=>$positionlist, 'position'=>$position, 'presentationoptions'=>$this->presentationoptions)); } - + //this function only can used after the call of build_editform() function show_editform() { $this->item_form->display(); } - + function is_cancelled() { return $this->item_form->is_cancelled(); } @@ -77,37 +78,38 @@ function get_data() { function save_item() { global $DB; - + if(!$item = $this->item_form->get_data()) { return false; } - + if($item->clone_item) { $item->id = ''; //to clone this item $item->position++; } $item->presentation = ''; - + $item->hasvalue = $this->get_hasvalue(); if(!$item->id) { $item->id = $DB->insert_record('feedback_item', $item); }else { $DB->update_record('feedback_item', $item); } - + $item = file_postupdate_standard_editor($item, 'presentation', $this->presentationoptions, $this->context, - 'feedback_item', + 'mod_feedback', + 'item', $item->id); - + $DB->update_record('feedback_item', $item); - + return $DB->get_record('feedback_item', array('id'=>$item->id)); } - + function print_item($item){ global $DB; @@ -115,21 +117,21 @@ function print_item($item){ if(!$item->feedback AND $item->template) { $template = $DB->get_record('feedback_template', array('id'=>$item->template)); $context = get_context_instance(CONTEXT_COURSE, $template->course); - $filearea = 'course_summary'; + $filearea = 'template'; }else { $cm = get_coursemodule_from_instance('feedback', $item->feedback); $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $filearea = 'feedback_item'; + $filearea = 'item'; } - + $item->presentationformat = FORMAT_HTML; $item->presentationtrust = 1; - - $output = file_rewrite_pluginfile_urls($item->presentation, 'pluginfile.php', $context->id, $filearea, $item->id); + + $output = file_rewrite_pluginfile_urls($item->presentation, 'pluginfile.php', $context->id, 'mod_feedback', $filearea, $item->id); echo format_text($output, FORMAT_HTML); } - /** + /** * print the item at the edit-page of feedback * * @global object @@ -138,7 +140,7 @@ function print_item($item){ */ function print_item_preview($item) { global $OUTPUT, $DB; - + if($item->dependitem) { if($dependitem = $DB->get_record('feedback_item', array('id'=>$item->dependitem))) { echo ' '; @@ -146,8 +148,8 @@ function print_item_preview($item) { } $this->print_item($item); } - - /** + + /** * print the item at the complete-page of feedback * * @global object @@ -160,7 +162,7 @@ function print_item_complete($item, $value = '', $highlightrequire = false) { $this->print_item($item); } - /** + /** * print the item at the complete-page of feedback * * @global object @@ -179,19 +181,19 @@ function create_value($data) { function compare_value($item, $dbvalue, $dependvalue) { return false; } - + //used by create_item and update_item functions, //when provided $data submitted from feedback_show_edit function get_presentation($data) { // $context = get_context_instance(CONTEXT_MODULE, $data->cmid); - + // $presentation = new object(); // $presentation->id = null; // $presentation->definition = ''; // $presentation->format = FORMAT_HTML; - + // $draftid_editor = file_get_submitted_draft_itemid('presentation'); - // $currenttext = file_prepare_draft_area($draftid_editor, $context->id, 'feedback_item_label', $presentation->id, array('subdirs'=>true), $presentation->definition); + // $currenttext = file_prepare_draft_area($draftid_editor, $context->id, 'mod_feedback', 'item_label', $presentation->id, array('subdirs'=>true), $presentation->definition); // $presentation->entry = array('text'=>$currenttext, 'format'=>$presentation->format, 'itemid'=>$draftid_editor); // return $data->presentation; @@ -199,9 +201,9 @@ function get_presentation($data) { function postupdate($item) { global $DB; - + $context = get_context_instance(CONTEXT_MODULE, $item->cmid); - $item = file_postupdate_standard_editor($item, 'presentation', $this->presentationoptions, $context, 'feedback_item', $item->id); + $item = file_postupdate_standard_editor($item, 'presentation', $this->presentationoptions, $context, 'mod_feedback', 'item', $item->id); // $item = new object(); // $item->id = $data->id @@ -210,11 +212,11 @@ function postupdate($item) { } return false; } - + function get_hasvalue() { return 0; } - + function can_switch_require() { return false; } diff --git a/mod/feedback/lib.php b/mod/feedback/lib.php index 0f8f2b75c9ce6..f8b418e294266 100644 --- a/mod/feedback/lib.php +++ b/mod/feedback/lib.php @@ -138,40 +138,38 @@ function feedback_update_instance($feedback) { * Serves the files included in feedback items like label. Implements needed access control ;-) * * @param object $course - * @param object $cminfo + * @param object $cm * @param object $context * @param string $filearea * @param array $args * @param bool $forcedownload * @return bool false if file not found, does not return if found - justsend the file */ -function feedback_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) { +function feedback_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG, $DB; - if (!$cminfo->uservisible) { + if ($context->contextlevel != CONTEXT_MODULE) { return false; } - if($filearea === 'feedback_template') { + require_login($course, false, $cm); + + if ($filearea === 'template') { $usedcontext = get_context_instance(CONTEXT_COURSE, $course->id); }else { $usedcontext = $context; } - if ($filearea === 'feedback_item' OR $filearea === 'feedback_template') { + if ($filearea === 'item' OR $filearea === 'template') { $itemid = (int)array_shift($args); - if (!$cm = get_coursemodule_from_instance('feedback', $cminfo->instance, $course->id)) { - return false; - } - require_course_login($course, true, $cm); if (!$item = $DB->get_record('feedback_item', array('id'=>$itemid))) { return false; } - if (!$feedback = $DB->get_record('feedback', array('id'=>$cminfo->instance))) { + if (!$feedback = $DB->get_record('feedback', array('id'=>$cm->instance))) { return false; } @@ -179,14 +177,14 @@ function feedback_pluginfile($course, $cminfo, $context, $filearea, $args, $forc return false; } - if ($item->feedback == $cminfo->instance) { + if ($item->feedback == $cm->instance) { $filecontext = $usedcontext; } else { return false; } - $relativepath = '/'.implode('/', $args); - $fullpath = $filecontext->id.$filearea.$itemid.$relativepath; + $relativepath = implode('/', $args); + $fullpath = "/$filecontext->id/mod_feedback/$filearea/$itemid/$relativepath"; $fs = get_file_storage(); if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { @@ -919,7 +917,6 @@ function feedback_save_as_template($feedback, $name, $ispublic = 0) { global $DB; $fs = get_file_storage(); -die('TODO: MDL-21227 feedback code must not touch course summary files, code needs to be fixed, sorry'); if (!$feedbackitems = $DB->get_records('feedback_item', array('feedback'=>$feedback->id))) { return false; } @@ -948,11 +945,12 @@ function feedback_save_as_template($feedback, $name, $ispublic = 0) { $t_item->template = $newtempl->id; $t_item->id = $DB->insert_record('feedback_item', $t_item); //copy all included files to the feedback_template filearea - if ($itemfiles = $fs->get_area_files($f_context->id, 'feedback_item', $item->id, "id", false)) { + if ($itemfiles = $fs->get_area_files($f_context->id, 'mod_feedback', 'item', $item->id, "id", false)) { foreach($itemfiles as $ifile) { $file_record = new object(); $file_record->contextid = $c_context->id; - $file_record->filearea = 'course_summary'; + $file_record->component = 'mod_feedback'; + $file_record->filearea = 'template'; $file_record->itemid = $t_item->id; $fs->create_file_from_storedfile($file_record, $ifile); } @@ -986,7 +984,6 @@ function feedback_save_as_template($feedback, $name, $ispublic = 0) { function feedback_delete_template($id) { global $DB; -die('TODO: MDL-21227 feedback code must not touch course summary files, code needs to be fixed, sorry'); $template = $DB->get_record("feedback_template", array("id"=>$id)); //deleting the files from the item @@ -996,8 +993,8 @@ function feedback_delete_template($id) { if($t_items = $DB->get_records("feedback_item", array("template"=>$id))) { foreach($t_items as $t_item) { - if ($templatefiles = $fs->get_area_files($context->id, 'course_summary', $t_item->id, "id", false)) { - $fs->delete_area_files($context->id, 'course_summary', $t_item->id); + if ($templatefiles = $fs->get_area_files($context->id, 'mod_feedback', 'template', $t_item->id, "id", false)) { + $fs->delete_area_files($context->id, 'mod_feedback', 'template', $t_item->id); } } } @@ -1020,8 +1017,6 @@ function feedback_items_from_template($feedback, $templateid, $deleteold = false global $DB; $fs = get_file_storage(); -die('TODO: MDL-21227 feedback code must not touch course summary files, code needs to be fixed, sorry'); - //get all templateitems if(!$templitems = $DB->get_records('feedback_item', array('template'=>$templateid))) { return false; @@ -1068,11 +1063,12 @@ function feedback_items_from_template($feedback, $templateid, $deleteold = false $item->id = $DB->insert_record('feedback_item', $item); //TODO: moving the files to the new items - if ($templatefiles = $fs->get_area_files($c_context->id, 'course_summary', $t_item->id, "id", false)) { + if ($templatefiles = $fs->get_area_files($c_context->id, 'mod_feedback', 'template', $t_item->id, "id", false)) { foreach($templatefiles as $tfile) { $file_record = new object(); $file_record->contextid = $f_context->id; - $file_record->filearea = 'feedback_item'; + $file_record->component = 'mod_feedback'; + $file_record->filearea = 'item'; $file_record->itemid = $item->id; $fs->create_file_from_storedfile($file_record, $tfile); } @@ -1296,8 +1292,8 @@ function feedback_delete_item($itemid, $renumber = true){ } $context = get_context_instance(CONTEXT_MODULE, $cm->id); - if ($itemfiles = $fs->get_area_files($context->id, 'feedback_item', $item->id, "id", false)) { - $fs->delete_area_files($context->id, 'feedback_item', $item->id); + if ($itemfiles = $fs->get_area_files($context->id, 'mod_feedback', 'item', $item->id, "id", false)) { + $fs->delete_area_files($context->id, 'mod_feedback', 'item', $item->id); } $DB->delete_records("feedback_value", array("item"=>$itemid)); diff --git a/mod/folder/backup/moodle2/backup_folder_stepslib.php b/mod/folder/backup/moodle2/backup_folder_stepslib.php index e97c552ade2cd..d715b802057e8 100644 --- a/mod/folder/backup/moodle2/backup_folder_stepslib.php +++ b/mod/folder/backup/moodle2/backup_folder_stepslib.php @@ -51,7 +51,8 @@ protected function define_structure() { // (none) // Define file annotations - $folder->annotate_files(array('folder_intro', 'folder_content'), null); // This file area hasn't itemid + $folder->annotate_files('mod_folder', 'intro', null); + $folder->annotate_files('mod_folder', 'content', null); // Return the root element (folder), wrapped into standard activity structure return $this->prepare_activity_structure($folder); diff --git a/mod/folder/db/upgradelib.php b/mod/folder/db/upgradelib.php index 1d0c1bd187714..6c39bf2bcab9f 100644 --- a/mod/folder/db/upgradelib.php +++ b/mod/folder/db/upgradelib.php @@ -72,8 +72,8 @@ function folder_20_migrate() { // copy files in given directory, skip moddata and backups! $context = get_context_instance(CONTEXT_MODULE, $candidate->cmid); $coursecontext = get_context_instance(CONTEXT_COURSE, $candidate->course); - $files = $fs->get_directory_files($coursecontext->id, 'course_content', 0, $directory, true, true); - $file_record = array('contextid'=>$context->id, 'filearea'=>'folder_content', 'itemid'=>0); + $files = $fs->get_directory_files($coursecontext->id, 'course', 'legacy', 0, $directory, true, true); + $file_record = array('contextid'=>$context->id, 'component'=>'mod_folder', 'filearea'=>'content', 'itemid'=>0); foreach ($files as $file) { $path = $file->get_filepath(); if (stripos($path, '/backupdata/') === 0 or stripos($path, '/moddata/') === 0) { diff --git a/mod/folder/edit.php b/mod/folder/edit.php index 6fb7dd2b61e61..1df5c123d8cef 100644 --- a/mod/folder/edit.php +++ b/mod/folder/edit.php @@ -18,7 +18,7 @@ /** * Manage files in folder module instance * - * @package mod-folder + * @package mod_folder * @copyright 2010 Dongsheng Cai * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -31,38 +31,37 @@ $id = required_param('id', PARAM_INT); // Course module ID $cm = get_coursemodule_from_id('folder', $id, 0, false, MUST_EXIST); -$context = get_context_instance(CONTEXT_MODULE, $cm->id); +$context = get_context_instance(CONTEXT_MODULE, $cm->id, MUST_EXIST); $folder = $DB->get_record('folder', array('id'=>$cm->instance), '*', MUST_EXIST); $course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST); -require_login($course, true, $cm); +require_login($course, false, $cm); require_capability('moodle/course:managefiles', $context); add_to_log($course->id, 'folder', 'edit', 'edit.php?id='.$cm->id, $folder->id, $cm->id); -$data = new stdclass; -$data->id = $cm->id; - -$options = array('subdirs'=>1, 'maxbytes'=>$CFG->maxbytes, 'maxfiles'=>-1, 'accepted_types'=>'*', 'return_types'=>FILE_INTERNAL); - $PAGE->set_url('/mod/folder/edit.php', array('id' => $cm->id)); - $PAGE->set_title($course->shortname.': '.$folder->name); $PAGE->set_heading($course->fullname); $PAGE->set_activity_record($folder); +$data = new object(); +$data->id = $cm->id; +$options = array('subdirs'=>1, 'maxbytes'=>$CFG->maxbytes, 'maxfiles'=>-1, 'accepted_types'=>'*', 'return_types'=>FILE_INTERNAL); +file_prepare_standard_filemanager($data, 'files', $options, $context, 'mod_folder', 'content', 0); -$form = new mod_folder_edit_form(null, array('id'=>$cm->id)); +$mform = new mod_folder_edit_form(null, array('data'=>$data, 'options'=>$options)); -if ($formdata = $form->get_data()) { - $formdata = file_postupdate_standard_filemanager($formdata, 'files', $options, $context, 'folder_content', 0); +if ($mform->is_cancelled()) { + redirect(new moodle_url('/mod/folder/view.php', array('id'=>$cm->id))); + +} else if ($formdata = $mform->get_data()) { + $formdata = file_postupdate_standard_filemanager($formdata, 'files', $options, $context, 'mod_folder', 'content', 0); redirect(new moodle_url('/mod/folder/view.php', array('id'=>$cm->id))); -} else { - file_prepare_standard_filemanager($data, 'files', $options, $context, 'folder_content', 0); - $form->set_data($data); - echo $OUTPUT->header(); - echo $OUTPUT->box_start('generalbox foldertree'); - $form->display(); - echo $OUTPUT->box_end(); - echo $OUTPUT->footer(); } + +echo $OUTPUT->header(); +echo $OUTPUT->box_start('generalbox foldertree'); +$mform->display(); +echo $OUTPUT->box_end(); +echo $OUTPUT->footer(); diff --git a/mod/folder/edit_form.php b/mod/folder/edit_form.php index a6121c13a5e12..9cf731192295a 100644 --- a/mod/folder/edit_form.php +++ b/mod/folder/edit_form.php @@ -16,20 +16,29 @@ // along with Moodle. If not, see . /** - * A moodle form to manage files + * A moodle form to manage folder files * - * @package mod-folder + * @package mod_folder * @copyright 2010 Dongsheng Cai * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +defined('MOODLE_INTERNAL') || die(); + +require_once("$CFG->libdir/formslib.php"); + class mod_folder_edit_form extends moodleform { function definition() { - $mform =& $this->_form; - $cmid = $this->_customdata['id']; - $mform->addElement('hidden', 'id', $cmid); - $mform->addElement('filemanager', 'files_filemanager', get_string('files'), null, array('subdirs'=>1, 'accepted_types'=>'*', 'return_types'=>FILE_INTERNAL)); + $mform = $this->_form; + + $data = $this->_customdata['data']; + $options = $this->_customdata['options']; + + $mform->addElement('hidden', 'id', $data->id); + $mform->addElement('filemanager', 'files_filemanager', get_string('files'), null, $options); $submit_string = get_string('submit'); $this->add_action_buttons(true, $submit_string); + + $this->set_data($data); } } diff --git a/mod/folder/lib.php b/mod/folder/lib.php index 786ff9db2bc1e..6fdad3145f8c0 100644 --- a/mod/folder/lib.php +++ b/mod/folder/lib.php @@ -23,6 +23,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +defined('MOODLE_INTERNAL') || die(); + /** * List of features supported in Folder module * @param string $feature FEATURE_xx constant for requested feature @@ -97,7 +99,7 @@ function folder_add_instance($data, $mform) { $context = get_context_instance(CONTEXT_MODULE, $cmid); if ($draftitemid) { - file_save_draft_area_files($draftitemid, $context->id, 'folder_content', 0, array('subdirs'=>true)); + file_save_draft_area_files($draftitemid, $context->id, 'mod_folder', 'content', 0, array('subdirs'=>true)); } return $data->id; @@ -123,7 +125,7 @@ function folder_update_instance($data, $mform) { $context = get_context_instance(CONTEXT_MODULE, $cmid); if ($draftitemid = file_get_submitted_draft_itemid('files')) { - file_save_draft_area_files($draftitemid, $context->id, 'folder_content', 0, array('subdirs'=>true)); + file_save_draft_area_files($draftitemid, $context->id, 'mod_folder', 'content', 0, array('subdirs'=>true)); } return true; @@ -218,9 +220,8 @@ function folder_get_participants($folderid) { */ function folder_get_file_areas($course, $cm, $context) { $areas = array(); - if (has_capability('moodle/course:managefiles', $context)) { - $areas['folder_content'] = get_string('foldercontent', 'folder'); - } + $areas['content'] = get_string('foldercontent', 'folder'); + return $areas; } @@ -240,24 +241,26 @@ function folder_get_file_areas($course, $cm, $context) { function folder_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) { global $CFG; - $canwrite = has_capability('moodle/course:managefiles', $context); - $fs = get_file_storage(); + if ($filearea === 'content') { + $fs = get_file_storage(); - if ($filearea === 'folder_content') { $filepath = is_null($filepath) ? '/' : $filepath; $filename = is_null($filename) ? '.' : $filename; - - $urlbase = $CFG->wwwroot.'/pluginfile.php'; - if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) { + if (!$storedfile = $fs->get_file($context->id, 'mod_folder', 'content', 0, $filepath, $filename)) { if ($filepath === '/' and $filename === '.') { - $storedfile = new virtual_root_file($context->id, $filearea, 0); + $storedfile = new virtual_root_file($context->id, 'mod_folder', 'content', 0); } else { // not found return null; } } + require_once("$CFG->dirroot/mod/folder/locallib.php"); + $urlbase = $CFG->wwwroot.'/pluginfile.php'; + + // students may read files here + $canwrite = has_capability('moodle/course:managefiles', $context); return new folder_content_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, $canwrite, false); } @@ -270,36 +273,32 @@ function folder_get_file_info($browser, $areas, $course, $cm, $context, $fileare * Serves the folder files. * * @param object $course - * @param object $cminfo + * @param object $cm * @param object $context * @param string $filearea * @param array $args * @param bool $forcedownload * @return bool false if file not found, does not return if found - justsend the file */ -function folder_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) { +function folder_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG, $DB; - if (!$cminfo->uservisible) { + if ($context->contextlevel != CONTEXT_MODULE) { return false; } - if ($filearea !== 'folder_content') { - // intro is handled automatically in pluginfile.php - return false; - } + require_course_login($course, true, $cm); - if (!$cm = get_coursemodule_from_instance('folder', $cminfo->instance, $course->id)) { + if ($filearea !== 'content') { + // intro is handled automatically in pluginfile.php return false; } - require_course_login($course, true, $cm); - array_shift($args); // ignore revision - designed to prevent caching problems only $fs = get_file_storage(); - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.$filearea.'0'.$relativepath; + $relativepath = implode('/', $args); + $fullpath = "/$context->id/mod_folder/content/0/$relativepath"; if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { return false; } diff --git a/mod/folder/locallib.php b/mod/folder/locallib.php index 1d747ff8e4f42..aac77a10711d4 100644 --- a/mod/folder/locallib.php +++ b/mod/folder/locallib.php @@ -23,71 +23,11 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +defined('MOODLE_INTERNAL') || die(); + require_once("$CFG->dirroot/mod/folder/lib.php"); -require_once("$CFG->libdir/file/file_browser.php"); require_once("$CFG->libdir/filelib.php"); -/** - * Prints file folder tree view - * @param object $folder instance - * @param object $cm instance - * @param object $course - * @return void - */ -function folder_print_tree($folder, $cm, $course) { - global $PAGE; - - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $fs = get_file_storage(); - $dir = $fs->get_area_tree($context->id, 'folder_content', 0); - echo '
'; - echo folder_htmllize_tree($dir, $folder, $context); - echo '
'; - $PAGE->requires->js_init_call('M.mod_folder.init_tree', array(true)); -} - -/** - * Internal function - creates htmls structure suitable for YUI tree. - */ -function folder_htmllize_tree($dir, $folder, $context) { - if (empty($dir['subdirs']) and empty($dir['files'])) { - return ''; - } - $result = '
    '; - foreach ($dir['subdirs'] as $subdir) { - $result .= '
  • '.s($subdir['dirname']).' '.folder_htmllize_tree($subdir, $folder, $context).'
  • '; - } - foreach ($dir['files'] as $file) { - $result .= '
  • '.folder_get_file_link($file, $folder, $context).'
  • '; - } - $result .= '
'; - - return $result; -} - -/** - * Returns file link - * @param object $file - * @param object $folder - * @param object $context - * @return string html link - */ -function folder_get_file_link($file, $folder, $context) { - global $CFG, $OUTPUT; - - $strfile = get_string('file'); - $strdownload = get_string('download'); - $urlbase = "$CFG->wwwroot/pluginfile.php"; - $path = '/'.$context->id.'/folder_content/'.$folder->revision.$file->get_filepath().$file->get_filename(); - $viewurl = file_encode_url($urlbase, $path, false); - $downloadurl = file_encode_url($urlbase, $path, true); - $downicon = $OUTPUT->pix_url('t/down'); - $mimeicon = $OUTPUT->pix_url(file_mimetype_icon($file->get_mimetype())); - - $downloadurl = " \"$strdownload\""; - return "\"$strfile\" ".s($file->get_filename()).''.$downloadurl; -} - /** * File browsing support class */ diff --git a/mod/folder/mod_form.php b/mod/folder/mod_form.php index 9aaa699f8f4b0..dc2bd4f0e11a4 100644 --- a/mod/folder/mod_form.php +++ b/mod/folder/mod_form.php @@ -67,7 +67,7 @@ function data_preprocessing(&$default_values) { if ($this->current->instance) { // editing existing instance - copy existing files into draft area $draftitemid = file_get_submitted_draft_itemid('files'); - file_prepare_draft_area($draftitemid, $this->context->id, 'folder_content', 0, array('subdirs'=>true)); + file_prepare_draft_area($draftitemid, $this->context->id, 'mod_folder', 'content', 0, array('subdirs'=>true)); $default_values['files'] = $draftitemid; } } diff --git a/mod/folder/renderer.php b/mod/folder/renderer.php new file mode 100644 index 0000000000000..1e249a085cb5c --- /dev/null +++ b/mod/folder/renderer.php @@ -0,0 +1,67 @@ +render(new folder_tree($folder, $cm, $course)); + } + + public function render_folder_tree(folder_tree $tree) { + global $PAGE; + + echo '
'; + echo $this->htmllize_tree($tree, $tree->dir); + echo '
'; + $this->page->requires->js_init_call('M.mod_folder.init_tree', array(true)); + } + + /** + * Internal function - creates htmls structure suitable for YUI tree. + */ + protected function htmllize_tree($tree, $dir) { + global $CFG; + + if (empty($dir['subdirs']) and empty($dir['files'])) { + return ''; + } + $result = '
    '; + foreach ($dir['subdirs'] as $subdir) { + $result .= '
  • '.s($subdir['dirname']).' '.$this->htmllize_tree($tree, $subdir).'
  • '; + } + foreach ($dir['files'] as $file) { + $url = file_encode_url("$CFG->wwwroot/pluginfile.php", '/'.$tree->context->id.'/mod_folder/content/'.$tree->folder->revision.$file->get_filepath().$file->get_filename(), true); + $filename = $file->get_filename(); + $result .= '
  • '.html_writer::link($url, $filename).'
  • '; + } + $result .= '
'; + + return $result; + } +} + +class folder_tree implements renderable { + public $context; + public $folder; + public $cm; + public $course; + public $dir; + + public function __construct($folder, $cm, $course) { + $this->folder = $folder; + $this->cm = $cm; + $this->course = $course; + + $this->context = get_context_instance(CONTEXT_MODULE, $cm->id); + $fs = get_file_storage(); + $this->dir = $fs->get_area_tree($this->context->id, 'mod_folder', 'content', 0); + } +} \ No newline at end of file diff --git a/mod/folder/view.php b/mod/folder/view.php index b0ecda924a34f..3e8c846a805d9 100644 --- a/mod/folder/view.php +++ b/mod/folder/view.php @@ -25,6 +25,7 @@ require('../../config.php'); require_once("$CFG->dirroot/mod/folder/locallib.php"); +require_once("$CFG->dirroot/repository/lib.php"); require_once($CFG->libdir . '/completionlib.php'); $id = optional_param('id', 0, PARAM_INT); // Course module ID @@ -55,24 +56,28 @@ $PAGE->set_title($course->shortname.': '.$folder->name); $PAGE->set_heading($course->fullname); $PAGE->set_activity_record($folder); -echo $OUTPUT->header(); -echo $OUTPUT->heading(format_string($folder->name), 2); + +$output = $PAGE->get_renderer('mod_folder'); + +echo $output->header(); + +echo $output->heading(format_string($folder->name), 2); if (trim(strip_tags($folder->intro))) { - echo $OUTPUT->box_start('mod_introbox', 'pageintro'); + echo $output->box_start('mod_introbox', 'pageintro'); echo format_module_intro('folder', $folder, $cm->id); - echo $OUTPUT->box_end(); + echo $output->box_end(); } -echo $OUTPUT->box_start('generalbox foldertree'); -echo $OUTPUT->area_file_tree_viewer($context->id, 'folder_content', 0); -echo $OUTPUT->box_end(); +echo $output->box_start('generalbox foldertree'); +echo $output->folder_tree($folder, $cm, $course); +echo $output->box_end(); if (has_capability('moodle/course:managefiles', $context)) { - echo $OUTPUT->container_start('mdl-align'); - echo $OUTPUT->single_button(new moodle_url('/mod/folder/edit.php', array('id'=>$id)), get_string('edit')); - echo $OUTPUT->container_end(); + echo $output->container_start('mdl-align'); + echo $output->single_button(new moodle_url('/mod/folder/edit.php', array('id'=>$id)), get_string('edit')); + echo $output->container_end(); } -echo $OUTPUT->footer(); +echo $output->footer(); diff --git a/mod/forum/backup/moodle2/backup_forum_stepslib.php b/mod/forum/backup/moodle2/backup_forum_stepslib.php index 4b1e2f113f608..3345cd8d1d6da 100644 --- a/mod/forum/backup/moodle2/backup_forum_stepslib.php +++ b/mod/forum/backup/moodle2/backup_forum_stepslib.php @@ -134,9 +134,10 @@ protected function define_structure() { // Define file annotations - $forum->annotate_files(array('forum_intro'), null); // This file area hasn't itemid + $forum->annotate_files('mod_forum', 'intro', null); // This file area hasn't itemid - $post->annotate_files(array('forum_post', 'forum_attachment'), 'id'); + $post->annotate_files('mod_forum', 'post', 'id'); + $post->annotate_files('mod_forum', 'attachment', 'id'); // Return the root element (forum), wrapped into standard activity structure return $this->prepare_activity_structure($forum); diff --git a/mod/forum/db/upgrade.php b/mod/forum/db/upgrade.php index b6e505dcc9ad2..c1a838cb6c0f5 100644 --- a/mod/forum/db/upgrade.php +++ b/mod/forum/db/upgrade.php @@ -125,7 +125,7 @@ function xmldb_forum_upgrade($oldversion) { } $context = get_context_instance(CONTEXT_MODULE, $post->cmid); - $filearea = 'forum_attachment'; + $filearea = 'attachment'; $filename = clean_param($post->attachment, PARAM_FILE); if ($filename === '') { echo $OUTPUT->notification("Unsupported post filename, skipping: ".$filepath); @@ -133,8 +133,8 @@ function xmldb_forum_upgrade($oldversion) { $DB->update_record('forum_posts', $post); continue; } - if (!$fs->file_exists($context->id, $filearea, $post->id, '/', $filename)) { - $file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>$post->id, 'filepath'=>'/', 'filename'=>$filename, 'userid'=>$post->userid); + if (!$fs->file_exists($context->id, 'mod_form', $filearea, $post->id, '/', $filename)) { + $file_record = array('contextid'=>$context->id, 'component'=>'mod_form', 'filearea'=>$filearea, 'itemid'=>$post->id, 'filepath'=>'/', 'filename'=>$filename, 'userid'=>$post->userid); if ($fs->create_file_from_pathname($file_record, $filepath)) { $post->attachment = '1'; if ($DB->update_record('forum_posts', $post)) { diff --git a/mod/forum/lib.php b/mod/forum/lib.php index 749ba9b6edda3..568aab2ddfe42 100644 --- a/mod/forum/lib.php +++ b/mod/forum/lib.php @@ -3103,7 +3103,7 @@ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=fa $post->course = $course->id; $post->forum = $forum->id; - $post->message = file_rewrite_pluginfile_urls($post->message, 'pluginfile.php', $modcontext->id, 'forum_post', $post->id); + $post->message = file_rewrite_pluginfile_urls($post->message, 'pluginfile.php', $modcontext->id, 'mod_forum', 'post', $post->id); // caching if (!isset($cm->cache)) { @@ -3717,13 +3717,13 @@ function forum_move_attachments($discussion, $forumfrom, $forumto) { // loop through all posts, better not use attachment flag ;-) if ($posts = $DB->get_records('forum_posts', array('discussion'=>$discussion->id), '', 'id, attachment')) { foreach ($posts as $post) { - if ($oldfiles = $fs->get_area_files($oldcontext->id, 'forum_attachment', $post->id, "id", false)) { + if ($oldfiles = $fs->get_area_files($oldcontext->id, 'mod_forum', 'attachment', $post->id, "id", false)) { foreach ($oldfiles as $oldfile) { $file_record = new object(); $file_record->contextid = $newcontext->id; $fs->create_file_from_storedfile($file_record, $oldfile); } - $fs->delete_area_files($oldcontext->id, 'forum_attachment', $post->id); + $fs->delete_area_files($oldcontext->id, 'mod_forum', 'attachment', $post->id); if ($post->attachment != '1') { //weird - let's fix it $post->attachment = '1'; @@ -3770,7 +3770,6 @@ function forum_print_attachments($post, $cm, $type) { $strattachment = get_string('attachment', 'forum'); $fs = get_file_storage(); - $browser = get_file_browser(); $imagereturn = ''; $output = ''; @@ -3778,13 +3777,13 @@ function forum_print_attachments($post, $cm, $type) { $canexport = (has_capability('mod/forum:exportpost', $context) || ($post->userid == $USER->id && has_capability('mod/forum:exportownpost', $context))); require_once($CFG->libdir.'/portfoliolib.php'); - if ($files = $fs->get_area_files($context->id, 'forum_attachment', $post->id, "timemodified", false)) { + if ($files = $fs->get_area_files($context->id, 'mod_forum', 'attachment', $post->id, "timemodified", false)) { $button = new portfolio_add_button(); foreach ($files as $file) { $filename = $file->get_filename(); $mimetype = $file->get_mimetype(); $iconimage = ''.$mimetype.''; - $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$context->id.'/forum_attachment/'.$post->id.'/'.$filename); + $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$context->id.'/mod_forum/attachment/'.$post->id.'/'.$filename); if ($type == 'html') { $output .= "$iconimage "; @@ -3847,33 +3846,29 @@ function forum_get_file_areas($course, $cm, $context) { * Serves the forum attachments. Implements needed access control ;-) * * @param object $course - * @param object $cminfo + * @param object $cm * @param object $context * @param string $filearea * @param array $args * @param bool $forcedownload * @return bool false if file not found, does not return if found - justsend the file */ -function forum_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) { +function forum_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG, $DB; - if (!$cminfo->uservisible) { + if ($context->contextlevel != CONTEXT_MODULE) { return false; } - $fileareas = array('forum_attachment', 'forum_post'); + require_course_login($course, true, $cm); + + $fileareas = array('attachment', 'post'); if (!in_array($filearea, $fileareas)) { return false; } $postid = (int)array_shift($args); - if (!$cm = get_coursemodule_from_instance('forum', $cminfo->instance, $course->id)) { - return false; - } - - require_course_login($course, true, $cm); - if (!$post = $DB->get_record('forum_posts', array('id'=>$postid))) { return false; } @@ -3882,19 +3877,19 @@ function forum_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedo return false; } - if (!$forum = $DB->get_record('forum', array('id'=>$cminfo->instance))) { + if (!$forum = $DB->get_record('forum', array('id'=>$cm->instance))) { return false; } $fs = get_file_storage(); - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.$filearea.$postid.$relativepath; + $relativepath = implode('/', $args); + $fullpath = "/$context->id/mod_forum/$filearea/$postid/$relativepath"; if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { return false; } // Make sure groups allow this user to see this file - if ($discussion->groupid > 0 and $groupmode = groups_get_activity_groupmode($cminfo, $course)) { // Groups are being used + if ($discussion->groupid > 0 and $groupmode = groups_get_activity_groupmode($cm, $course)) { // Groups are being used if (!groups_group_exists($discussion->groupid)) { // Can't find group return false; // Be safe and don't send it to anyone } @@ -3941,7 +3936,7 @@ function forum_add_attachment($post, $forum, $cm, $mform=null, &$message=null) { $info = file_get_draft_area_info($post->attachments); $present = ($info['filecount']>0) ? '1' : ''; - file_save_draft_area_files($post->attachments, $context->id, 'forum_attachment', $post->id); + file_save_draft_area_files($post->attachments, $context->id, 'mod_forum', 'attachment', $post->id); $DB->set_field('forum_posts', 'attachment', $present, array('id'=>$post->id)); @@ -3974,7 +3969,7 @@ function forum_add_new_post($post, $mform, &$message) { $post->attachment = ""; $post->id = $DB->insert_record("forum_posts", $post); - $message = file_save_draft_area_files($post->itemid, $context->id, 'forum_post', $post->id, array('subdirs'=>true), $message); + $message = file_save_draft_area_files($post->itemid, $context->id, 'mod_forum', 'post', $post->id, array('subdirs'=>true), $message); $DB->set_field('forum_posts', 'message', $message, array('id'=>$post->id)); forum_add_attachment($post, $forum, $cm, $mform, $message); @@ -4020,7 +4015,7 @@ function forum_update_post($post, $mform, &$message) { $discussion->timestart = $post->timestart; $discussion->timeend = $post->timeend; } - $post->message = file_save_draft_area_files($post->itemid, $context->id, 'forum_post', $post->id, array('subdirs'=>true), $post->message); + $post->message = file_save_draft_area_files($post->itemid, $context->id, 'mod_forum', 'post', $post->id, array('subdirs'=>true), $post->message); $DB->set_field('forum_posts', 'message', $post->message, array('id'=>$post->id)); $DB->update_record('forum_discussions', $discussion); @@ -4083,7 +4078,7 @@ function forum_add_discussion($discussion, $mform=null, &$message=null, $userid= // TODO: Fix the calling code so that there always is a $cm when this function is called if (!empty($cm->id) && !empty($discussion->itemid)) { // In "single simple discussions" this may not exist yet $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $text = file_save_draft_area_files($discussion->itemid, $context->id, 'forum_post', $post->id, array('subdirs'=>true), $post->message); + $text = file_save_draft_area_files($discussion->itemid, $context->id, 'mod_forum', 'post', $post->id, array('subdirs'=>true), $post->message); $DB->set_field('forum_posts', 'message', $text, array('id'=>$post->id)); } @@ -4198,7 +4193,7 @@ function forum_delete_post($post, $children, $course, $cm, $forum, $skipcompleti //delete attachments $fs = get_file_storage(); - $fs->delete_area_files($context->id, 'forum_attachment', $post->id); + $fs->delete_area_files($context->id, 'mod_forum', 'attachment', $post->id); if ($DB->delete_records("forum_posts", array("id" => $post->id))) { @@ -6959,7 +6954,7 @@ function forum_reset_userdata($data) { continue; } $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $fs->delete_area_files($context->id, 'forum_attachment'); + $fs->delete_area_files($context->id, 'mod_forum', 'attachment'); //remove ratings $ratingdeloptions->contextid = $context->id; diff --git a/mod/forum/locallib.php b/mod/forum/locallib.php index 6e81d05fde4bb..ba07ed8589e51 100644 --- a/mod/forum/locallib.php +++ b/mod/forum/locallib.php @@ -97,8 +97,8 @@ public function load_data() { if ($this->attachment) { $this->set_file_and_format_data($this->attachment); } else { - $attach = $fs->get_area_files($this->modcontext->id, 'forum_attachment', $this->post->id, 'timemodified', false); - $embed = $fs->get_area_files($this->modcontext->id, 'forum_post', $this->post->id, 'timemodified', false); + $attach = $fs->get_area_files($this->modcontext->id, 'mod_forum', 'attachment', $this->post->id, 'timemodified', false); + $embed = $fs->get_area_files($this->modcontext->id, 'mod_forum', 'post', $this->post->id, 'timemodified', false); $files = array_merge($attach, $embed); $this->set_file_and_format_data($files); } @@ -112,8 +112,8 @@ public function load_data() { $this->posts = forum_get_all_discussion_posts($this->discussion->id, 'p.created ASC'); $this->multifiles = array(); foreach ($this->posts as $post) { - $attach = $fs->get_area_files($this->modcontext->id, 'forum_attachment', $post->id, 'timemodified', false); - $embed = $fs->get_area_files($this->modcontext->id, 'forum_post', $post->id, 'timemodified', false); + $attach = $fs->get_area_files($this->modcontext->id, 'mod_forum', 'attachment', $post->id, 'timemodified', false); + $embed = $fs->get_area_files($this->modcontext->id, 'mod_forum', 'post', $post->id, 'timemodified', false); $files = array_merge($attach, $embed); if ($files) { $this->keyedfiles[$post->id] = $files; @@ -304,7 +304,7 @@ private function prepare_post($post, $fileoutputextras=null) { $options->para = true; $format = $this->get('exporter')->get('format'); $formattedtext = format_text($post->message, $post->messageformat, $options, $this->get('course')->id); - $formattedtext = portfolio_rewrite_pluginfile_urls($formattedtext, $this->modcontext->id, 'forum_post', $post->id, $format); + $formattedtext = portfolio_rewrite_pluginfile_urls($formattedtext, $this->modcontext->id, 'mod_forum', 'post', $post->id, $format); $output = ''; diff --git a/mod/forum/post.php b/mod/forum/post.php index 8a54fbdd793ed..f258a6243b238 100644 --- a/mod/forum/post.php +++ b/mod/forum/post.php @@ -51,7 +51,7 @@ $sitecontext = get_context_instance(CONTEXT_SYSTEM); if (!isloggedin() or isguestuser()) { - + if (!isloggedin() and !get_referer()) { // No referer+not logged in - probably coming in via email See MDL-9052 require_login(); @@ -270,7 +270,7 @@ $post = trusttext_pre_edit($post, 'message', $modcontext); unset($SESSION->fromdiscussion); - + }else if (!empty($delete)) { // User is deleting a post @@ -297,8 +297,8 @@ || has_capability('mod/forum:deleteanypost', $modcontext)) ) { print_error('cannotdeletepost', 'forum'); } - - + + $replycount = forum_count_replies($post); if (!empty($confirm) && confirm_sesskey()) { // User has confirmed the delete @@ -493,7 +493,7 @@ $mform_post = new mod_forum_post_form('post.php', array('course'=>$course, 'cm'=>$cm, 'coursecontext'=>$coursecontext, 'modcontext'=>$modcontext, 'forum'=>$forum, 'post'=>$post)); $draftitemid = file_get_submitted_draft_itemid('attachments'); -file_prepare_draft_area($draftitemid, $modcontext->id, 'forum_attachment', empty($post->id)?null:$post->id); +file_prepare_draft_area($draftitemid, $modcontext->id, 'mod_forum', 'attachment', empty($post->id)?null:$post->id); //load data into form NOW! @@ -531,7 +531,7 @@ } $draftid_editor = file_get_submitted_draft_itemid('message'); -$currenttext = file_prepare_draft_area($draftid_editor, $modcontext->id, 'forum_post', empty($post->id) ? null : $post->id, array('subdirs'=>true), $post->message); +$currenttext = file_prepare_draft_area($draftid_editor, $modcontext->id, 'mod_forum', 'post', empty($post->id) ? null : $post->id, array('subdirs'=>true), $post->message); $mform_post->set_data(array( 'attachments'=>$draftitemid, 'general'=>$heading, 'subject'=>$post->subject, diff --git a/mod/glossary/backup/moodle2/backup_glossary_stepslib.php b/mod/glossary/backup/moodle2/backup_glossary_stepslib.php index ac9652c305521..585250af5b092 100644 --- a/mod/glossary/backup/moodle2/backup_glossary_stepslib.php +++ b/mod/glossary/backup/moodle2/backup_glossary_stepslib.php @@ -118,9 +118,10 @@ protected function define_structure() { $rating->annotate_ids('user', 'userid'); // Define file annotations - $glossary->annotate_files(array('glossary_intro'), null); // This file area hasn't itemid + $glossary->annotate_files('mod_glossary', 'intro', null); // This file area hasn't itemid - $entry->annotate_files(array('glossary_entry', 'glossary_attachment'), 'id'); + $entry->annotate_files('mod_glossary', 'entry', 'id'); + $entry->annotate_files('mod_glossary', 'attachment', 'id'); // Return the root element (glossary), wrapped into standard activity structure return $this->prepare_activity_structure($glossary); diff --git a/mod/glossary/db/upgrade.php b/mod/glossary/db/upgrade.php index a71a4d7be8f19..d155b5a30ed10 100644 --- a/mod/glossary/db/upgrade.php +++ b/mod/glossary/db/upgrade.php @@ -71,7 +71,7 @@ function xmldb_glossary_upgrade($oldversion) { } $context = get_context_instance(CONTEXT_MODULE, $entry->cmid); - $filearea = 'glossary_attachment'; + $filearea = 'attachment'; $filename = clean_param($entry->attachment, PARAM_FILE); if ($filename === '') { echo $OUTPUT->notification("Unsupported entry filename, skipping: ".$filepath); @@ -79,8 +79,8 @@ function xmldb_glossary_upgrade($oldversion) { $DB->update_record('glossary_entries', $entry); continue; } - if (!$fs->file_exists($context->id, $filearea, $entry->id, '/', $filename)) { - $file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>$entry->id, 'filepath'=>'/', 'filename'=>$filename, 'userid'=>$entry->userid); + if (!$fs->file_exists($context->id, 'mod_glossary', $filearea, $entry->id, '/', $filename)) { + $file_record = array('contextid'=>$context->id, 'component'=>'mod_glossary', 'filearea'=>$filearea, 'itemid'=>$entry->id, 'filepath'=>'/', 'filename'=>$filename, 'userid'=>$entry->userid); if ($fs->create_file_from_pathname($file_record, $filepath)) { $entry->attachment = '1'; if ($DB->update_record('glossary_entries', $entry)) { diff --git a/mod/glossary/deleteentry.php b/mod/glossary/deleteentry.php index e2e471d72a4f5..6ea898062965a 100644 --- a/mod/glossary/deleteentry.php +++ b/mod/glossary/deleteentry.php @@ -76,13 +76,13 @@ // move attachments too $fs = get_file_storage(); - if ($oldfiles = $fs->get_area_files($context->id, 'glossary_attachment', $entry->id)) { + if ($oldfiles = $fs->get_area_files($context->id, 'mod_glossary', 'attachment', $entry->id)) { foreach ($oldfiles as $oldfile) { $file_record = new object(); $file_record->contextid = $newcontext->id; $fs->create_file_from_storedfile($file_record, $oldfile); } - $fs->delete_area_files($context->id, 'glossary_attachment', $entry->id); + $fs->delete_area_files($context->id, 'mod_glossary', 'attachment', $entry->id); $entry->attachment = '1'; } else { $entry->attachment = '0'; @@ -91,7 +91,7 @@ } else { $fs = get_file_storage(); - $fs->delete_area_files($context->id, 'glossary_attachment', $entry->id); + $fs->delete_area_files($context->id, 'mod_glossary', 'attachment', $entry->id); $DB->delete_records("comments", array('itemid'=>$entry->id, 'commentarea'=>'glossary_entry', 'contextid'=>$context->id)); $DB->delete_records("glossary_alias", array("entryid"=>$entry->id)); $DB->delete_records("glossary_entries", array("id"=>$entry->id)); diff --git a/mod/glossary/edit.php b/mod/glossary/edit.php index 09eab850094e9..870ea63c63563 100644 --- a/mod/glossary/edit.php +++ b/mod/glossary/edit.php @@ -69,8 +69,8 @@ $definitionoptions = array('trusttext'=>true, 'subdirs'=>false, 'maxfiles'=>$maxfiles, 'maxbytes'=>$maxbytes, 'context'=>$context); $attachmentoptions = array('subdirs'=>false, 'maxfiles'=>$maxfiles, 'maxbytes'=>$maxbytes); -$entry = file_prepare_standard_editor($entry, 'definition', $definitionoptions, $context, 'glossary_entry', $entry->id); -$entry = file_prepare_standard_filemanager($entry, 'attachment', $attachmentoptions, $context, 'glossary_attachment', $entry->id); +$entry = file_prepare_standard_editor($entry, 'definition', $definitionoptions, $context, 'mod_glossary', 'entry', $entry->id); +$entry = file_prepare_standard_filemanager($entry, 'attachment', $attachmentoptions, $context, 'mod_glossary', 'attachment', $entry->id); $entry->cmid = $cm->id; @@ -131,8 +131,8 @@ } // save and relink embedded images and save attachments - $entry = file_postupdate_standard_editor($entry, 'definition', $definitionoptions, $context, 'glossary_entry', $entry->id); - $entry = file_postupdate_standard_filemanager($entry, 'attachment', $attachmentoptions, $context, 'glossary_attachment', $entry->id); + $entry = file_postupdate_standard_editor($entry, 'definition', $definitionoptions, $context, 'mod_glossary', 'entry', $entry->id); + $entry = file_postupdate_standard_filemanager($entry, 'attachment', $attachmentoptions, $context, 'mod_glossary', 'attachment', $entry->id); // store the updated value values $DB->update_record('glossary_entries', $entry); diff --git a/mod/glossary/exportentry.php b/mod/glossary/exportentry.php index 72fcc900e6ed8..49f6e6ae97eaa 100644 --- a/mod/glossary/exportentry.php +++ b/mod/glossary/exportentry.php @@ -106,13 +106,13 @@ // move attachments too $fs = get_file_storage(); - if ($oldfiles = $fs->get_area_files($context->id, 'glossary_attachment', $entry->id)) { + if ($oldfiles = $fs->get_area_files($context->id, 'mod_glossary', 'attachment', $entry->id)) { foreach ($oldfiles as $oldfile) { $file_record = new object(); $file_record->contextid = $maincontext->id; $fs->create_file_from_storedfile($file_record, $oldfile); } - $fs->delete_area_files($context->id, 'glossary_attachment', $entry->id); + $fs->delete_area_files($context->id, 'mod_glossary', 'attachment', $entry->id); $entry->attachment = '1'; } else { $entry->attachment = '0'; diff --git a/mod/glossary/lib.php b/mod/glossary/lib.php index a6ff4204b0082..002d81031b0d4 100644 --- a/mod/glossary/lib.php +++ b/mod/glossary/lib.php @@ -172,13 +172,13 @@ function glossary_delete_instance($id) { $entry->glossaryid = $entry->sourceglossaryid; $entry->sourceglossaryid = 0; $newcontext = get_context_instance(CONTEXT_MODULE, $entry->sourcecmid); - if ($oldfiles = $fs->get_area_files($context->id, 'glossary_attachment', $entry->id)) { + if ($oldfiles = $fs->get_area_files($context->id, 'mod_glossary', 'attachment', $entry->id)) { foreach ($oldfiles as $oldfile) { $file_record = new object(); $file_record->contextid = $newcontext->id; $fs->create_file_from_storedfile($file_record, $oldfile); } - $fs->delete_area_files($context->id, 'glossary_attachment', $entry->id); + $fs->delete_area_files($context->id, 'mod_glossary', 'attachment', $entry->id); $entry->attachment = '1'; } else { $entry->attachment = '0'; @@ -854,7 +854,7 @@ function glossary_print_entry_default ($entry, $glossary, $cm) { $definition = '' . strip_tags($definition) . ''; $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $definition = file_rewrite_pluginfile_urls($definition, 'pluginfile.php', $context->id, 'glossary_entry', $entry->id); + $definition = file_rewrite_pluginfile_urls($definition, 'pluginfile.php', $context->id, 'mod_glossary', 'entry', $entry->id); $options = new object(); $options->para = false; @@ -914,7 +914,7 @@ function glossary_print_entry_definition($entry, $glossary, $cm) { $options->trusted = $entry->definitiontrust; $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $definition = file_rewrite_pluginfile_urls($definition, 'pluginfile.php', $context->id, 'glossary_entry', $entry->id); + $definition = file_rewrite_pluginfile_urls($definition, 'pluginfile.php', $context->id, 'mod_glossary', 'entry', $entry->id); $text = format_text($definition, $entry->definitionformat, $options); @@ -1044,7 +1044,7 @@ function glossary_print_entry_icons($course, $cm, $glossary, $entry, $mode='',$h } } $fs = get_file_storage(); - if ($files = $fs->get_area_files($filecontext->id, 'glossary_attachment', $entry->id, "timemodified", false)) { + if ($files = $fs->get_area_files($filecontext->id, 'mod_glossary', 'attachment', $entry->id, "timemodified", false)) { $button->set_formats(PORTFOLIO_FORMAT_RICHHTML); } else { $button->set_formats(PORTFOLIO_FORMAT_PLAINHTML); @@ -1312,17 +1312,16 @@ function glossary_print_attachments($entry, $cm, $type=NULL, $align="left") { $strattachment = get_string('attachment', 'glossary'); $fs = get_file_storage(); - $browser = get_file_browser(); $imagereturn = ''; $output = ''; - if ($files = $fs->get_area_files($filecontext->id, 'glossary_attachment', $entry->id, "timemodified", false)) { + if ($files = $fs->get_area_files($filecontext->id, 'mod_glossary', 'attachment', $entry->id, "timemodified", false)) { foreach ($files as $file) { $filename = $file->get_filename(); $mimetype = $file->get_mimetype(); $iconimage = ''.$mimetype.''; - $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$context->id.'/glossary_attachment/'.$entry->id.'/'.$filename); + $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$context->id.'/mod_glossary/attachment/'.$entry->id.'/'.$filename); if ($type == 'html') { $output .= "$iconimage "; @@ -1370,26 +1369,24 @@ function glossary_get_file_areas($course, $cm, $context) { * Serves the glossary attachments. Implements needed access control ;-) * * @param object $course - * @param object $cminfo + * @param object $cm * @param object $context * @param string $filearea * @param array $args * @param bool $forcedownload * @return bool false if file not found, does not return if found - justsend the file */ -function glossary_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) { +function glossary_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG, $DB; - if (!$cminfo->uservisible) { + if ($context->contextlevel != CONTEXT_MODULE) { return false; } - if ($filearea === 'glossary_attachment' or $filearea === 'glossary_entry') { - $entryid = (int)array_shift($args); + require_course_login($course, true, $cm); - if (!$cm = get_coursemodule_from_instance('glossary', $cminfo->instance, $course->id)) { - return false; - } + if ($filearea === 'attachment' or $filearea === 'entry') { + $entryid = (int)array_shift($args); require_course_login($course, true, $cm); @@ -1397,7 +1394,7 @@ function glossary_pluginfile($course, $cminfo, $context, $filearea, $args, $forc return false; } - if (!$glossary = $DB->get_record('glossary', array('id'=>$cminfo->instance))) { + if (!$glossary = $DB->get_record('glossary', array('id'=>$cm->instance))) { return false; } @@ -1405,12 +1402,14 @@ function glossary_pluginfile($course, $cminfo, $context, $filearea, $args, $forc return false; } - if ($entry->glossaryid == $cminfo->instance) { + // this trickery here is because we need to support source glossary access + + if ($entry->glossaryid == $cm->instance) { $filecontext = $context; - } else if ($entry->sourceglossaryid == $cminfo->instance) { + } else if ($entry->sourceglossaryid == $cm->instance) { if (!$maincm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) { - print_error('invalidcoursemodule'); + return false; } $filecontext = get_context_instance(CONTEXT_MODULE, $maincm->id); @@ -1418,8 +1417,8 @@ function glossary_pluginfile($course, $cminfo, $context, $filearea, $args, $forc return false; } - $relativepath = '/'.implode('/', $args); - $fullpath = $filecontext->id.$filearea.$entryid.$relativepath; + $relativepath = implode('/', $args); + $fullpath = "/$filecontext->id/mod_glossary/$filearea/$entryid/$relativepath"; $fs = get_file_storage(); if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { @@ -2385,7 +2384,7 @@ function glossary_reset_userdata($data) { continue; } $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $fs->delete_area_files($context->id, 'glossary_attachment'); + $fs->delete_area_files($context->id, 'mod_glossary', 'attachment'); //delete ratings $ratingdeloptions->contextid = $context->id; @@ -2418,7 +2417,7 @@ function glossary_reset_userdata($data) { continue; } $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $fs->delete_area_files($context->id, 'glossary_attachment'); + $fs->delete_area_files($context->id, 'mod_glossary', 'attachment'); //delete ratings $ratingdeloptions->contextid = $context->id; @@ -2448,7 +2447,7 @@ function glossary_reset_userdata($data) { continue; } $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $fs->delete_area_files($context->id, 'glossary_attachment'); + $fs->delete_area_files($context->id, 'mod_glossary', 'attachment'); //delete ratings $ratingdeloptions->contextid = $context->id; @@ -2484,7 +2483,7 @@ function glossary_reset_userdata($data) { if ($cm = get_coursemodule_from_instance('glossary', $entry->glossaryid)) { $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $fs->delete_area_files($context->id, 'glossary_attachment', $entry->id); + $fs->delete_area_files($context->id, 'mod_glossary', 'attachment', $entry->id); //delete ratings $ratingdeloptions->contextid = $context->id; diff --git a/mod/glossary/locallib.php b/mod/glossary/locallib.php index 03b925c1782a6..e8a662dee5159 100644 --- a/mod/glossary/locallib.php +++ b/mod/glossary/locallib.php @@ -75,8 +75,8 @@ public function load_data() { $this->multifiles = array(); foreach (array_keys($entries) as $entry) { $this->keyedfiles[$entry] = array_merge( - $fs->get_area_files($context->id, 'glossary_attachment', $entry, "timemodified", false), - $fs->get_area_files($context->id, 'glossary_entry', $entry, "timemodified", false) + $fs->get_area_files($context->id, 'mod_glossary', 'attachment', $entry, "timemodified", false), + $fs->get_area_files($context->id, 'mod_glossary', 'entry', $entry, "timemodified", false) ); $this->multifiles = array_merge($this->multifiles, $this->keyedfiles[$entry]); } @@ -262,8 +262,8 @@ public function load_data() { $this->aliases = $DB->get_records('glossary_alias', array('entryid'=>$this->entryid)); $fs = get_file_storage(); $this->multifiles = array_merge( - $fs->get_area_files($context->id, 'glossary_attachment', $this->entry->id, "timemodified", false), - $fs->get_area_files($context->id, 'glossary_entry', $this->entry->id, "timemodified", false) + $fs->get_area_files($context->id, 'mod_glossary', 'attachment', $this->entry->id, "timemodified", false), + $fs->get_area_files($context->id, 'mod_glossary', 'entry', $this->entry->id, "timemodified", false) ); } @@ -388,7 +388,7 @@ public static function entry_content($course, $cm, $glossary, $entry, $aliases, $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $entry->definition = portfolio_rewrite_pluginfile_urls($entry->definition, $context->id, 'glossary_entry', $entry->id, $format); + $entry->definition = portfolio_rewrite_pluginfile_urls($entry->definition, $context->id, 'mod_glossary', 'entry', $entry->id, $format); $output .= format_text($entry->definition, $entry->definitionformat, $options); if (isset($entry->footer)) { @@ -418,7 +418,7 @@ public static function entry_content($course, $cm, $glossary, $entry, $aliases, $filecontext = $context; } $fs = get_file_storage(); - if ($files = $fs->get_area_files($filecontext->id, 'glossary_attachment', $entry->id, "timemodified", false)) { + if ($files = $fs->get_area_files($filecontext->id, 'mod_glossary', 'attachment', $entry->id, "timemodified", false)) { $output .= '
' . "\n"; foreach ($files as $file) { diff --git a/mod/imscp/backup/moodle2/backup_imscp_stepslib.php b/mod/imscp/backup/moodle2/backup_imscp_stepslib.php index b9b4dff7b1b91..ff753200ffbfe 100644 --- a/mod/imscp/backup/moodle2/backup_imscp_stepslib.php +++ b/mod/imscp/backup/moodle2/backup_imscp_stepslib.php @@ -51,7 +51,7 @@ protected function define_structure() { // (none) // Define file annotations - $imscp->annotate_files(array('imscp_intro'), null); // This file area hasn't itemid + $imscp->annotate_files('mod_imscp', 'intro', null); // This file area hasn't itemid /** * Don't annotate contents for now. It breaks backup as far as it's using itemid for storing * revisions. Each element only can have one files anotation and itemid must be null or id for all them @@ -62,7 +62,7 @@ protected function define_structure() { * * TODO: To decide MDL-22315 comments about this. */ - // $imscp->annotate_files(array('imscp_content'), 'revision'); // This file area uses 'revision' as itemid + $imscp->annotate_files('mod_imscp', 'content', null); // TODO: backup everything as is for now, the revision would be the same after restore // Return the root element (imscp), wrapped into standard activity structure return $this->prepare_activity_structure($imscp); diff --git a/mod/imscp/db/upgradelib.php b/mod/imscp/db/upgradelib.php index d842c4e0f3f69..332dec3a0c53f 100644 --- a/mod/imscp/db/upgradelib.php +++ b/mod/imscp/db/upgradelib.php @@ -77,7 +77,8 @@ function imscp_20_migrate() { $fullpath = $root.'/'.$package; if (file_exists($fullpath)) { $file_record = array('contextid' => $context->id, - 'filearea' => 'imscp_backup', + 'component' => 'mod_imscp', + 'filearea' => 'backup', 'itemid' => 1, 'filepath' => '/', 'filename' => $package); @@ -93,7 +94,7 @@ function imscp_20_migrate() { continue; } - $file_record = array('contextid'=>$context->id, 'filearea'=>'imscp_content', 'itemid'=>1); + $file_record = array('contextid'=>$context->id, 'component'=>'mod_imscp', 'filearea'=>'content', 'itemid'=>1); $error = false; foreach ($files as $relname=>$fullpath) { $parts = explode('/', $relname); diff --git a/mod/imscp/lib.php b/mod/imscp/lib.php index b6f53c9bc835c..085cdaa2e8b28 100644 --- a/mod/imscp/lib.php +++ b/mod/imscp/lib.php @@ -101,10 +101,10 @@ function imscp_add_instance($data, $mform) { $imscp = $DB->get_record('imscp', array('id'=>$data->id), '*', MUST_EXIST); if ($filename = $mform->get_new_filename('package')) { - if ($package = $mform->save_stored_file('package', $context->id, 'imscp_backup', 1, '/', $filename)) { + if ($package = $mform->save_stored_file('package', $context->id, 'mod_imscp', 'backup', 1, '/', $filename)) { // extract package content $packer = get_file_packer('application/zip'); - $package->extract_to_storage($packer, $context->id, 'imscp_content', 1, '/'); + $package->extract_to_storage($packer, $context->id, 'mod_imscp', 'content', 1, '/'); $structure = imscp_parse_structure($imscp, $context); $imscp->structure = is_array($structure) ? serialize($structure) : null; $DB->update_record('imscp', $imscp); @@ -143,26 +143,26 @@ function imscp_update_instance($data, $mform) { // get a list of existing packages before adding new package if ($imscp->keepold > -1) { - $packages = $fs->get_area_files($context->id, 'imscp_backup', false, "itemid ASC", false); + $packages = $fs->get_area_files($context->id, 'mod_imscp', 'backup', false, "itemid ASC", false); } else { $packages = array(); } - $package = $mform->save_stored_file('package', $context->id, 'imscp_backup', $imscp->revision, '/', $filename); + $package = $mform->save_stored_file('package', $context->id, 'mod_imscp', 'backup', $imscp->revision, '/', $filename); // purge all extracted content - $fs->delete_area_files($context->id, 'imscp_content'); + $fs->delete_area_files($context->id, 'mod_imscp', 'content'); // extract package content if ($package) { $packer = get_file_packer('application/zip'); - $package->extract_to_storage($packer, $context->id, 'imscp_content', $imscp->revision, '/'); + $package->extract_to_storage($packer, $context->id, 'mod_imscp', 'content', $imscp->revision, '/'); } // cleanup old package files, keep current + keepold while ($packages and (count($packages) > $imscp->keepold)) { $package = array_shift($packages); - $fs->delete_area_files($context->id, 'imscp_backup', $package->get_itemid()); + $fs->delete_area_files($context->id, 'mod_imscp', 'backup', $package->get_itemid()); } } @@ -262,10 +262,10 @@ function imscp_get_participants($imscpid) { */ function imscp_get_file_areas($course, $cm, $context) { $areas = array(); - if (has_capability('moodle/course:managefiles', $context)) { - $areas['imscp_content'] = get_string('areacontent', 'imscp'); - $areas['imscp_backup'] = get_string('areabackup', 'imscp'); - } + + $areas['content'] = get_string('areacontent', 'imscp'); + $areas['backup'] = get_string('areabackup', 'imscp'); + return $areas; } @@ -284,18 +284,20 @@ function imscp_get_file_areas($course, $cm, $context) { */ function imscp_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) { global $CFG, $DB; - require_once("$CFG->dirroot/mod/imscp/locallib.php"); // note: imscp_intro handled in file_browser automatically if (!has_capability('moodle/course:managefiles', $context)) { - // no peaking here, sorry + // no peaking here for students!! return null; } - if ($filearea !== 'imscp_content' and $filearea !== 'imscp_backup') { + if ($filearea !== 'content' and $filearea !== 'backup') { return null; } + + require_once("$CFG->dirroot/mod/imscp/locallib.php"); + if (is_null($itemid)) { return new imscp_file_info($browser, $course, $cm, $context, $areas, $filearea, $itemid); } @@ -303,49 +305,46 @@ function imscp_get_file_info($browser, $areas, $course, $cm, $context, $filearea $fs = get_file_storage(); $filepath = is_null($filepath) ? '/' : $filepath; $filename = is_null($filename) ? '.' : $filename; - if (!$storedfile = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) { + if (!$storedfile = $fs->get_file($context->id, 'mod_imscp', $filearea, $itemid, $filepath, $filename)) { return null; } // do not allow manual modification of any files! $urlbase = $CFG->wwwroot.'/pluginfile.php'; - return new file_info_stored($browser, $context, $storedfile, $urlbase, $itemid, true, true, false, false); + return new file_info_stored($browser, $context, $storedfile, $urlbase, $itemid, true, true, false, false); //no writing here! } /** * Serves the imscp files. * * @param object $course - * @param object $cminfo + * @param object $cm * @param object $context * @param string $filearea * @param array $args * @param bool $forcedownload * @return bool false if file not found, does not return if found - justsend the file */ -function imscp_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) { +function imscp_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG, $DB; - if (!$cminfo->uservisible) { + if ($context->contextlevel != CONTEXT_MODULE) { return false; } - if (!$cm = get_coursemodule_from_instance('imscp', $cminfo->instance, $course->id)) { - return false; - } + require_login($course, true, $cm); - if ($filearea === 'imscp_content') { - require_course_login($course, true, $cm); + if ($filearea === 'content') { $revision = array_shift($args); $fs = get_file_storage(); - $relativepath = '/'.implode('/', $args); - if ($relativepath === '/imsmanifest.xml') { + $relativepath = implode('/', $args); + if ($relativepath === 'imsmanifest.xml') { if (!has_capability('moodle/course:managefiles', $context)) { // no stealing of detailed package info ;-) return false; } } - $fullpath = $context->id.$filearea.$revision.$relativepath; + $fullpath = "/$context->id/mod_imscp/$filearea/$revision/$relativepath"; if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { return false; } @@ -353,16 +352,15 @@ function imscp_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedo // finally send the file send_stored_file($file, 86400, 0, $forcedownload); - } else if ($filearea === 'imscp_backup') { - require_login($course, false, $cm); + } else if ($filearea === 'backup') { if (!has_capability('moodle/course:managefiles', $context)) { // no stealing of package backups return false; } $revision = array_shift($args); $fs = get_file_storage(); - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.$filearea.$revision.$relativepath; + $relativepath = implode('/', $args); + $fullpath = "/$context->id/mod_imscp/$filearea/$revision/$relativepath"; if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { return false; } diff --git a/mod/imscp/locallib.php b/mod/imscp/locallib.php index 286837649f87f..75a2a099d4b87 100644 --- a/mod/imscp/locallib.php +++ b/mod/imscp/locallib.php @@ -24,7 +24,6 @@ */ require_once("$CFG->dirroot/mod/imscp/lib.php"); -require_once("$CFG->libdir/file/file_browser.php"); require_once("$CFG->libdir/filelib.php"); require_once("$CFG->libdir/resourcelib.php"); @@ -35,7 +34,7 @@ function imscp_print_content($imscp, $cm, $course) { $first = reset($items); $context = get_context_instance(CONTEXT_MODULE, $cm->id); $urlbase = "$CFG->wwwroot/pluginfile.php"; - $path = '/'.$context->id.'/imscp_content/'.$imscp->revision.'/'.$first['href']; + $path = '/'.$context->id.'/mod_imscp/content/'.$imscp->revision.'/'.$first['href']; $firsturl = file_encode_url($urlbase, $path, false); echo '
'; @@ -60,7 +59,7 @@ function imscp_htmllize_item($item, $imscp, $cm) { $context = get_context_instance(CONTEXT_MODULE, $cm->id); $urlbase = "$CFG->wwwroot/pluginfile.php"; - $path = '/'.$context->id.'/imscp_content/'.$imscp->revision.'/'.$item['href']; + $path = '/'.$context->id.'/mod_imscp/content/'.$imscp->revision.'/'.$item['href']; $url = file_encode_url($urlbase, $path, false); $result = "
  • ".$item['title'].''; if ($item['subitems']) { @@ -78,7 +77,7 @@ function imscp_htmllize_item($item, $imscp, $cm) { function imscp_parse_structure($imscp, $context) { $fs = get_file_storage(); - if (!$manifestfile = $fs->get_file($context->id, 'imscp_content', $imscp->revision, '/', 'imsmanifest.xml')) { + if (!$manifestfile = $fs->get_file($context->id, 'mod_imscp', 'content', $imscp->revision, '/', 'imsmanifest.xml')) { return null; } @@ -212,6 +211,7 @@ public function __construct($browser, $course, $cm, $context, $areas, $filearea) */ public function get_params() { return array('contextid'=>$this->context->id, + 'component'=>'mod_imscp', 'filearea' =>$this->filearea, 'itemid' =>null, 'filepath' =>null, @@ -250,9 +250,9 @@ public function get_children() { global $DB; $children = array(); - $itemids = $DB->get_records('files', array('contextid'=>$this->context->id, 'filearea'=>$this->filearea), 'itemid', "DISTINCT itemid"); + $itemids = $DB->get_records('files', array('contextid'=>$this->context->id, 'component'=>'mod_imscp', 'filearea'=>$this->filearea), 'itemid', "DISTINCT itemid"); foreach ($itemids as $itemid=>$unused) { - if ($child = $this->browser->get_file_info($this->context, $this->filearea, $itemid)) { + if ($child = $this->browser->get_file_info($this->context, 'mod_imscp', $this->filearea, $itemid)) { $children[] = $child; } } diff --git a/mod/imscp/mod_form.php b/mod/imscp/mod_form.php index 0ed638687d5ee..3a0f6f68acd97 100644 --- a/mod/imscp/mod_form.php +++ b/mod/imscp/mod_form.php @@ -74,7 +74,7 @@ function validation($data, $files) { $usercontext = get_context_instance(CONTEXT_USER, $USER->id); $fs = get_file_storage(); - if (!$files = $fs->get_area_files($usercontext->id, 'user_draft', $data['package'], 'id', false)) { + if (!$files = $fs->get_area_files($usercontext->id, 'user', 'draft', $data['package'], 'id', false)) { if (!$this->current->instance) { $errors['package'] = get_string('required'); return $errors; @@ -86,7 +86,7 @@ function validation($data, $files) { if ($file->get_mimetype() != 'application/zip') { $errors['package'] = get_string('invalidfiletype', 'error', '', $file); // better delete current file, it is not usable anyway - $fs->delete_area_files($usercontext->id, 'user_draft', $data['package']); + $fs->delete_area_files($usercontext->id, 'user', 'draft', $data['package']); } return $errors; diff --git a/mod/label/backup/moodle2/backup_label_stepslib.php b/mod/label/backup/moodle2/backup_label_stepslib.php index 127b956de7410..c6428dbae753b 100644 --- a/mod/label/backup/moodle2/backup_label_stepslib.php +++ b/mod/label/backup/moodle2/backup_label_stepslib.php @@ -50,7 +50,7 @@ protected function define_structure() { // (none) // Define file annotations - $label->annotate_files(array('label_intro'), null); // This file area hasn't itemid + $label->annotate_files('mod_label', 'intro', null); // This file area hasn't itemid // Return the root element (label), wrapped into standard activity structure return $this->prepare_activity_structure($label); diff --git a/mod/lesson/backup/moodle2/backup_lesson_stepslib.php b/mod/lesson/backup/moodle2/backup_lesson_stepslib.php index 3dd86a1360be0..c1e4a3d919ba4 100644 --- a/mod/lesson/backup/moodle2/backup_lesson_stepslib.php +++ b/mod/lesson/backup/moodle2/backup_lesson_stepslib.php @@ -181,8 +181,8 @@ protected function define_structure() { $timer->annotate_ids('user', 'userid'); // Annotate the file areas in user by the lesson module. - $lesson->annotate_files(array('lesson_media_file'), 'id'); - $page->annotate_files(array('lesson_page_contents'), 'id'); + $lesson->annotate_files('mod_lesson', 'media_file', 'id'); + $page->annotate_files('mod_lesson', 'page_contents', 'id'); // Prepare and return the structure we have just created for the lesson module. return $this->prepare_activity_structure($lesson); diff --git a/mod/lesson/db/upgrade.php b/mod/lesson/db/upgrade.php index 3c98111bf6e31..63a0235c11a79 100644 --- a/mod/lesson/db/upgrade.php +++ b/mod/lesson/db/upgrade.php @@ -121,7 +121,7 @@ function xmldb_lesson_upgrade($oldversion) { continue; } - $filearea = 'lesson_media_file'; + $filearea = 'media_file'; $filename = clean_param($lesson->mediafile, PARAM_FILE); if ($filename === '') { echo $OUTPUT->notification("Unsupported lesson filename, skipping: ".$filepath); @@ -130,8 +130,8 @@ function xmldb_lesson_upgrade($oldversion) { } $context = get_context_instance(CONTEXT_MODULE, $lesson->cmid); - if (!$fs->file_exists($context->id, $filearea, $lesson->id, '/', $filename)) { - $file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>$lesson->id, 'filepath'=>'/', 'filename'=>$filename); + if (!$fs->file_exists($context->id, 'mod_lesson', $filearea, $lesson->id, '/', $filename)) { + $file_record = array('contextid'=>$context->id, 'component'=>'mod_lesson', 'filearea'=>$filearea, 'itemid'=>$lesson->id, 'filepath'=>'/', 'filename'=>$filename); if ($fs->create_file_from_pathname($file_record, $filepath)) { if ($DB->set_field('lesson', 'mediafile', $filename, array('id'=>$lesson->id))) { unlink($filepath); diff --git a/mod/lesson/importppt.php b/mod/lesson/importppt.php index 8f1664c002447..9917dce4fea89 100644 --- a/mod/lesson/importppt.php +++ b/mod/lesson/importppt.php @@ -72,15 +72,15 @@ if (!$filename = $mform->get_new_filename('pptzip')) { print_error('invalidfile', 'lesson'); } - if (!$package = $mform->save_stored_file('pptzip', $context->id, 'lesson_ppt_imports', $lesson->id, '/', $filename, true)) { + if (!$package = $mform->save_stored_file('pptzip', $context->id, 'mod_lesson', 'ppt_imports', $lesson->id, '/', $filename, true)) { print_error('unabletosavefile', 'lesson'); } // extract package content $packer = get_file_packer('application/zip'); - $package->extract_to_storage($packer, $context->id, 'lesson_imported_files', $lesson->id, '/'); + $package->extract_to_storage($packer, $context->id, 'mod_lesson', 'imported_files', $lesson->id, '/'); $fs = get_file_storage(); - if ($files = $fs->get_area_files($context->id, 'lesson_imported_files', $lesson->id)) { + if ($files = $fs->get_area_files($context->id, 'mod_lesson', 'imported_files', $lesson->id)) { $pages = array(); foreach ($files as $key=>$file) { @@ -167,7 +167,7 @@ $id = $DB->insert_record('lesson_pages', $branchtable->page); if (!empty($branchtable->page->images)) { - $changes = array('contextid'=>$context->id, 'filearea'=>'lesson_page_contents', 'itemid'=>$id, 'timemodified'=>time()); + $changes = array('contextid'=>$context->id, 'component'=>'mod_lesson', 'filearea'=>'page_contents', 'itemid'=>$id, 'timemodified'=>time()); foreach ($branchtable->page->images as $image) { $fs->create_file_from_storedfile($changes, $image); } @@ -194,7 +194,7 @@ } // Remove all unzipped files! - $fs->delete_area_files($context->id, 'lesson_imported_files', $lesson->id); + $fs->delete_area_files($context->id, 'mod_lesson', 'imported_files', $lesson->id); redirect("$CFG->wwwroot/mod/$modname/view.php?id=$cm->id", get_string('pptsuccessfullimport', 'lesson'), 5); } diff --git a/mod/lesson/lib.php b/mod/lesson/lib.php index b38a222800861..f2e1bea40174b 100644 --- a/mod/lesson/lib.php +++ b/mod/lesson/lib.php @@ -59,7 +59,7 @@ function lesson_add_instance($data, $mform) { $lesson = $DB->get_record('lesson', array('id'=>$lessonid), '*', MUST_EXIST); if ($filename = $mform->get_new_filename('mediafile')) { - if ($file = $mform->save_stored_file('mediafile', $context->id, 'lesson_media_file', $lesson->id, '/', $filename)) { + if ($file = $mform->save_stored_file('mediafile', $context->id, 'mod_lesson', 'media_file', $lesson->id, '/', $filename)) { $DB->set_field('lesson', 'mediafile', $file->get_filename(), array('id'=>$lesson->id)); } } @@ -95,7 +95,7 @@ function lesson_update_instance($data, $mform) { $context = get_context_instance(CONTEXT_MODULE, $cmid); if ($filename = $mform->get_new_filename('mediafile')) { - if ($file = $mform->save_stored_file('mediafile', $context->id, 'lesson_media_file', $data->id, '/', $filename, true)) { + if ($file = $mform->save_stored_file('mediafile', $context->id, 'mod_lesson', 'media_file', $data->id, '/', $filename, true)) { $DB->set_field('lesson', 'mediafile', $file->get_filename(), array('id'=>$data->id)); } } @@ -878,17 +878,17 @@ function lesson_get_import_export_formats($type) { * Serves the lesson attachments. Implements needed access control ;-) * * @param object $course - * @param object $cminfo + * @param object $cm * @param object $context * @param string $filearea * @param array $args * @param bool $forcedownload * @return bool false if file not found, does not return if found - justsend the file */ -function lesson_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) { +function lesson_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG, $DB; - if (!$cminfo->uservisible) { + if ($context->contextlevel != CONTEXT_MODULE) { return false; } @@ -897,25 +897,22 @@ function lesson_pluginfile($course, $cminfo, $context, $filearea, $args, $forced return false; } - if (!$cm = get_coursemodule_from_instance('lesson', $cminfo->instance, $course->id)) { - return false; - } - - if (!$lesson = $DB->get_record('lesson', array('id'=>$cminfo->instance))) { + if (!$lesson = $DB->get_record('lesson', array('id'=>$cm->instance))) { return false; } require_course_login($course, true, $cm); - if ($filearea === 'lesson_page_content') { + if ($filearea === 'page_contents') { $pageid = (int)array_shift($args); if (!$page = $DB->get_record('lesson_pages', array('id'=>$pageid))) { return false; } - $fullpath = $context->id.$filearea.$pageid.'/'.implode('/', $args); - $forcedownload = true; + $fullpath = "/$context->id/mod_lesson/$filearea/$pageid/".implode('/', $args); + $forcedownload = true; //TODO: this is strange (skodak) } else { - $fullpath = $context->id.$filearea.implode('/', $args); + + $fullpath = "/$context->id/mod_lesson/$filearea/".implode('/', $args); } $fs = get_file_storage(); @@ -932,7 +929,9 @@ function lesson_pluginfile($course, $cminfo, $context, $filearea, $args, $forced * @return array */ function lesson_get_file_areas() { - return array('lesson_page_contents'=>'lesson_page_contents', 'lesson_media_file'=>'lesson_media_file'); + $areas = array(); + $areas['page_contents'] = 'page_contents'; //TODO: localize!!!! + $areas['media_files'] = 'media_files'; //TODO: localize!!!! } /** @@ -952,11 +951,16 @@ function lesson_get_file_areas() { */ function lesson_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) { global $CFG; + if (has_capability('moodle/course:managefiles', $context)) { + // no peaking here for students!! + return null; + } + $fs = get_file_storage(); $filepath = is_null($filepath) ? '/' : $filepath; $filename = is_null($filename) ? '.' : $filename; $urlbase = $CFG->wwwroot.'/pluginfile.php'; - if (!$storedfile = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) { + if (!$storedfile = $fs->get_file($context->id, 'mod_lesson', $filearea, $itemid, $filepath, $filename)) { return null; } return new file_info_stored($browser, $context, $storedfile, $urlbase, $filearea, $itemid, true, true, false); @@ -1887,7 +1891,7 @@ final public static function create($properties, lesson $lesson, $context, $maxb $editor = new stdClass; $editor->id = $newpage->id; $editor->contents_editor = $properties->contents_editor; - $editor = file_postupdate_standard_editor($editor, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$maxbytes), $context, 'lesson_page_contents', $editor->id); + $editor = file_postupdate_standard_editor($editor, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$maxbytes), $context, 'mod_lesson', 'page_contents', $editor->id); $DB->update_record("lesson_pages", $editor); if ($newpage->prevpageid > 0) { @@ -2235,7 +2239,7 @@ public function callback_on_view($canmanage) { * @return bool */ public function update($properties, $context = null, $maxbytes = null) { - global $DB, $PAGE; + global $DB; $answers = $this->get_answers(); $properties->id = $this->properties->id; $properties->lessonid = $this->lesson->id; @@ -2248,7 +2252,7 @@ public function update($properties, $context = null, $maxbytes = null) { if ($maxbytes === null) { $maxbytes =get_max_upload_file_size(); } - $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$maxbytes), $context, 'lesson_page_contents', $properties->id); + $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$maxbytes), $context, 'mod_lesson', 'page_contents', $properties->id); $DB->update_record("lesson_pages", $properties); for ($i = 0; $i < $this->lesson->maxanswers; $i++) { @@ -2492,7 +2496,7 @@ public function get_contents() { $this->properties->contentsformat = FORMAT_HTML; } $context = get_context_instance(CONTEXT_MODULE, $PAGE->cm->id); - return file_rewrite_pluginfile_urls($this->properties->contents, 'pluginfile.php', $context->id, 'lesson_page_contents', $this->properties->id); + return file_rewrite_pluginfile_urls($this->properties->contents, 'pluginfile.php', $context->id, 'mod_lesson', 'page_contents', $this->properties->id); } else { return ''; } @@ -2916,7 +2920,7 @@ public function custom_definition() {} * @param int $pageid */ public final function set_data($data, $context=null, $pageid=null) { - $data = file_prepare_standard_editor($data, 'contents', $this->editoroptions, $context, 'lesson_page_contents', $pageid); + $data = file_prepare_standard_editor($data, 'contents', $this->editoroptions, $context, 'mod_lesson', 'page_contents', $pageid); parent::set_data($data); } diff --git a/mod/lesson/locallib.php b/mod/lesson/locallib.php index 09b78bc79ba02..1529d1267d9bf 100644 --- a/mod/lesson/locallib.php +++ b/mod/lesson/locallib.php @@ -583,10 +583,9 @@ function lesson_get_media_html($lesson, $context) { global $CFG, $PAGE, $OUTPUT; require_once("$CFG->libdir/resourcelib.php"); - // get the media file from file pool - $browser = get_file_browser(); - $file_info = $browser->get_file_info($context, 'lesson_media_file', $lesson->id, '/', $lesson->mediafile); - $url = $file_info->get_url(); + // get the media file link + $path = '/'.$context->id.'/media_file/'.$lesson->id->revision.'/'.$lesson->mediafile; + $url = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, false); $title = $lesson->mediafile; $clicktoopen = html_writer::link(new moodle_url($url), get_string('download')); diff --git a/mod/lesson/mod_form.php b/mod/lesson/mod_form.php index 6ee478727dd8a..4a1fc60bd88d4 100644 --- a/mod/lesson/mod_form.php +++ b/mod/lesson/mod_form.php @@ -330,7 +330,7 @@ function data_preprocessing(&$default_values) { if (!empty($this->_cm) && !empty($default_values['mediafile'])) { $context = get_context_instance(CONTEXT_MODULE, $this->_cm->id); $draftitemid = file_get_submitted_draft_itemid('mediafile'); - file_prepare_draft_area($draftitemid, $context->id, 'lesson_media_file', $this->_cm->instance, array('subdirs' => 0, 'maxbytes' => $this->course->maxbytes, 'maxfiles' => 1)); + file_prepare_draft_area($draftitemid, $context->id, 'mod_lesson', 'media_file', $this->_cm->instance, array('subdirs' => 0, 'maxbytes' => $this->course->maxbytes, 'maxfiles' => 1)); $default_values['mediafile'] = $draftitemid; } } diff --git a/mod/lesson/pagetypes/endofbranch.php b/mod/lesson/pagetypes/endofbranch.php index 5d97c2ce9a898..50828154d7cd4 100644 --- a/mod/lesson/pagetypes/endofbranch.php +++ b/mod/lesson/pagetypes/endofbranch.php @@ -104,7 +104,7 @@ public function update($properties) { if (empty($properties->qoption)) { $properties->qoption = '0'; } - $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), get_context_instance(CONTEXT_MODULE, $PAGE->cm->id), 'lesson_page_contents', $properties->id); + $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), get_context_instance(CONTEXT_MODULE, $PAGE->cm->id), 'mod_lesson', 'page_contents', $properties->id); $DB->update_record("lesson_pages", $properties); $answers = $this->get_answers(); diff --git a/mod/lesson/pagetypes/endofcluster.php b/mod/lesson/pagetypes/endofcluster.php index f7b7dc4211859..d502629534be0 100644 --- a/mod/lesson/pagetypes/endofcluster.php +++ b/mod/lesson/pagetypes/endofcluster.php @@ -73,7 +73,7 @@ public function update($properties) { if (empty($properties->qoption)) { $properties->qoption = '0'; } - $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), get_context_instance(CONTEXT_MODULE, $PAGE->cm->id), 'lesson_page_contents', $properties->id); + $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), get_context_instance(CONTEXT_MODULE, $PAGE->cm->id), 'mod_lesson', 'page_contents', $properties->id); $DB->update_record("lesson_pages", $properties); $answers = $this->get_answers(); diff --git a/mod/lesson/pagetypes/essay.php b/mod/lesson/pagetypes/essay.php index 51303d5d98881..4471fe49a70bb 100644 --- a/mod/lesson/pagetypes/essay.php +++ b/mod/lesson/pagetypes/essay.php @@ -120,7 +120,7 @@ public function update($properties) { $answers = $this->get_answers(); $properties->id = $this->properties->id; $properties->lessonid = $this->lesson->id; - $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), get_context_instance(CONTEXT_MODULE, $PAGE->cm->id), 'lesson_page_contents', $properties->id); + $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), get_context_instance(CONTEXT_MODULE, $PAGE->cm->id), 'mod_lesson', 'page_contents', $properties->id); $DB->update_record("lesson_pages", $properties); if (!array_key_exists(0, $this->answers)) { diff --git a/mod/lesson/pagetypes/matching.php b/mod/lesson/pagetypes/matching.php index c0e2a0291447a..ea3e5fb59930a 100644 --- a/mod/lesson/pagetypes/matching.php +++ b/mod/lesson/pagetypes/matching.php @@ -299,7 +299,7 @@ public function update($properties) { $answers = $this->get_answers(); $properties->id = $this->properties->id; $properties->lessonid = $this->lesson->id; - $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), get_context_instance(CONTEXT_MODULE, $PAGE->cm->id), 'lesson_page_contents', $properties->id); + $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), get_context_instance(CONTEXT_MODULE, $PAGE->cm->id), 'mod_lesson', 'page_contents', $properties->id); $DB->update_record("lesson_pages", $properties); // need to add two to offset correct response and wrong response diff --git a/mod/page/backup/moodle2/backup_page_stepslib.php b/mod/page/backup/moodle2/backup_page_stepslib.php index fa17c958d914c..f6d01314fafaf 100644 --- a/mod/page/backup/moodle2/backup_page_stepslib.php +++ b/mod/page/backup/moodle2/backup_page_stepslib.php @@ -52,7 +52,8 @@ protected function define_structure() { // (none) // Define file annotations - $page->annotate_files(array('page_intro', 'page_content'), null); // This file areas haven't itemid + $page->annotate_files('mod_page', 'intro', null); // This file areas haven't itemid + $page->annotate_files('mod_page', 'content', null); // This file areas haven't itemid // Return the root element (page), wrapped into standard activity structure return $this->prepare_activity_structure($page); diff --git a/mod/page/db/upgradelib.php b/mod/page/db/upgradelib.php index 8ad91a9f64e3d..8a8dbcadf5e8a 100644 --- a/mod/page/db/upgradelib.php +++ b/mod/page/db/upgradelib.php @@ -111,15 +111,15 @@ function page_20_migrate_candidate($candidate, $fs, $format) { $page = resource_migrate_to_module('page', $candidate, $page); // now try to migrate files from site files - // noite: this can not work for html pages or files with other relatively linked files :-( + // note: this can not work for html pages or files with other relatively linked files :-( $siteid = get_site()->id; if (preg_match_all("|$CFG->wwwroot/file.php(\?file=)?/$siteid(/[^\s'\"&\?#]+)|", $page->content, $matches)) { $context = get_context_instance(CONTEXT_MODULE, $candidate->cmid); $sitecontext = get_context_instance(CONTEXT_COURSE, $siteid); - $file_record = array('contextid'=>$context->id, 'filearea'=>'page_content', 'itemid'=>0); + $file_record = array('contextid'=>$context->id, 'component'=>'mod_page', 'filearea'=>'content', 'itemid'=>0); $fs = get_file_storage(); foreach ($matches[2] as $i=>$sitefile) { - if (!$file = $fs->get_file_by_hash(sha1($sitecontext->id.'course_content0'.$sitefile))) { + if (!$file = $fs->get_file_by_hash(sha1("/$sitecontext->id/course/legacy/0".$sitefile))) { continue; } try { diff --git a/mod/page/lib.php b/mod/page/lib.php index 35be5e2e0327b..06ba3311c5587 100644 --- a/mod/page/lib.php +++ b/mod/page/lib.php @@ -108,7 +108,7 @@ function page_add_instance($data, $mform) { $context = get_context_instance(CONTEXT_MODULE, $cmid); if ($draftitemid) { - $data->content = file_save_draft_area_files($draftitemid, $context->id, 'page_content', 0, page_get_editor_options($context), $data->content); + $data->content = file_save_draft_area_files($draftitemid, $context->id, 'mod_page', 'content', 0, page_get_editor_options($context), $data->content); $DB->update_record('page', $data); } @@ -148,7 +148,7 @@ function page_update_instance($data, $mform) { $context = get_context_instance(CONTEXT_MODULE, $cmid); if ($draftitemid) { - $data->content = file_save_draft_area_files($draftitemid, $context->id, 'page_content', 0, page_get_editor_options($context), $data->content); + $data->content = file_save_draft_area_files($draftitemid, $context->id, 'mod_page', 'content', 0, page_get_editor_options($context), $data->content); $DB->update_record('page', $data); } @@ -280,9 +280,7 @@ function page_get_coursemodule_info($coursemodule) { */ function page_get_file_areas($course, $cm, $context) { $areas = array(); - if (has_capability('moodle/course:managefiles', $context)) { - $areas['page_content'] = get_string('pagecontent', 'page'); - } + $areas['content'] = get_string('pagecontent', 'page'); return $areas; } @@ -302,25 +300,28 @@ function page_get_file_areas($course, $cm, $context) { function page_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) { global $CFG; - $canwrite = has_capability('moodle/course:managefiles', $context); + if (!has_capability('moodle/course:managefiles', $context)) { + // students can not peak here! + return null; + } $fs = get_file_storage(); - if ($filearea === 'page_content') { + if ($filearea === 'content') { $filepath = is_null($filepath) ? '/' : $filepath; $filename = is_null($filename) ? '.' : $filename; $urlbase = $CFG->wwwroot.'/pluginfile.php'; - if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) { + if (!$storedfile = $fs->get_file($context->id, 'mod_page', 'content', 0, $filepath, $filename)) { if ($filepath === '/' and $filename === '.') { - $storedfile = new virtual_root_file($context->id, $filearea, 0); + $storedfile = new virtual_root_file($context->id, 'mod_page', 'content', 0); } else { // not found return null; } } require_once("$CFG->dirroot/mod/page/locallib.php"); - return new page_content_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, $canwrite, false); + return new page_content_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, true, false); } // note: page_intro handled in file_browser automatically @@ -331,43 +332,39 @@ function page_get_file_info($browser, $areas, $course, $cm, $context, $filearea, /** * Serves the page files. * @param object $course - * @param object $cminfo + * @param object $cm * @param object $context * @param string $filearea * @param array $args * @param bool $forcedownload * @return bool false if file not found, does not return if found - justsend the file */ -function page_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) { +function page_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG, $DB; require_once("$CFG->libdir/resourcelib.php"); - if (!$cminfo->uservisible) { + if ($context->contextlevel != CONTEXT_MODULE) { return false; } - if ($filearea !== 'page_content') { - // intro is handled automatically in pluginfile.php - return false; - } + require_course_login($course, true, $cm); - if (!$cm = get_coursemodule_from_instance('page', $cminfo->instance, $course->id)) { + if ($filearea !== 'content') { + // intro is handled automatically in pluginfile.php return false; } - require_course_login($course, true, $cm); - array_shift($args); // ignore revision - designed to prevent caching problems only $fs = get_file_storage(); - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.$filearea.'0'.$relativepath; + $relativepath = implode('/', $args); + $fullpath = "/$context->id/mod_page/$filearea/0/$relativepath"; if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { $page = $DB->get_record('page', array('id'=>$cminfo->instance), 'id, legacyfiles', MUST_EXIST); if ($page->legacyfiles != RESOURCELIB_LEGACYFILES_ACTIVE) { return false; } - if (!$file = resourcelib_try_file_migration($relativepath, $cminfo->id, $cminfo->course, 'page_content', 0)) { + if (!$file = resourcelib_try_file_migration('/'.$relativepath, $cminfo->id, $cminfo->course, 'mod_page', 'content', 0)) { return false; } //file migrate - update flag diff --git a/mod/page/mod_form.php b/mod/page/mod_form.php index df355fd943532..9adef17bbb32c 100644 --- a/mod/page/mod_form.php +++ b/mod/page/mod_form.php @@ -122,7 +122,7 @@ function data_preprocessing(&$default_values) { if ($this->current->instance) { $draftitemid = file_get_submitted_draft_itemid('page'); $default_values['page']['format'] = $default_values['contentformat']; - $default_values['page']['text'] = file_prepare_draft_area($draftitemid, $this->context->id, 'page_content', 0, page_get_editor_options($this->context), $default_values['content']); + $default_values['page']['text'] = file_prepare_draft_area($draftitemid, $this->context->id, 'mod_page', 'content', 0, page_get_editor_options($this->context), $default_values['content']); $default_values['page']['itemid'] = $draftitemid; } if (!empty($default_values['displayoptions'])) { diff --git a/mod/page/view.php b/mod/page/view.php index 2a73c28ea162b..0e6df797c0fa7 100644 --- a/mod/page/view.php +++ b/mod/page/view.php @@ -90,7 +90,7 @@ } } -$content = file_rewrite_pluginfile_urls($page->content, 'pluginfile.php', $context->id, 'page_content', $page->revision); +$content = file_rewrite_pluginfile_urls($page->content, 'pluginfile.php', $context->id, 'mod_page', 'content', $page->revision); $formatoptions = (object)array('noclean'=>true); $content = format_text($content, $page->contentformat, $formatoptions, $course->id); echo $OUTPUT->box($content, "generalbox center clearfix"); diff --git a/mod/resource/backup/moodle2/backup_resource_stepslib.php b/mod/resource/backup/moodle2/backup_resource_stepslib.php index 06e022bd668cc..67b1fbc68bdd3 100644 --- a/mod/resource/backup/moodle2/backup_resource_stepslib.php +++ b/mod/resource/backup/moodle2/backup_resource_stepslib.php @@ -52,7 +52,8 @@ protected function define_structure() { // (none) // Define file annotations - $resource->annotate_files(array('resource_intro', 'resource_content'), null); // This file areas haven't itemid + $resource->annotate_files('mod_resource', 'intro', null); // This file areas haven't itemid + $resource->annotate_files('mod_resource', 'content', null); // This file areas haven't itemid // Return the root element (resource), wrapped into standard activity structure return $this->prepare_activity_structure($resource); diff --git a/mod/resource/db/upgrade.php b/mod/resource/db/upgrade.php index 6ec89db79a1e1..fde3388c5ced9 100644 --- a/mod/resource/db/upgrade.php +++ b/mod/resource/db/upgrade.php @@ -224,11 +224,12 @@ function xmldb_resource_upgrade($oldversion) { if ($instances = $DB->get_recordset_sql($sql)) { foreach ($instances as $instance) { $context = get_context_instance(CONTEXT_MODULE, $instance->cmid); - $filearea = 'resource_content'; + $component = 'mod_resource'; + $filearea = 'content'; $itemid = 0; $filepath = file_correct_filepath(dirname($instance->mainfile)); $filename = basename($instance->mainfile); - file_set_sortorder($context->id, $filearea, $itemid, $filepath, $filename, 1); + file_set_sortorder($context->id, $component, $filearea, $itemid, $filepath, $filename, 1); } } diff --git a/mod/resource/db/upgradelib.php b/mod/resource/db/upgradelib.php index 266b0d73191a0..3442462e9f5a8 100644 --- a/mod/resource/db/upgradelib.php +++ b/mod/resource/db/upgradelib.php @@ -67,8 +67,8 @@ function resource_20_migrate() { $context = get_context_instance(CONTEXT_MODULE, $candidate->cmid); $sitecontext = get_context_instance(CONTEXT_COURSE, $siteid); - $file_record = array('contextid'=>$context->id, 'filearea'=>'resource_content', 'itemid'=>0); - if ($file = $fs->get_file_by_hash(sha1($sitecontext->id.'course_content0'.$path))) { + $file_record = array('contextid'=>$context->id, 'component'=>'mod_resourse', 'filearea'=>'content', 'itemid'=>0); + if ($file = $fs->get_file_by_hash(sha1("/$sitecontext->id/course/legacy/content/0".$path))) { try { $fs->create_file_from_storedfile($file_record, $file); } catch (Exception $x) { @@ -93,7 +93,7 @@ function resource_20_migrate() { } // try migration of main file - ignore if does not exist - if ($file = resourcelib_try_file_migration($resource->mainfile, $candidate->cmid, $candidate->course, 'resource_content', 0)) { + if ($file = resourcelib_try_file_migration($resource->mainfile, $candidate->cmid, $candidate->course, 'mod_resource', 'content', 0)) { $resource->mainfile = $file->get_filepath().$file->get_filename(); } @@ -127,7 +127,7 @@ function resource_20_migrate() { } // try migration of main file - ignore if does not exist - if ($file = resourcelib_try_file_migration($resource->mainfile, $candidate->cmid, $candidate->course, 'resource_content', 0)) { + if ($file = resourcelib_try_file_migration($resource->mainfile, $candidate->cmid, $candidate->course, 'mod_resource', 'content', 0)) { $resource->mainfile = $file->get_filepath().$file->get_filename(); } } diff --git a/mod/resource/lib.php b/mod/resource/lib.php index ddbec431b051a..14fae27f46596 100644 --- a/mod/resource/lib.php +++ b/mod/resource/lib.php @@ -242,7 +242,7 @@ function resource_get_coursemodule_info($coursemodule) { return $info; } $fs = get_file_storage(); - $files = $fs->get_area_files($context->id, 'resource_content', 0, 'sortorder'); + $files = $fs->get_area_files($context->id, 'mod_resource', 'content', 0, 'sortorder'); if (count($files) >= 1) { $mainfile = array_pop($files); $info->icon = str_replace(array('.gif', '.png'), '', file_extension_icon($mainfile->get_filename())); @@ -272,7 +272,7 @@ function resource_get_coursemodule_info($coursemodule) { return NULL; } // do not open any window because it would be left there after download - $path = '/'.$context->id.'/resource_content/'.$resource->revision.$mainfile->get_filepath().$mainfile->get_filename(); + $path = '/'.$context->id.'/mod_resource/content/'.$resource->revision.$mainfile->get_filepath().$mainfile->get_filename(); $fullurl = addslashes_js(file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, true)); // When completion information is enabled for download files, make @@ -302,9 +302,7 @@ function resource_get_coursemodule_info($coursemodule) { */ function resource_get_file_areas($course, $cm, $context) { $areas = array(); - if (has_capability('moodle/course:managefiles', $context)) { - $areas['resource_content'] = get_string('resourcecontent', 'resource'); - } + $areas['content'] = get_string('resourcecontent', 'resource'); return $areas; } @@ -324,25 +322,28 @@ function resource_get_file_areas($course, $cm, $context) { function resource_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) { global $CFG; - $canwrite = has_capability('moodle/course:managefiles', $context); + if (!has_capability('moodle/course:managefiles', $context)) { + // students can not peak here! + return null; + } $fs = get_file_storage(); - if ($filearea === 'resource_content') { + if ($filearea === 'content') { $filepath = is_null($filepath) ? '/' : $filepath; $filename = is_null($filename) ? '.' : $filename; $urlbase = $CFG->wwwroot.'/pluginfile.php'; - if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) { + if (!$storedfile = $fs->get_file($context->id, 'mod_resource', 'content', 0, $filepath, $filename)) { if ($filepath === '/' and $filename === '.') { - $storedfile = new virtual_root_file($context->id, $filearea, 0); + $storedfile = new virtual_root_file($context->id, 'mod_resource', 'content', 0); } else { // not found return null; } } require_once("$CFG->dirroot/mod/resource/locallib.php"); - return new resource_content_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, $canwrite, false); + return new resource_content_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, true, false); } // note: resource_intro handled in file_browser automatically @@ -353,43 +354,39 @@ function resource_get_file_info($browser, $areas, $course, $cm, $context, $filea /** * Serves the resource files. * @param object $course - * @param object $cminfo + * @param object $cm * @param object $context * @param string $filearea * @param array $args * @param bool $forcedownload * @return bool false if file not found, does not return if found - justsend the file */ -function resource_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) { +function resource_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG, $DB; require_once("$CFG->libdir/resourcelib.php"); - if (!$cminfo->uservisible) { + if ($context->contextlevel != CONTEXT_MODULE) { return false; } - if ($filearea !== 'resource_content') { - // intro is handled automatically in pluginfile.php - return false; - } + require_course_login($course, true, $cm); - if (!$cm = get_coursemodule_from_instance('resource', $cminfo->instance, $course->id)) { + if ($filearea !== 'content') { + // intro is handled automatically in pluginfile.php return false; } - require_course_login($course, true, $cm); - array_shift($args); // ignore revision - designed to prevent caching problems only $fs = get_file_storage(); - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.$filearea.'0'.$relativepath; + $relativepath = implode('/', $args); + $fullpath = "/$context->id/mod_resource/$filearea/0/$relativepath"; if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { $resource = $DB->get_record('resource', array('id'=>$cminfo->instance), 'id, legacyfiles', MUST_EXIST); if ($resource->legacyfiles != RESOURCELIB_LEGACYFILES_ACTIVE) { return false; } - if (!$file = resourcelib_try_file_migration($relativepath, $cminfo->id, $cminfo->course, 'resource_content', 0)) { + if (!$file = resourcelib_try_file_migration('/'.$relativepath, $cm->id, $cm->course, 'mod_resource', 'content', 0)) { return false; } // file migrate - update flag @@ -400,7 +397,7 @@ function resource_pluginfile($course, $cminfo, $context, $filearea, $args, $forc // should we apply filters? $mimetype = $file->get_mimetype(); if ($mimetype = 'text/html' or $mimetype = 'text/plain') { - $filter = $DB->get_field('resource', 'filterfiles', array('id'=>$cminfo->instance)); + $filter = $DB->get_field('resource', 'filterfiles', array('id'=>$cm->instance)); } else { $filter = 0; } diff --git a/mod/resource/locallib.php b/mod/resource/locallib.php index 86cdb026a0f1c..b2d4fb9c25c97 100644 --- a/mod/resource/locallib.php +++ b/mod/resource/locallib.php @@ -64,7 +64,7 @@ function resource_display_embed($resource, $cm, $course, $file) { $clicktoopen = resource_get_clicktoopen($file, $resource->revision); $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $path = '/'.$context->id.'/resource_content/'.$resource->revision.$file->get_filepath().$file->get_filename(); + $path = '/'.$context->id.'/mod_resource/content/'.$resource->revision.$file->get_filepath().$file->get_filename(); $fullurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, false); $mimetype = $file->get_mimetype(); @@ -145,7 +145,7 @@ function resource_display_frame($resource, $cm, $course, $file) { } else { $config = get_config('resource'); $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $path = '/'.$context->id.'/resource_content/'.$resource->revision.$file->get_filepath().$file->get_filename(); + $path = '/'.$context->id.'/mod_resource/content/'.$resource->revision.$file->get_filepath().$file->get_filename(); $fileurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, false); $navurl = "$CFG->wwwroot/mod/resource/view.php?id=$cm->id&frameset=top"; $title = strip_tags(format_string($course->shortname.': '.$resource->name)); @@ -180,7 +180,7 @@ function resource_get_clicktoopen($file, $revision, $extra='') { global $CFG; $filename = $file->get_filename(); - $path = '/'.$file->get_contextid().'/resource_content/'.$revision.$file->get_filepath().$file->get_filename(); + $path = '/'.$file->get_contextid().'/mod_resource/content/'.$revision.$file->get_filepath().$file->get_filename(); $fullurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, false); $string = get_string('clicktoopen2', 'resource', "$filename"); @@ -195,7 +195,7 @@ function resource_get_clicktodownload($file, $revision) { global $CFG; $filename = $file->get_filename(); - $path = '/'.$file->get_contextid().'/resource_content/'.$revision.$file->get_filepath().$file->get_filename(); + $path = '/'.$file->get_contextid().'/mod_resource/content/'.$revision.$file->get_filepath().$file->get_filename(); $fullurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, true); $string = get_string('clicktodownload', 'resource', "$filename"); @@ -222,7 +222,7 @@ function resource_print_workaround($resource, $cm, $course, $file) { echo '
    '; switch (resource_get_final_display_type($resource)) { case RESOURCELIB_DISPLAY_POPUP: - $path = '/'.$file->get_contextid().'/resource_content/'.$resource->revision.$file->get_filepath().$file->get_filename(); + $path = '/'.$file->get_contextid().'/mod_resource/content/'.$resource->revision.$file->get_filepath().$file->get_filename(); $fullurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, false); $options = empty($resource->displayoptions) ? array() : unserialize($resource->displayoptions); $width = empty($options['popupwidth']) ? 620 : $options['popupwidth']; @@ -408,12 +408,12 @@ function resource_set_mainfile($data) { $context = get_context_instance(CONTEXT_MODULE, $cmid); if ($draftitemid) { - file_save_draft_area_files($draftitemid, $context->id, 'resource_content', 0, array('subdirs'=>true)); + file_save_draft_area_files($draftitemid, $context->id, 'mod_resource', 'content', 0, array('subdirs'=>true)); } - $files = $fs->get_area_files($context->id, 'resource_content', 0, 'sortorder', false); + $files = $fs->get_area_files($context->id, 'mod_resource', 'content', 0, 'sortorder', false); if (count($files) == 1) { // only one file attached, set it as main file automatically $file = reset($files); - file_set_sortorder($context->id, 'resource_content', 0, $file->get_filepath(), $file->get_filename(), 1); + file_set_sortorder($context->id, 'mod_resource', 'content', 0, $file->get_filepath(), $file->get_filename(), 1); } } diff --git a/mod/resource/mod_form.php b/mod/resource/mod_form.php index 2f9e60f7b505c..4940be49cc557 100644 --- a/mod/resource/mod_form.php +++ b/mod/resource/mod_form.php @@ -158,7 +158,7 @@ function definition() { function data_preprocessing(&$default_values) { if ($this->current->instance and !$this->current->tobemigrated) { $draftitemid = file_get_submitted_draft_itemid('files'); - file_prepare_draft_area($draftitemid, $this->context->id, 'resource_content', 0, array('subdirs'=>true)); + file_prepare_draft_area($draftitemid, $this->context->id, 'mod_resource', 'content', 0, array('subdirs'=>true)); $default_values['files'] = $draftitemid; } if (!empty($default_values['displayoptions'])) { @@ -194,7 +194,7 @@ function validation($data, $files) { $usercontext = get_context_instance(CONTEXT_USER, $USER->id); $fs = get_file_storage(); - if (!$files = $fs->get_area_files($usercontext->id, 'user_draft', $data['files'], 'sortorder, id', false)) { + if (!$files = $fs->get_area_files($usercontext->id, 'user', 'draft', $data['files'], 'sortorder, id', false)) { $errors['files'] = get_string('required'); return $errors; } @@ -212,7 +212,7 @@ function validation($data, $files) { // set a default main file if (!$mainfile) { $file = reset($files); - file_set_sortorder($file->get_contextid(), $file->get_filearea(), $file->get_itemid(), + file_set_sortorder($file->get_contextid(), $file->get_component(), $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename(), 1); } } diff --git a/mod/resource/view.php b/mod/resource/view.php index dbfca270802a0..ec5686d98f180 100644 --- a/mod/resource/view.php +++ b/mod/resource/view.php @@ -65,7 +65,7 @@ } $fs = get_file_storage(); -$files = $fs->get_area_files($context->id, 'resource_content', 0, 'sortorder'); +$files = $fs->get_area_files($context->id, 'mod_resource', 'content', 0, 'sortorder'); if (count($files) < 1) { resource_print_filenotfound($resource, $cm, $course); die; @@ -76,7 +76,7 @@ if ($redirect) { // coming from course page or url index page // this redirect trick solves caching problems when tracking views ;-) - $path = '/'.$context->id.'/resource_content/'.$resource->revision.$file->get_filepath().$file->get_filename(); + $path = '/'.$context->id.'/mod_resource/content/'.$resource->revision.$file->get_filepath().$file->get_filename(); $fullurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, false); redirect($fullurl); } diff --git a/mod/scorm/backup/moodle2/backup_scorm_stepslib.php b/mod/scorm/backup/moodle2/backup_scorm_stepslib.php index 646fbf8367916..1fcf36ad4eb9b 100644 --- a/mod/scorm/backup/moodle2/backup_scorm_stepslib.php +++ b/mod/scorm/backup/moodle2/backup_scorm_stepslib.php @@ -152,7 +152,8 @@ protected function define_structure() { $scotrack->annotate_ids('user', 'userid'); // Define file annotations - $scorm->annotate_files(array('scorm_intro', 'scorm_content'), null); // This file area hasn't itemid + $scorm->annotate_files('mod_scorm', 'intro', null); // This file area hasn't itemid + $scorm->annotate_files('mod_scorm', 'content', null); // This file area hasn't itemid // Return the root element (scorm), wrapped into standard activity structure return $this->prepare_activity_structure($scorm); diff --git a/mod/scorm/datamodels/aicclib.php b/mod/scorm/datamodels/aicclib.php index 6cabfb7d98136..c8a8ba04aa6f7 100644 --- a/mod/scorm/datamodels/aicclib.php +++ b/mod/scorm/datamodels/aicclib.php @@ -103,7 +103,7 @@ function scorm_parse_aicc($scorm) { $fs = get_file_storage(); - $files = $fs->get_area_files($context->id, 'scorm_content', 0, '', false); + $files = $fs->get_area_files($context->id, 'mod_scorm', 'content', 0, '', false); $version = 'AICC'; diff --git a/mod/scorm/db/install.xml b/mod/scorm/db/install.xml index 6784e033a0543..d255b245da26e 100644 --- a/mod/scorm/db/install.xml +++ b/mod/scorm/db/install.xml @@ -24,7 +24,7 @@ - + diff --git a/mod/scorm/db/upgrade.php b/mod/scorm/db/upgrade.php index 7e6b26bc0be2d..0d6238c1f7452 100644 --- a/mod/scorm/db/upgrade.php +++ b/mod/scorm/db/upgrade.php @@ -120,7 +120,7 @@ function scorm_migrate_content_files($context, $base, $path) { $fullpathname = $base.$path; $fs = get_file_storage(); - $filearea = 'scorm_content'; + $filearea = 'content'; $items = new DirectoryIterator($fullpathname); foreach ($items as $item) { @@ -151,8 +151,8 @@ function scorm_migrate_content_files($context, $base, $path) { unset($item); // release file handle } - 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, 'mod_scorm', $filearea, '0', $filepath, $filename)) { + $file_record = array('contextid'=>$context->id, 'component'=>'mod_scorm', 'filearea'=>$filearea, 'itemid'=>0, 'filepath'=>$filepath, 'filename'=>$filename, 'timecreated'=>$item->getCTime(), 'timemodified'=>$item->getMTime()); unset($item); // release file handle if ($fs->create_file_from_pathname($file_record, $oldpathname)) { @@ -197,10 +197,10 @@ function scorm_migrate_content_files($context, $base, $path) { // first copy local packages if found - do not delete in case they are shared ;-) if ($scorm->scormtype === 'local' and preg_match('/.*(\.zip|\.pif)$/i', $scorm->reference)) { - $packagefile = '/'.clean_param($scorm->reference, PARAM_PATH); - $pathnamehash = sha1($coursecontext->id.'course_content0'.$packagefile); + $packagefile = clean_param($scorm->reference, PARAM_PATH); + $pathnamehash = sha1("/$coursecontext->id/course/legacy/0/$packagefile"); if ($file = $fs->get_file_by_hash($pathnamehash)) { - $file_record = array('scontextid'=>$context->id, 'filearea'=>'scorm_pacakge', + $file_record = array('scontextid'=>$context->id, 'component'=>'mod_scorm', 'filearea'=>'package', 'itemid'=>0, 'filepath'=>'/'); try { $fs->create_file_from_storedfile($file_record, $file); diff --git a/mod/scorm/lib.php b/mod/scorm/lib.php index 1b6b3cccf48de..34ebde37da931 100755 --- a/mod/scorm/lib.php +++ b/mod/scorm/lib.php @@ -88,8 +88,8 @@ function scorm_add_instance($scorm, $mform=null) { $filename = $mform->get_new_filename('packagefile'); if ($filename !== false) { $fs = get_file_storage(); - $fs->delete_area_files($context->id, 'scorm_package'); - $mform->save_stored_file('packagefile', $context->id, 'scorm_package', 0, '/', $filename); + $fs->delete_area_files($context->id, 'mod_scorm', 'package'); + $mform->save_stored_file('packagefile', $context->id, 'mod_scorm', 'package', 0, '/', $filename); $scorm->reference = $filename; } } @@ -165,8 +165,8 @@ function scorm_update_instance($scorm, $mform=null) { if ($filename !== false) { $scorm->reference = $filename; $fs = get_file_storage(); - $fs->delete_area_files($context->id, 'scorm_package'); - $mform->save_stored_file('packagefile', $context->id, 'scorm_package', 0, '/', $filename); + $fs->delete_area_files($context->id, 'mod_scorm', 'package'); + $mform->save_stored_file('packagefile', $context->id, 'mod_scorm', 'package', 0, '/', $filename); } } @@ -782,10 +782,8 @@ function scorm_get_extra_capabilities() { */ function scorm_get_file_areas($course, $cm, $context) { $areas = array(); - if (has_capability('moodle/course:managefiles', $context)) { - $areas['scorm_content'] = get_string('areacontent', 'scorm'); - $areas['scorm_package'] = get_string('areapackage', 'scorm'); - } + $areas['content'] = get_string('areacontent', 'scorm'); + $areas['package'] = get_string('areapackage', 'scorm'); return $areas; } @@ -814,49 +812,31 @@ function scorm_get_file_info($browser, $areas, $course, $cm, $context, $filearea $fs = get_file_storage(); - if ($filearea === 'scorm_content') { + if ($filearea === 'content') { $filepath = is_null($filepath) ? '/' : $filepath; $filename = is_null($filename) ? '.' : $filename; $urlbase = $CFG->wwwroot.'/pluginfile.php'; - if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) { + if (!$storedfile = $fs->get_file($context->id, 'mod_scorm', 'content', 0, $filepath, $filename)) { if ($filepath === '/' and $filename === '.') { - $storedfile = new virtual_root_file($context->id, $filearea, 0); + $storedfile = new virtual_root_file($context->id, 'mod_scorm', 'content', 0); } else { // not found return null; } } - /** - * @package mod-scorm - * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - class scorm_package_file_info extends file_info_stored { - public function get_parent() { - if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') { - return $this->browser->get_file_info($this->context); - } - return parent::get_parent(); - } - public function get_visible_name() { - if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') { - return $this->topvisiblename; - } - return parent::get_visible_name(); - } - } + require_once("$CFG->dirroot/mod/scorm/locallib.php"); return new scorm_package_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, false, false); - } else if ($filearea === 'scorm_package') { + } else if ($filearea === 'package') { $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 (!$storedfile = $fs->get_file($context->id, 'mod_scorm', 'package', 0, $filepath, $filename)) { if ($filepath === '/' and $filename === '.') { - $storedfile = new virtual_root_file($context->id, $filearea, 0); + $storedfile = new virtual_root_file($context->id, 'mod_scorm', 'package', 0); } else { // not found return null; @@ -874,40 +854,36 @@ public function get_visible_name() { * Serves scorm content, introduction images and packages. Implements needed access control ;-) * * @param object $course - * @param object $cminfo + * @param object $cm * @param object $context * @param string $filearea * @param array $args * @param bool $forcedownload * @return bool false if file not found, does not return if found - just send the file */ -function scorm_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) { +function scorm_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG; - if (!$cminfo->uservisible) { - return false; // probably hidden - } - - $lifetime = isset($CFG->filelifetime) ? $CFG->filelifetime : 86400; - - if (!$cm = get_coursemodule_from_instance('scorm', $cminfo->instance, $course->id)) { + if ($context->contextlevel != CONTEXT_MODULE) { return false; } require_login($course, true, $cm); - if ($filearea === 'scorm_content') { + $lifetime = isset($CFG->filelifetime) ? $CFG->filelifetime : 86400; + + if ($filearea === 'content') { $revision = (int)array_shift($args); // prevents caching problems - ignored here - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.'scorm_content0'.$relativepath; + $relativepath = implode('/', $args); + $fullpath = "$context->id/mod_scorm/content/0/$relativepath"; // TODO: add any other access restrictions here if needed! - } else if ($filearea === 'scorm_package') { + } else if ($filearea === 'package') { if (!has_capability('moodle/course:manageactivities', $context)) { return false; } - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.'scorm_package0'.$relativepath; + $relativepath = implode('/', $args); + $fullpath = "/$context->id/mod_scorm/package/0/$relativepath"; $lifetime = 0; // no caching here } else { @@ -994,7 +970,7 @@ function scorm_write_log($type, $text, $scoid) { * * @param object $type - type of log(aicc,scorm12,scorm13) used as prefix for filename * @param array $htmlarray - * @return mixed + * @return mixed */ function scorm_print_overview($courses, &$htmlarray) { global $USER, $CFG, $DB; diff --git a/mod/scorm/loadSCO.php b/mod/scorm/loadSCO.php index 8188d46c560f4..f0751d7bc40f9 100755 --- a/mod/scorm/loadSCO.php +++ b/mod/scorm/loadSCO.php @@ -122,7 +122,7 @@ //note: do not convert this to use get_file_url()! // SCORM does not work without slasharguments anyway and there might be some extra ?xx=yy params // see MDL-16060 - $result = "$CFG->wwwroot/pluginfile.php/$context->id/scorm_content/$scorm->revision/$launcher"; + $result = "$CFG->wwwroot/pluginfile.php/$context->id/mod_scorm/content/$scorm->revision/$launcher"; } // which API are we looking for diff --git a/mod/scorm/locallib.php b/mod/scorm/locallib.php index 7a4bf7f19932a..685517cbc6e45 100755 --- a/mod/scorm/locallib.php +++ b/mod/scorm/locallib.php @@ -1,6 +1,7 @@ dirroot/mod/scorm/lib.php"); +require_once("$CFG->libdir/filelib.php"); /// Constants and settings for module scorm define('UPDATE_NEVER', '0'); @@ -24,6 +25,26 @@ /// Local Library of functions for module scorm +/** + * @package mod-scorm + * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class scorm_package_file_info extends file_info_stored { + public function get_parent() { + if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') { + return $this->browser->get_file_info($this->context); + } + return parent::get_parent(); + } + public function get_visible_name() { + if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') { + return $this->topvisiblename; + } + return parent::get_visible_name(); + } +} + /** * Returns an array of the popup options for SCORM and each options default value * @@ -149,7 +170,7 @@ function scorm_parse($scorm, $full) { $packagefile = false; if ($scorm->scormtype === SCORM_TYPE_LOCAL) { - if ($packagefile = $fs->get_file($context->id, 'scorm_package', 0, '/', $scorm->reference)) { + if ($packagefile = $fs->get_file($context->id, 'mod_scorm', 'package', 0, '/', $scorm->reference)) { $newhash = $packagefile->get_contenthash(); } else { $newhash = null; @@ -160,8 +181,8 @@ function scorm_parse($scorm, $full) { return; } if ($scorm->reference !== '' and (!$full or $scorm->sha1hash !== sha1($scorm->reference))) { - $fs->delete_area_files($context->id, 'scorm_package'); - $file_record = array('contextid'=>$context->id, 'filearea'=>'scorm_package', 'itemid'=>0, 'filepath'=>'/'); + $fs->delete_area_files($context->id, 'mod_scorm', 'package'); + $file_record = array('contextid'=>$context->id, 'component'=>'mod_scorm', 'filearea'=>'package', 'itemid'=>0, 'filepath'=>'/'); if ($packagefile = $fs->create_file_from_url($file_record, $scorm->reference)) { $newhash = sha1($scorm->reference); } else { @@ -173,7 +194,7 @@ function scorm_parse($scorm, $full) { if ($packagefile) { if (!$full and $packagefile and $scorm->sha1hash === $newhash) { if (strpos($scorm->version, 'SCORM') !== false) { - if ($fs->get_file($context->id, 'scorm_content', 0, '/', 'imsmanifest.xml')) { + if ($fs->get_file($context->id, 'mod_scorm', 'content', 0, '/', 'imsmanifest.xml')) { // no need to update return; } @@ -184,17 +205,17 @@ function scorm_parse($scorm, $full) { } // now extract files - $fs->delete_area_files($context->id, 'scorm_content'); + $fs->delete_area_files($context->id, 'mod_scorm', 'content'); $packer = get_file_packer('application/zip'); - $packagefile->extract_to_storage($packer, $context->id, 'scorm_content', 0, '/'); + $packagefile->extract_to_storage($packer, $context->id, 'mod_scorm', 'content', 0, '/'); } else if (!$full) { return; } - if ($manifest = $fs->get_file($context->id, 'scorm_content', 0, '/', 'imsmanifest.xml')) { + if ($manifest = $fs->get_file($context->id, 'mod_scorm', 'content', 0, '/', 'imsmanifest.xml')) { require_once("$CFG->dirroot/mod/scorm/datamodels/scormlib.php"); // SCORM if (!scorm_parse_scorm($scorm, $manifest)) { @@ -832,7 +853,7 @@ function scorm_simple_play($scorm,$user, $context) { if ($scorm->updatefreq == UPDATE_EVERYTIME) { scorm_parse($scorm, false); } - if (has_capability('mod/scorm:viewreport', $context)) { //if this user can view reports, don't skipview so they can see links to reports. + if (has_capability('mod/scorm:viewreport', $context)) { //if this user can view reports, don't skipview so they can see links to reports. return $result; } @@ -1189,8 +1210,8 @@ function scorm_format_date_time($datetime) { $strdays = get_string('numdays'); $strhours = get_string('numhours'); $strminutes = get_string('numminutes'); - $strseconds = get_string('numseconds'); - + $strseconds = get_string('numseconds'); + if ($datetime[0] == 'P') { // if timestamp starts with 'P' - it's a SCORM 2004 format // this regexp discards empty sections, takes Month/Minute ambiguity into consideration, @@ -1210,7 +1231,7 @@ function scorm_format_date_time($datetime) { //$pattern = '##'; //$replace = ''; } - + $result = preg_replace($pattern, $replace, $datetime); return $result; diff --git a/mod/survey/backup/moodle2/backup_survey_stepslib.php b/mod/survey/backup/moodle2/backup_survey_stepslib.php index de5d3372bb4f8..c8f041011102c 100644 --- a/mod/survey/backup/moodle2/backup_survey_stepslib.php +++ b/mod/survey/backup/moodle2/backup_survey_stepslib.php @@ -71,7 +71,7 @@ protected function define_structure() { $analys->annotate_ids('user', 'userid'); // Define file annotations - $survey->annotate_files(array('survey_intro'), null); // This file area hasn't itemid + $survey->annotate_files('mod_survey', 'intro', null); // This file area hasn't itemid // Return the root element (survey), wrapped into standard activity structure return $this->prepare_activity_structure($survey); diff --git a/mod/url/backup/moodle2/backup_url_stepslib.php b/mod/url/backup/moodle2/backup_url_stepslib.php index 2e1ef32d478f2..ba5f8eb816026 100644 --- a/mod/url/backup/moodle2/backup_url_stepslib.php +++ b/mod/url/backup/moodle2/backup_url_stepslib.php @@ -21,7 +21,7 @@ * @copyright 2010 onwards Andrew Davis * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ - + /** * Define all the backup steps that will be used by the backup_url_activity_task */ @@ -32,7 +32,7 @@ class backup_url_activity_structure_step extends backup_activity_structure_step { protected function define_structure() { - + //the URL module stores no user info // Define each element separated @@ -51,7 +51,7 @@ protected function define_structure() { //module has no id annotations // Define file annotations - $url->annotate_files(array('url_intro'), null); // This file area hasn't itemid + $url->annotate_files('mod_url', 'intro', null); // This file area hasn't itemid // Return the root element (url), wrapped into standard activity structure return $this->prepare_activity_structure($url); diff --git a/mod/url/db/upgradelib.php b/mod/url/db/upgradelib.php index 47629a9987cdd..2a1a0ae4fe953 100644 --- a/mod/url/db/upgradelib.php +++ b/mod/url/db/upgradelib.php @@ -50,7 +50,6 @@ function url_20_migrate() { if (!$candidates = $DB->get_recordset('resource_old', array('type'=>'file', 'migrated'=>0))) { return; } - $fs = get_file_storage(); foreach ($candidates as $candidate) { $path = $candidate->reference; diff --git a/mod/url/locallib.php b/mod/url/locallib.php index 865ad5a51eac2..2a196bdc7e46c 100644 --- a/mod/url/locallib.php +++ b/mod/url/locallib.php @@ -23,7 +23,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -require_once("$CFG->libdir/file/file_browser.php"); require_once("$CFG->libdir/filelib.php"); require_once("$CFG->libdir/resourcelib.php"); require_once("$CFG->dirroot/mod/url/lib.php"); diff --git a/mod/wiki/backup/moodle2/backup_wiki_stepslib.php b/mod/wiki/backup/moodle2/backup_wiki_stepslib.php index 8ab4b632f0388..9180e8d2df7c3 100644 --- a/mod/wiki/backup/moodle2/backup_wiki_stepslib.php +++ b/mod/wiki/backup/moodle2/backup_wiki_stepslib.php @@ -115,7 +115,8 @@ protected function define_structure() { $comment->annotate_ids('user', 'userid'); // Define file annotations - $wiki->annotate_files(array('wiki_intro'), null); // This file area hasn't itemid + $wiki->annotate_files('mod_wiki', 'intro', null); // This file area hasn't itemid + //TODO: where are the attachments? (skodak) // Return the root element (wiki), wrapped into standard activity structure return $this->prepare_activity_structure($wiki); diff --git a/mod/wiki/db/upgrade.php b/mod/wiki/db/upgrade.php index 59fa84cfda645..27697f0f3f769 100644 --- a/mod/wiki/db/upgrade.php +++ b/mod/wiki/db/upgrade.php @@ -257,17 +257,18 @@ function xmldb_wiki_upgrade($oldversion) { if (is_file($thefile) && is_readable($thefile)) { $filerecord = array('contextid' => $context->id, - 'filearea' => 'wiki_attachments', + 'component' => 'mod_wiki', + 'filearea' => 'attachments', 'itemid' => $r->subwiki, 'filepath' => '/', 'filename' => $orgifilename, 'userid' => $r->userid); - if (!$fs->file_exists($context->id, 'wiki_attachments', $r->subwiki, '/', $orgifilename)) { + if (!$fs->file_exists($context->id, 'mod_wiki', 'attachments', $r->subwiki, '/', $orgifilename)) { //echo $OUTPUT->notification('Migrating file '.$orgifilename, 'notifysuccess'); $storedfile = $fs->create_file_from_pathname($filerecord, $thefile); } // we have to create another file here to make sure interlinks work - if (!$fs->file_exists($context->id, 'wiki_attachments', $r->subwiki, '/', $filename)) { + if (!$fs->file_exists($context->id, 'mod_wiki', 'attachment', $r->subwiki, '/', $filename)) { $filerecord['filename'] = $filename; //echo $OUTPUT->notification('Migrating file '.$filename, 'notifysuccess'); $storedfile = $fs->create_file_from_pathname($filerecord, $thefile); diff --git a/mod/wiki/edit_form.php b/mod/wiki/edit_form.php index 807da65c5bf8f..aea49c3c45aab 100644 --- a/mod/wiki/edit_form.php +++ b/mod/wiki/edit_form.php @@ -74,6 +74,7 @@ protected function definition() { $mform->addElement('filemanager', 'attachments', get_string('attachments', 'wiki'), null, page_wiki_edit::$attachmentoptions); $fileinfo = array( 'contextid'=>$contextid, + 'component'=>'mod_wiki', 'filearea'=>$filearea, 'itemid'=>$fileitemid, ); diff --git a/mod/wiki/editors/wikifiletable.php b/mod/wiki/editors/wikifiletable.php index 930ac00f98452..387d29e40ee8d 100644 --- a/mod/wiki/editors/wikifiletable.php +++ b/mod/wiki/editors/wikifiletable.php @@ -83,9 +83,8 @@ function toHtml() { $htmltable->head = array(get_string('deleteupload', 'wiki'), get_string('uploadname', 'wiki'), get_string('uploadactions', 'wiki')); $fs = get_file_storage(); - $browser = get_file_browser(); - $files = $fs->get_area_files($this->_fileinfo['contextid'], $this->_fileinfo['filearea'], $this->_fileinfo['itemid']); + $files = $fs->get_area_files($this->_fileinfo['contextid'], 'mod_wiki', 'attachments', $this->_fileinfo['itemid']); //TODO: verify where this is coming from, all params must be validated (skodak) if (count($files) < 2) { return get_string('noattachments', 'wiki'); @@ -107,7 +106,7 @@ function toHtml() { //actions $icon = mimeinfo_from_type('icon', $file->get_mimetype()); - $file_url = file_encode_url($CFG->wwwroot.'/pluginfile.php', "/{$this->_contextid}/{$this->_filearea}/{$this->_fileareaitemid}/".$file->get_filename()); + $file_url = file_encode_url($CFG->wwwroot.'/pluginfile.php', "/{$this->_contextid}/mod_wiki/attachments/{$this->_fileareaitemid}/".$file->get_filename()); $action_icons = ""; if(!empty($tags['attach'])) { @@ -117,7 +116,7 @@ function toHtml() { $action_icons .= "  printInsertTags($tags['link'], $file_url)." title=\"".get_string('attachmentlink', 'wiki')."\">pix_url('f/web')->out()."\" alt=\"Link\" />"; if ($icon == 'image.gif') { - $action_icons .= "  printInsertTags($tags['image'], $file->get_filename())." title=\"".get_string('attachmentimage', 'wiki')."\">pix_url('f/image')->out()."\" alt=\"Image\" />"; + $action_icons .= "  printInsertTags($tags['image'], $file->get_filename())." title=\"".get_string('attachmentimage', 'wiki')."\">pix_url('f/image')->out()."\" alt=\"Image\" />"; //TODO: localize } $htmltable->data[] = array($checkbox, ''.$file->get_filename().'', $action_icons); diff --git a/mod/wiki/lib.php b/mod/wiki/lib.php index 55990ee3136a0..e35478b045c22 100644 --- a/mod/wiki/lib.php +++ b/mod/wiki/lib.php @@ -381,25 +381,29 @@ function wiki_scale_used_anywhere($scaleid) { * * @author Josep Arus */ -function wiki_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) { +function wiki_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG; + if ($context->contextlevel != CONTEXT_MODULE) { + return false; + } + + require_course_login($course, true, $cm); + require_once($CFG->dirroot . "/mod/wiki/locallib.php"); - if ($filearea == 'wiki_attachments') { + if ($filearea == 'attachments') { $swid = (int) array_shift($args); if (!$subwiki = wiki_get_subwiki($swid)) { return false; } - require_course_login($course->id, true, $cm); - require_capability('mod/wiki:viewpage', $context); - $relativepath = '/' . implode('/', $args); + $relativepath = implode('/', $args); - $fullpath = $context->id . 'wiki_attachments' . $swid . $relativepath; + $fullpath = "/$context->id/mod_wiki/attachments/$swid/$relativepath"; $fs = get_file_storage(); if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { @@ -411,6 +415,7 @@ function wiki_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedow send_stored_file($file, $lifetime, 0); } } + function wiki_search_form($cm, $search='') { global $CFG, $OUTPUT; diff --git a/mod/wiki/locallib.php b/mod/wiki/locallib.php index 688ba0ba72be0..1962dfef967c6 100644 --- a/mod/wiki/locallib.php +++ b/mod/wiki/locallib.php @@ -574,7 +574,7 @@ function wiki_parse_content($markup, $pagecontent, $options = array()) { $cm = get_coursemodule_from_instance("wiki", $subwiki->wikiid); $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $parser_options = array('link_callback' => '/mod/wiki/locallib.php:wiki_parser_link', 'link_callback_args' => array('swid' => $options['swid']), 'table_callback' => '/mod/wiki/locallib.php:wiki_parser_table', 'real_path_callback' => '/mod/wiki/locallib.php:wiki_parser_real_path', 'real_path_callback_args' => array('context' => $context, 'filearea' => 'wiki_attachments', 'pageid' => $options['pageid']), 'pageid' => $options['pageid'], 'pretty_print' => (isset($options['pretty_print']) && $options['pretty_print']), 'printable' => (isset($options['printable']) && $options['printable'])); + $parser_options = array('link_callback' => '/mod/wiki/locallib.php:wiki_parser_link', 'link_callback_args' => array('swid' => $options['swid']), 'table_callback' => '/mod/wiki/locallib.php:wiki_parser_table', 'real_path_callback' => '/mod/wiki/locallib.php:wiki_parser_real_path', 'real_path_callback_args' => array('context' => $context, 'component' => 'mod_wiki', 'filearea' => 'attachments', 'pageid' => $options['pageid']), 'pageid' => $options['pageid'], 'pretty_print' => (isset($options['pretty_print']) && $options['pretty_print']), 'printable' => (isset($options['printable']) && $options['printable'])); return wiki_parser_proxy::parse($pagecontent, $markup, $parser_options); } @@ -1016,7 +1016,7 @@ function wiki_process_attachments($draftitemid, $deleteuploads, $contextid, $fil $usercontext = get_context_instance(CONTEXT_USER, $USER->id); $fs = get_file_storage(); - $oldfiles = $fs->get_area_files($contextid, $filearea, $itemid, 'id'); + $oldfiles = $fs->get_area_files($contextid, 'mod_wiki', 'attachments', $itemid, 'id'); foreach ($oldfiles as $file) { if (in_array($file->get_pathnamehash(), $deleteuploads)) { @@ -1024,14 +1024,14 @@ function wiki_process_attachments($draftitemid, $deleteuploads, $contextid, $fil } } - $draftfiles = $fs->get_area_files($usercontext->id, 'user_draft', $draftitemid, 'id'); - $oldfiles = $fs->get_area_files($contextid, $filearea, $itemid, 'id'); + $draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id'); + $oldfiles = $fs->get_area_files($contextid, 'mod_wiki', 'attachments', $itemid, 'id'); - $file_record = array('contextid' => $contextid, 'filearea' => $filearea, 'itemid' => $itemid); + $file_record = array('contextid' => $contextid, 'component'=>'mod_wiki', 'filearea' => 'attachments', 'itemid' => $itemid); //more or less a merge... $newhashes = array(); foreach ($draftfiles as $file) { - $newhash = sha1($contextid . $filearea . $itemid . $file->get_filepath() . $file->get_filename()); + $newhash = sha1("/$contextid/mod_wiki/attachments/$itemid" . $file->get_filepath() . $file->get_filename()); $newhashes[$newhash] = $file; } @@ -1065,7 +1065,7 @@ function wiki_process_attachments($draftitemid, $deleteuploads, $contextid, $fil } //delete all draft files - $fs->delete_area_files($usercontext->id, 'user_draft', $draftitemid); + $fs->delete_area_files($usercontext->id, 'user', 'draft', $draftitemid); return $errors; } @@ -1215,7 +1215,7 @@ function wiki_print_page_content($page, $context, $subwikiid) { echo $OUTPUT->box($box); } } - $html = file_rewrite_pluginfile_urls($page->cachedcontent, 'pluginfile.php', $context->id, 'wiki_attachments', $subwikiid); + $html = file_rewrite_pluginfile_urls($page->cachedcontent, 'pluginfile.php', $context->id, 'mod_wiki', 'attachments', $subwikiid); echo $OUTPUT->box($html); if (!empty($CFG->usetags)) { @@ -1307,8 +1307,7 @@ function wiki_print_upload_table($context, $filearea, $fileitemid, $deleteupload $htmltable->head = array(get_string('deleteupload', 'wiki'), get_string('uploadname', 'wiki'), get_string('uploadactions', 'wiki')); $fs = get_file_storage(); - $browser = get_file_browser(); - $files = $fs->get_area_files($context->id, $filearea, $fileitemid); + $files = $fs->get_area_files($context->id, 'mod_wiki', $filearea, $fileitemid); //TODO: this is weird (skodak) foreach ($files as $file) { if (!$file->is_directory()) { diff --git a/mod/wiki/pagelib.php b/mod/wiki/pagelib.php index 2043ef42905b7..a582cdca5afd3 100644 --- a/mod/wiki/pagelib.php +++ b/mod/wiki/pagelib.php @@ -530,17 +530,18 @@ protected function print_edit($content = null) { switch ($format) { case 'html': $data->newcontentformat = FORMAT_HTML; - $data = file_prepare_standard_editor($data, 'newcontent', page_wiki_edit::$attachmentoptions, $context, 'wiki_attachments', $this->subwiki->id); + $data = file_prepare_standard_editor($data, 'newcontent', page_wiki_edit::$attachmentoptions, $context, 'mod_wiki', 'attachments', $this->subwiki->id); break; default: //$draftitemid = file_get_submitted_draft_itemid('attachments'); - //file_prepare_draft_area($draftitemid, $context->id, 'wiki_attachments', $this->subwiki->id); + //file_prepare_draft_area($draftitemid, $context->id, 'mod_wiki', 'attachments', $this->subwiki->id); //$data->attachments = $draftitemid; } if ($version->contentformat != 'html') { - $params['contextid'] = $context->id; - $params['filearea'] = 'wiki_attachments'; + $params['contextid'] = $context->id; + $params['component'] = 'mod_wiki'; + $params['filearea'] = 'attachments'; $params['fileitemid'] = $this->subwiki->id; } @@ -575,9 +576,9 @@ protected function process_uploads($context) { global $PAGE, $OUTPUT; if ($this->upload) { - file_save_draft_area_files($this->attachments, $context->id, 'wiki_attachments', $this->subwiki->id); + file_save_draft_area_files($this->attachments, $context->id, 'mod_wiki', 'attachments', $this->subwiki->id); return null; - //return wiki_process_attachments($this->attachments, $this->deleteuploads, $context->id, 'wiki_attachments', $this->subwiki->id); + //return wiki_process_attachments($this->attachments, $this->deleteuploads, $context->id, 'mod_wiki', 'attachments', $this->subwiki->id); } } } @@ -1907,8 +1908,9 @@ protected function print_save() { $params = array('attachmentoptions' => page_wiki_edit::$attachmentoptions, 'format' => $this->format, 'version' => $this->versionnumber); if ($this->format != 'html') { - $params['contextid'] = $context->id; - $params['filearea'] = 'wiki_attachments'; + $params['contextid'] = $context->id; + $params['component'] = 'mod_wiki'; + $params['filearea'] = 'attachments'; $params['fileitemid'] = $this->page->id; } @@ -1918,7 +1920,7 @@ protected function print_save() { $data = false; if ($data = $form->get_data()) { if ($this->format == 'html') { - $data = file_postupdate_standard_editor($data, 'newcontent', page_wiki_edit::$attachmentoptions, $context, 'wiki_attachments', $this->subwiki->id); + $data = file_postupdate_standard_editor($data, 'newcontent', page_wiki_edit::$attachmentoptions, $context, 'mod_wiki', 'attachments', $this->subwiki->id); } if (isset($this->section)) { diff --git a/mod/wiki/renderer.php b/mod/wiki/renderer.php index 9b326974a0d08..9933ac0255e51 100644 --- a/mod/wiki/renderer.php +++ b/mod/wiki/renderer.php @@ -63,7 +63,7 @@ public function search_result($records) { $table->head = array('title' => $page->title . ' (' . html_writer::link($CFG->wwwroot . '/mod/wiki/view.php?pageid=' . $page->id, get_string('view', 'wiki')) . ')'); $table->align = array('title' => 'left'); $table->width = '100%'; - $table->data = array(array(file_rewrite_pluginfile_urls($page->cachedcontent, 'pluginfile.php', $context->id, 'wiki_attachments', $page->id))); + $table->data = array(array(file_rewrite_pluginfile_urls($page->cachedcontent, 'pluginfile.php', $context->id, 'mod_wiki', 'attachments', $page->id))); $table->colclasses = array('wikisearchresults'); $html .= html_writer::table($table); } diff --git a/mod/workshop/db/upgrade.php b/mod/workshop/db/upgrade.php index 154f6fbeff29b..c2bcc2ab237fe 100644 --- a/mod/workshop/db/upgrade.php +++ b/mod/workshop/db/upgrade.php @@ -163,9 +163,10 @@ function xmldb_workshop_upgrade($oldversion) { echo $OUTPUT->notification('Unsupported submission filename: ' . $filepath); continue; } - if (! $fs->file_exists($context->id, 'workshop_submission_attachment', $submission->id, '/', $filename)) { + if (! $fs->file_exists($context->id, 'mod_workshop', 'submission_attachment', $submission->id, '/', $filename)) { $filerecord = array('contextid' => $context->id, - 'filearea' => 'workshop_submission_attachment', + 'component' => 'mod_workshop', + 'filearea' => 'submission_attachment', 'itemid' => $submission->id, 'filepath' => '/', 'filename' => $filename, diff --git a/mod/workshop/exsubmission.php b/mod/workshop/exsubmission.php index 667d1f55b3e8e..1056d30b3192c 100644 --- a/mod/workshop/exsubmission.php +++ b/mod/workshop/exsubmission.php @@ -102,9 +102,9 @@ $contentopts = array('trusttext' => true, 'subdirs' => false, 'maxfiles' => $maxfiles, 'maxbytes' => $maxbytes); $attachmentopts = array('subdirs' => true, 'maxfiles' => $maxfiles, 'maxbytes' => $maxbytes); $example = file_prepare_standard_editor($example, 'content', $contentopts, $workshop->context, - 'workshop_submission_content', $example->id); + 'mod_workshop', 'submission_content', $example->id); $example = file_prepare_standard_filemanager($example, 'attachment', $attachmentopts, $workshop->context, - 'workshop_submission_attachment', $example->id); + 'mod_workshop', 'submission_attachment', $example->id); $mform = new workshop_submission_form($PAGE->url, array('current' => $example, 'workshop' => $workshop, 'contentopts' => $contentopts, 'attachmentopts' => $attachmentopts)); @@ -132,9 +132,9 @@ } // save and relink embedded images and save attachments $formdata = file_postupdate_standard_editor($formdata, 'content', $contentopts, $workshop->context, - 'workshop_submission_content', $formdata->id); + 'mod_workshop', 'submission_content', $formdata->id); $formdata = file_postupdate_standard_filemanager($formdata, 'attachment', $attachmentopts, $workshop->context, - 'workshop_submission_attachment', $formdata->id); + 'mod_workshop', 'submission_attachment', $formdata->id); if (empty($formdata->attachment)) { // explicit cast to zero integer $formdata->attachment = 0; diff --git a/mod/workshop/fileinfolib.php b/mod/workshop/fileinfolib.php index 994fdb878b1e0..857b62818fbfa 100644 --- a/mod/workshop/fileinfolib.php +++ b/mod/workshop/fileinfolib.php @@ -54,6 +54,7 @@ public function __construct($browser, $course, $cm, $context, $areas, $filearea) */ public function get_params() { return array('contextid'=>$this->context->id, + 'component'=>'mod_workshop', 'filearea' =>$this->filearea, 'itemid' =>null, 'filepath' =>null, @@ -92,7 +93,7 @@ public function get_children() { global $DB; $children = array(); - $itemids = $DB->get_records('files', array('contextid' => $this->context->id, 'filearea' => $this->filearea), + $itemids = $DB->get_records('files', array('contextid' => $this->context->id, 'component' => 'mod_workshop', 'filearea' => $this->filearea), 'itemid', "DISTINCT itemid"); foreach ($itemids as $itemid => $unused) { if ($child = $this->browser->get_file_info($this->context, $this->filearea, $itemid)) { diff --git a/mod/workshop/form/accumulative/lib.php b/mod/workshop/form/accumulative/lib.php index b1adb0368327a..0e0f3145cc744 100644 --- a/mod/workshop/form/accumulative/lib.php +++ b/mod/workshop/form/accumulative/lib.php @@ -28,6 +28,41 @@ require_once(dirname(dirname(__FILE__)) . '/lib.php'); // interface definition require_once($CFG->libdir . '/gradelib.php'); // to handle float vs decimal issues +function workshopform_accumulative_pluginfile($course, $cm, $context, $filearea, array $args, $forcedownload) { + global $DB; + + if ($context->contextlevel != CONTEXT_MODULE) { + return false; + } + + require_login($course, true, $cm); + + if ($filearea !== 'description') { + return false; + } + + $itemid = (int)array_shift($args); // the id of the assessment form dimension + if (!$workshop = $DB->get_record('workshop', array('id' => $cm->instance))) { + send_file_not_found(); + } + + if (!$dimension = $DB->get_record('workshopform_accumulative', array('id' => $itemid ,'workshopid' => $workshop->id))) { + send_file_not_found(); + } + + // TODO now make sure the user is allowed to see the file + // (media embedded into the dimension description) + $fs = get_file_storage(); + $relativepath = implode('/', $args); + $fullpath = "/$context->id/workshopform_accumulative/$filearea/$itemid/$relativepath"; + if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + return false; + } + + // finally send the file + send_stored_file($file); +} + /** * Accumulative grading strategy logic. */ @@ -84,7 +119,7 @@ public function get_edit_strategy_form($actionurl=null) { for ($i = 0; $i < $nodimensions; $i++) { // prepare all editor elements $fields = file_prepare_standard_editor($fields, 'description__idx_'.$i, $this->descriptionopts, - $PAGE->context, 'workshopform_accumulative_description', $fields->{'dimensionid__idx_'.$i}); + $PAGE->context, 'workshopform_accumulative', 'description', $fields->{'dimensionid__idx_'.$i}); } $customdata = array(); @@ -138,7 +173,7 @@ public function save_edit_strategy_form(stdclass $data) { } // re-save with correct path to embeded media files $record = file_postupdate_standard_editor($record, 'description', $this->descriptionopts, - $PAGE->context, 'workshopform_accumulative_description', $record->id); + $PAGE->context, 'workshopform_accumulative', 'description', $record->id); $DB->update_record('workshopform_accumulative', $record); } $this->delete_dimensions($todelete); @@ -165,7 +200,7 @@ public function get_assessment_form(moodle_url $actionurl=null, $mode='preview', // rewrite URLs to the embeded files for ($i = 0; $i < $nodimensions; $i++) { $fields->{'description__idx_'.$i} = file_rewrite_pluginfile_urls($fields->{'description__idx_'.$i}, - 'pluginfile.php', $PAGE->context->id, 'workshopform_accumulative_description', $fields->{'dimensionid__idx_'.$i}); + 'pluginfile.php', $PAGE->context->id, 'workshopform_accumulative', 'description', $fields->{'dimensionid__idx_'.$i}); } if ('assessment' === $mode and !empty($assessment)) { @@ -377,7 +412,7 @@ protected function delete_dimensions(array $ids) { $fs = get_file_storage(); foreach ($ids as $id) { if (!empty($id)) { // to prevent accidental removal of all files in the area - $fs->delete_area_files($PAGE->context->id, 'workshopform_accumulative_description', $id); + $fs->delete_area_files($PAGE->context->id, 'workshopform_accumulative', 'description', $id); } } $DB->delete_records_list('workshopform_accumulative', 'id', $ids); diff --git a/mod/workshop/form/comments/lib.php b/mod/workshop/form/comments/lib.php index 141f11d29ecbd..85be3d1f02610 100644 --- a/mod/workshop/form/comments/lib.php +++ b/mod/workshop/form/comments/lib.php @@ -28,6 +28,41 @@ require_once(dirname(dirname(__FILE__)) . '/lib.php'); // interface definition require_once($CFG->libdir . '/gradelib.php'); // to handle float vs decimal issues +function workshopform_comments_pluginfile($course, $cm, $context, $filearea, array $args, $forcedownload) { + global $DB; + + if ($context->contextlevel != CONTEXT_MODULE) { + return false; + } + + require_login($course, true, $cm); + + if ($filearea !== 'description') { + return false; + } + + $itemid = (int)array_shift($args); // the id of the assessment form dimension + if (!$workshop = $DB->get_record('workshop', array('id' => $cm->instance))) { + send_file_not_found(); + } + + if (!$dimension = $DB->get_record('workshopform_comments', array('id' => $itemid ,'workshopid' => $workshop->id))) { + send_file_not_found(); + } + + // TODO now make sure the user is allowed to see the file + // (media embedded into the dimension description) + $fs = get_file_storage(); + $relativepath = implode('/', $args); + $fullpath = "/$context->id/workshopform_comments/$filearea/$itemid/$relativepath"; + if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + return false; + } + + // finally send the file + send_stored_file($file); +} + /** * Accumulative grading strategy logic. */ @@ -84,7 +119,7 @@ public function get_edit_strategy_form($actionurl=null) { for ($i = 0; $i < $nodimensions; $i++) { // prepare all editor elements $fields = file_prepare_standard_editor($fields, 'description__idx_'.$i, $this->descriptionopts, - $PAGE->context, 'workshopform_comments_description', $fields->{'dimensionid__idx_'.$i}); + $PAGE->context, 'workshopform_comments', 'description', $fields->{'dimensionid__idx_'.$i}); } $customdata = array(); @@ -138,7 +173,7 @@ public function save_edit_strategy_form(stdclass $data) { } // re-save with correct path to embeded media files $record = file_postupdate_standard_editor($record, 'description', $this->descriptionopts, - $PAGE->context, 'workshopform_comments_description', $record->id); + $PAGE->context, 'workshopform_comments', 'description', $record->id); $DB->update_record('workshopform_comments', $record); } $this->delete_dimensions($todelete); @@ -165,7 +200,7 @@ public function get_assessment_form(moodle_url $actionurl=null, $mode='preview', // rewrite URLs to the embeded files for ($i = 0; $i < $nodimensions; $i++) { $fields->{'description__idx_'.$i} = file_rewrite_pluginfile_urls($fields->{'description__idx_'.$i}, - 'pluginfile.php', $PAGE->context->id, 'workshopform_comments_description', $fields->{'dimensionid__idx_'.$i}); + 'pluginfile.php', $PAGE->context->id, 'workshopform_comments', 'description', $fields->{'dimensionid__idx_'.$i}); } if ('assessment' === $mode and !empty($assessment)) { @@ -353,7 +388,7 @@ protected function delete_dimensions(array $ids) { $fs = get_file_storage(); foreach ($ids as $id) { if (!empty($id)) { // to prevent accidental removal of all files in the area - $fs->delete_area_files($PAGE->context->id, 'workshopform_comments_description', $id); + $fs->delete_area_files($PAGE->context->id, 'workshopform_comments', 'description', $id); } } $DB->delete_records_list('workshopform_comments', 'id', $ids); diff --git a/mod/workshop/form/numerrors/lib.php b/mod/workshop/form/numerrors/lib.php index 2d4eb31b9ab34..38a4a1799cb10 100644 --- a/mod/workshop/form/numerrors/lib.php +++ b/mod/workshop/form/numerrors/lib.php @@ -28,6 +28,41 @@ require_once(dirname(dirname(__FILE__)) . '/lib.php'); // interface definition require_once($CFG->libdir . '/gradelib.php'); // to handle float vs decimal issues +function workshopform_numerrors_pluginfile($course, $cm, $context, $filearea, array $args, $forcedownload) { + global $DB; + + if ($context->contextlevel != CONTEXT_MODULE) { + return false; + } + + require_login($course, true, $cm); + + if ($filearea !== 'description') { + return false; + } + + $itemid = (int)array_shift($args); // the id of the assessment form dimension + if (!$workshop = $DB->get_record('workshop', array('id' => $cm->instance))) { + send_file_not_found(); + } + + if (!$dimension = $DB->get_record('workshopform_numerrors', array('id' => $itemid ,'workshopid' => $workshop->id))) { + send_file_not_found(); + } + + // TODO now make sure the user is allowed to see the file + // (media embedded into the dimension description) + $fs = get_file_storage(); + $relativepath = implode('/', $args); + $fullpath = "/$context->id/workshopform_numerrors/$filearea/$itemid/$relativepath"; + if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + return false; + } + + // finally send the file + send_stored_file($file); +} + /** * "Number of errors" grading strategy logic. */ @@ -88,7 +123,7 @@ public function get_edit_strategy_form($actionurl=null) { for ($i = 0; $i < $nodimensions; $i++) { // prepare all editor elements $fields = file_prepare_standard_editor($fields, 'description__idx_'.$i, $this->descriptionopts, - $PAGE->context, 'workshopform_numerrors_description', $fields->{'dimensionid__idx_'.$i}); + $PAGE->context, 'workshopform_numerror', 'description', $fields->{'dimensionid__idx_'.$i}); } $customdata = array(); @@ -144,7 +179,7 @@ public function save_edit_strategy_form(stdclass $data) { } // re-save with correct path to embeded media files $record = file_postupdate_standard_editor($record, 'description', $this->descriptionopts, $PAGE->context, - 'workshopform_numerrors_description', $record->id); + 'workshopform_numerrors', 'description', $record->id); $DB->update_record('workshopform_numerrors', $record); } $this->delete_dimensions($todelete); @@ -200,7 +235,7 @@ public function get_assessment_form(moodle_url $actionurl=null, $mode='preview', // rewrite URLs to the embeded files for ($i = 0; $i < $nodimensions; $i++) { $fields->{'description__idx_'.$i} = file_rewrite_pluginfile_urls($fields->{'description__idx_'.$i}, - 'pluginfile.php', $PAGE->context->id, 'workshopform_numerrors_description', $fields->{'dimensionid__idx_'.$i}); + 'pluginfile.php', $PAGE->context->id, 'workshopform_numerrors', 'description', $fields->{'dimensionid__idx_'.$i}); } if ('assessment' === $mode and !empty($assessment)) { @@ -411,7 +446,7 @@ protected function delete_dimensions(array $ids) { $fs = get_file_storage(); foreach ($ids as $id) { - $fs->delete_area_files($PAGE->context->id, 'workshopform_numerrors_description', $id); + $fs->delete_area_files($PAGE->context->id, 'workshopform_numerrors', 'description', $id); } $DB->delete_records_list('workshopform_numerrors', 'id', $ids); } diff --git a/mod/workshop/form/rubric/lib.php b/mod/workshop/form/rubric/lib.php index 0dc86fd3e8e60..056d4133094b3 100644 --- a/mod/workshop/form/rubric/lib.php +++ b/mod/workshop/form/rubric/lib.php @@ -28,6 +28,41 @@ require_once(dirname(dirname(__FILE__)) . '/lib.php'); // interface definition require_once($CFG->libdir . '/gradelib.php'); // to handle float vs decimal issues +function workshopform_rubric_pluginfile($course, $cm, $context, $filearea, array $args, $forcedownload) { + global $DB; + + if ($context->contextlevel != CONTEXT_MODULE) { + return false; + } + + require_login($course, true, $cm); + + if ($filearea !== 'description') { + return false; + } + + $itemid = (int)array_shift($args); // the id of the assessment form dimension + if (!$workshop = $DB->get_record('workshop', array('id' => $cm->instance))) { + send_file_not_found(); + } + + if (!$dimension = $DB->get_record('workshopform_rubric', array('id' => $itemid ,'workshopid' => $workshop->id))) { + send_file_not_found(); + } + + // TODO now make sure the user is allowed to see the file + // (media embedded into the dimension description) + $fs = get_file_storage(); + $relativepath = implode('/', $args); + $fullpath = "/$context->id/workshopform_rubric/$filearea/$itemid/$relativepath"; + if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + return false; + } + + // finally send the file + send_stored_file($file); +} + /** * Rubric grading strategy logic. */ @@ -94,7 +129,7 @@ public function get_edit_strategy_form($actionurl=null) { for ($i = 0; $i < $nodimensions; $i++) { // prepare all editor elements $fields = file_prepare_standard_editor($fields, 'description__idx_'.$i, $this->descriptionopts, - $this->workshop->context, 'workshopform_rubric_description', $fields->{'dimensionid__idx_'.$i}); + $this->workshop->context, 'workshopform_rubric', 'description', $fields->{'dimensionid__idx_'.$i}); } $customdata = array(); @@ -160,7 +195,7 @@ public function save_edit_strategy_form(stdclass $data) { } // re-save with correct path to embeded media files $record = file_postupdate_standard_editor($record, 'description', $this->descriptionopts, - $this->workshop->context, 'workshopform_rubric_description', $record->id); + $this->workshop->context, 'workshopform_rubric', 'description', $record->id); $DB->update_record('workshopform_rubric', $record); // create/update the criterion levels @@ -205,7 +240,7 @@ public function get_assessment_form(moodle_url $actionurl=null, $mode='preview', // rewrite URLs to the embeded files for ($i = 0; $i < $nodimensions; $i++) { $fields->{'description__idx_'.$i} = file_rewrite_pluginfile_urls($fields->{'description__idx_'.$i}, - 'pluginfile.php', $this->workshop->context->id, 'workshopform_rubric_description', + 'pluginfile.php', $this->workshop->context->id, 'workshopform_rubric', 'description', $fields->{'dimensionid__idx_'.$i}); } @@ -448,7 +483,7 @@ protected function delete_dimensions(array $ids) { $fs = get_file_storage(); foreach ($ids as $id) { if (!empty($id)) { // to prevent accidental removal of all files in the area - $fs->delete_area_files($this->workshop->context->id, 'workshopform_rubric_description', $id); + $fs->delete_area_files($this->workshop->context->id, 'workshopform_rubric', 'description', $id); } } $DB->delete_records_list('workshopform_rubric', 'id', $ids); diff --git a/mod/workshop/lib.php b/mod/workshop/lib.php index 7bfceabf5b51c..c0361e872c59c 100644 --- a/mod/workshop/lib.php +++ b/mod/workshop/lib.php @@ -83,13 +83,13 @@ function workshop_add_instance(stdclass $workshop) { // process the custom wysiwyg editors if ($draftitemid = $workshop->instructauthorseditor['itemid']) { - $workshop->instructauthors = file_save_draft_area_files($draftitemid, $context->id, 'workshop_instructauthors', + $workshop->instructauthors = file_save_draft_area_files($draftitemid, $context->id, 'mod_workshop', 'instructauthors', 0, workshop::instruction_editors_options($context), $workshop->instructauthorseditor['text']); $workshop->instructauthorsformat = $workshop->instructauthorseditor['format']; } if ($draftitemid = $workshop->instructreviewerseditor['itemid']) { - $workshop->instructreviewers = file_save_draft_area_files($draftitemid, $context->id, 'workshop_instructreviewers', + $workshop->instructreviewers = file_save_draft_area_files($draftitemid, $context->id, 'mod_workshop', 'instructreviewers', 0, workshop::instruction_editors_options($context), $workshop->instructreviewerseditor['text']); $workshop->instructreviewersformat = $workshop->instructreviewerseditor['format']; } @@ -130,13 +130,13 @@ function workshop_update_instance(stdclass $workshop) { // process the custom wysiwyg editors if ($draftitemid = $workshop->instructauthorseditor['itemid']) { - $workshop->instructauthors = file_save_draft_area_files($draftitemid, $context->id, 'workshop_instructauthors', + $workshop->instructauthors = file_save_draft_area_files($draftitemid, $context->id, 'mod_workshop', 'instructauthors', 0, workshop::instruction_editors_options($context), $workshop->instructauthorseditor['text']); $workshop->instructauthorsformat = $workshop->instructauthorseditor['format']; } if ($draftitemid = $workshop->instructreviewerseditor['itemid']) { - $workshop->instructreviewers = file_save_draft_area_files($draftitemid, $context->id, 'workshop_instructreviewers', + $workshop->instructreviewers = file_save_draft_area_files($draftitemid, $context->id, 'mod_workshop', 'instructreviewers', 0, workshop::instruction_editors_options($context), $workshop->instructreviewerseditor['text']); $workshop->instructreviewersformat = $workshop->instructreviewerseditor['format']; } @@ -428,7 +428,7 @@ function workshop_update_grades(stdclass $workshop, $userid=0) { * Returns the lists of all browsable file areas within the given module context * * The file area workshop_intro for the activity introduction field is added automatically - * by {@link file_browser::get_file_info_module()} + * by {@link file_browser::get_file_info_context_module()} * * @param stdclass $course * @param stdclass $cm @@ -437,12 +437,11 @@ function workshop_update_grades(stdclass $workshop, $userid=0) { */ function workshop_get_file_areas($course, $cm, $context) { $areas = array(); - if (has_capability('moodle/course:managefiles', $context)) { - $areas['workshop_instructauthors'] = get_string('areainstructauthors', 'workshop'); - $areas['workshop_instructreviewers'] = get_string('areainstructreviewers', 'workshop'); - $areas['workshop_submission_content'] = get_string('areasubmissioncontent', 'workshop'); - $areas['workshop_submission_attachment'] = get_string('areasubmissionattachment', 'workshop'); - } + $areas['instructauthors'] = get_string('areainstructauthors', 'workshop'); + $areas['instructreviewers'] = get_string('areainstructreviewers', 'workshop'); + $areas['submission_content'] = get_string('areasubmissioncontent', 'workshop'); + $areas['submission_attachment'] = get_string('areasubmissionattachment', 'workshop'); + return $areas; } @@ -454,37 +453,35 @@ function workshop_get_file_areas($course, $cm, $context) { * the fileareas workshop_submission_content and workshop_submission_attachment are used. * The access rights to the files are checked here. The user must be either a peer-reviewer * of the submission or have capability ... (todo) to access the submission files. - * Besides that, areas workshop_instructauthors and workshop_instructreviewers contain the media + * Besides that, areas workshop_instructauthors and mod_workshop instructreviewers contain the media * embedded using the mod_form.php. * * @param stdclass $course - * @param stdclass $cminfo + * @param stdclass $cm * @param stdclass $context * @param string $filearea * @param array $args * @param bool $forcedownload * @return void this should never return to the caller */ -function workshop_pluginfile($course, $cminfo, $context, $filearea, array $args, $forcedownload) { +function workshop_pluginfile($course, $cm, $context, $filearea, array $args, $forcedownload) { global $DB; - if (!$cminfo->uservisible) { - send_file_not_found(); - } - if (!$cm = get_coursemodule_from_instance('workshop', $cminfo->instance, $course->id)) { - send_file_not_found(); + if ($context->contextlevel != CONTEXT_MODULE) { + return false; } + require_login($course, true, $cm); - if ($filearea === 'workshop_instructauthors') { + if ($filearea === 'instructauthors') { // submission instructions may contain sensitive data if (!has_any_capability(array('moodle/course:manageactivities', 'mod/workshop:submit'), $context)) { send_file_not_found(); } array_shift($args); // we do not use itemids here - $relativepath = '/' . implode('/', $args); - $fullpath = $context->id . $filearea . '0' . $relativepath; // beware, slashes are not used here! + $relativepath = implode('/', $args); + $fullpath = "/$context->id/mod_workshop/$filearea/0/$relativepath"; // beware, slashes are not used here! $fs = get_file_storage(); if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { @@ -497,15 +494,15 @@ function workshop_pluginfile($course, $cminfo, $context, $filearea, array $args, send_stored_file($file, $lifetime, 0); } - if ($filearea === 'workshop_instructreviewers') { + if ($filearea === 'instructreviewers') { // submission instructions may contain sensitive data if (!has_any_capability(array('moodle/course:manageactivities', 'mod/workshop:peerassess'), $context)) { send_file_not_found(); } array_shift($args); // we do not use itemids here - $relativepath = '/' . implode('/', $args); - $fullpath = $context->id . $filearea . '0' . $relativepath; // beware, slashes are not used here! + $relativepath = implode('/', $args); + $fullpath = "/$context->id/mod_workshop/$filearea/0/$relativepath"; // beware, slashes are not used here! $fs = get_file_storage(); if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { @@ -516,67 +513,19 @@ function workshop_pluginfile($course, $cminfo, $context, $filearea, array $args, // finally send the file send_stored_file($file, $lifetime, 0); - } - - // the following file areas are for the files embedded into the assessment forms - // TODO this should be rewritten to using callbacks into subplugins - if (in_array($filearea, array( - 'workshopform_comments_description', - 'workshopform_accumulative_description', - 'workshopform_numerrors_description', - 'workshopform_rubric_description', - ))) { - $itemid = (int)array_shift($args); // the id of the assessment form dimension - if (!$workshop = $DB->get_record('workshop', array('id' => $cminfo->instance))) { - send_file_not_found(); - } - switch ($filearea) { - case 'workshopform_comments_description': - $dimension = $DB->get_record('workshopform_comments', array('id' => $itemid)); - break; - case 'workshopform_accumulative_description': - $dimension = $DB->get_record('workshopform_accumulative', array('id' => $itemid)); - break; - case 'workshopform_numerrors_description': - $dimension = $DB->get_record('workshopform_numerrors', array('id' => $itemid)); - break; - case 'workshopform_rubric_description': - $dimension = $DB->get_record('workshopform_rubric', array('id' => $itemid)); - break; - default: - $dimension = false; - } - if (empty($dimension)) { - send_file_not_found(); - } - if ($workshop->id != $dimension->workshopid) { - // this should never happen but just in case - send_file_not_found(); - } - // TODO now make sure the user is allowed to see the file - // (media embedded into the dimension description) - $fs = get_file_storage(); - $relativepath = '/' . implode('/', $args); - $fullpath = $context->id . $filearea . $itemid . $relativepath; - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { - return false; - } - // finally send the file - send_stored_file($file); - } - if ($filearea == 'workshop_submission_content' or $filearea == 'workshop_submission_attachment') { + } else if ($filearea === 'submission_content' or $filearea === 'submission_attachment') { $itemid = (int)array_shift($args); - if (!$submission = $DB->get_record('workshop_submissions', array('id' => $itemid))) { + if (!$workshop = $DB->get_record('workshop', array('id' => $cm->instance))) { return false; } - if (!$workshop = $DB->get_record('workshop', array('id' => $cminfo->instance))) { + if (!$submission = $DB->get_record('workshop_submissions', array('id' => $itemid, 'workshopid' => $workshop->id))) { return false; } // TODO now make sure the user is allowed to see the file $fs = get_file_storage(); - $relativepath = '/' . implode('/', $args); - $fullpath = $context->id . $filearea . $itemid . $relativepath; + $relativepath = implode('/', $args); + $fullpath = "/$context->id/mod_workshop/$filearea/$itemid/$relativepath"; if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { return false; } @@ -611,7 +560,7 @@ function workshop_get_file_info($browser, $areas, $course, $cm, $context, $filea $fs = get_file_storage(); - if ($filearea === 'workshop_submission_content' or $filearea === 'workshop_submission_attachment') { + if ($filearea === 'content' or $filearea === 'attachment') { if (is_null($itemid)) { require_once($CFG->dirroot . '/mod/workshop/fileinfolib.php'); @@ -623,9 +572,9 @@ function workshop_get_file_info($browser, $areas, $course, $cm, $context, $filea $filepath = is_null($filepath) ? '/' : $filepath; $filename = is_null($filename) ? '.' : $filename; - if (!$storedfile = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) { + if (!$storedfile = $fs->get_file($context->id, 'mod_workshop', $filearea, $itemid, $filepath, $filename)) { if ($filepath === '/' and $filename === '.') { - $storedfile = new virtual_root_file($context->id, $filearea, $itemid); + $storedfile = new virtual_root_file($context->id, 'mod_workshop', $filearea, $itemid); } else { // not found return null; @@ -647,16 +596,16 @@ function workshop_get_file_info($browser, $areas, $course, $cm, $context, $filea return new file_info_stored($browser, $context, $storedfile, $urlbase, $topvisiblename, true, true, false, false); } - if ($filearea == 'workshop_instructauthors' or $filearea == 'workshop_instructreviewers') { + if ($filearea == 'instructauthors' or $filearea == 'instructreviewers') { // always only itemid 0 $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 (!$storedfile = $fs->get_file($context->id, 'mod_workshop', $filearea, 0, $filepath, $filename)) { if ($filepath === '/' and $filename === '.') { - $storedfile = new virtual_root_file($context->id, $filearea, 0); + $storedfile = new virtual_root_file($context->id, 'mod_workshop', $filearea, 0); } else { // not found return null; diff --git a/mod/workshop/mod_form.php b/mod/workshop/mod_form.php index d937fd334da4d..29c6bf5d1fade 100644 --- a/mod/workshop/mod_form.php +++ b/mod/workshop/mod_form.php @@ -192,7 +192,7 @@ function data_preprocessing(&$data) { // editing an existing workshop - let us prepare the added editor elements (intro done automatically) $draftitemid = file_get_submitted_draft_itemid('instructauthors'); $data['instructauthorseditor']['text'] = file_prepare_draft_area($draftitemid, $this->context->id, - 'workshop_instructauthors', false, + 'mod_workshop', 'instructauthors', false, workshop::instruction_editors_options($this->context), $data['instructauthors']); $data['instructauthorseditor']['format'] = $data['instructauthorsformat']; @@ -200,7 +200,7 @@ function data_preprocessing(&$data) { $draftitemid = file_get_submitted_draft_itemid('instructreviewers'); $data['instructreviewerseditor']['text'] = file_prepare_draft_area($draftitemid, $this->context->id, - 'workshop_instructreviewers', false, + 'mod_workshop', 'instructreviewers', false, workshop::instruction_editors_options($this->context), $data['instructreviewers']); $data['instructreviewerseditor']['format'] = $data['instructreviewersformat']; diff --git a/mod/workshop/renderer.php b/mod/workshop/renderer.php index ecbbae268e505..ebc253c717dc3 100644 --- a/mod/workshop/renderer.php +++ b/mod/workshop/renderer.php @@ -202,7 +202,7 @@ public function submission_full(stdclass $submission, $showauthorname=false) { $content = format_text($submission->content, $submission->contentformat); $content = file_rewrite_pluginfile_urls($content, 'pluginfile.php', $this->page->context->id, - 'workshop_submission_content', $submission->id); + 'workshop_submission', 'content', $submission->id); $o .= $this->output->container($content, 'content'); $o .= $this->submission_attachments($submission); @@ -228,7 +228,7 @@ public function submission_attachments(stdclass $submission, $format=null) { $fs = get_file_storage(); $ctx = $this->page->context; - $files = $fs->get_area_files($ctx->id, 'workshop_submission_attachment', $submission->id); + $files = $fs->get_area_files($ctx->id, 'mod_workshop', 'submission_attachment', $submission->id); $outputimgs = ""; // images to be displayed inline $outputfiles = ""; // list of attachment files @@ -241,7 +241,7 @@ public function submission_attachments(stdclass $submission, $format=null) { $filepath = $file->get_filepath(); $filename = $file->get_filename(); $fileurl = file_encode_url($CFG->wwwroot . '/pluginfile.php', - '/' . $ctx->id . '/workshop_submission_attachment/' . $submission->id . $filepath . $filename, true); + '/' . $ctx->id . '/mod_workshop/submission_attachment/' . $submission->id . $filepath . $filename, true); $type = $file->get_mimetype(); $type = mimeinfo_from_type("type", $type); $image = html_writer::empty_tag('img', array('src'=>$this->output->pix_url(file_mimetype_icon($type)), 'alt'=>$type, 'class'=>'icon')); @@ -349,7 +349,7 @@ public function example_full(stdclass $example) { $content = format_text($example->content, $example->contentformat); $content = file_rewrite_pluginfile_urls($content, 'pluginfile.php', $this->page->context->id, - 'workshop_submission_content', $example->id); + 'workshop_submission', 'content', $example->id); $o .= $this->output->container($content, 'content'); $o .= $this->submission_attachments($example); diff --git a/mod/workshop/submission.php b/mod/workshop/submission.php index 4bad65ba90c3a..55a03e4379426 100644 --- a/mod/workshop/submission.php +++ b/mod/workshop/submission.php @@ -102,9 +102,9 @@ $contentopts = array('trusttext' => true, 'subdirs' => false, 'maxfiles' => $maxfiles, 'maxbytes' => $maxbytes); $attachmentopts = array('subdirs' => true, 'maxfiles' => $maxfiles, 'maxbytes' => $maxbytes); $submission = file_prepare_standard_editor($submission, 'content', $contentopts, $workshop->context, - 'workshop_submission_content', $submission->id); + 'mod_workshop', 'submission_content', $submission->id); $submission = file_prepare_standard_filemanager($submission, 'attachment', $attachmentopts, $workshop->context, - 'workshop_submission_attachment', $submission->id); + 'mod_workshop', 'submission_attachment', $submission->id); $mform = new workshop_submission_form($PAGE->url, array('current' => $submission, 'workshop' => $workshop, 'contentopts' => $contentopts, 'attachmentopts' => $attachmentopts)); @@ -132,9 +132,9 @@ } // save and relink embedded images and save attachments $formdata = file_postupdate_standard_editor($formdata, 'content', $contentopts, $workshop->context, - 'workshop_submission_content', $formdata->id); + 'mod_workshop', 'submission_content', $formdata->id); $formdata = file_postupdate_standard_filemanager($formdata, 'attachment', $attachmentopts, $workshop->context, - 'workshop_submission_attachment', $formdata->id); + 'mod_workshop', 'submission_attachment', $formdata->id); if (empty($formdata->attachment)) { // explicit cast to zero integer $formdata->attachment = 0; diff --git a/mod/workshop/view.php b/mod/workshop/view.php index a28d3ae86c308..0916c516b515a 100644 --- a/mod/workshop/view.php +++ b/mod/workshop/view.php @@ -96,7 +96,7 @@ case workshop::PHASE_SUBMISSION: if (trim(strip_tags($workshop->instructauthors))) { $instructions = file_rewrite_pluginfile_urls($workshop->instructauthors, 'pluginfile.php', $PAGE->context->id, - 'workshop_instructauthors', 0, workshop::instruction_editors_options($PAGE->context)); + 'mod_workshop', 'instructauthors', 0, workshop::instruction_editors_options($PAGE->context)); print_collapsible_region_start('', 'workshop-viewlet-instructauthors', get_string('instructauthors', 'workshop')); echo $output->box(format_text($instructions, $workshop->instructauthorsformat), array('generalbox', 'instructions')); print_collapsible_region_end(); @@ -201,7 +201,7 @@ } if (trim(strip_tags($workshop->instructreviewers))) { $instructions = file_rewrite_pluginfile_urls($workshop->instructreviewers, 'pluginfile.php', $PAGE->context->id, - 'workshop_instructreviewers', 0, workshop::instruction_editors_options($PAGE->context)); + 'mod_workshop', 'instructreviewers', 0, workshop::instruction_editors_options($PAGE->context)); print_collapsible_region_start('', 'workshop-viewlet-instructreviewers', get_string('instructreviewers', 'workshop')); echo $output->box(format_text($instructions, $workshop->instructreviewersformat), array('generalbox', 'instructions')); print_collapsible_region_end(); diff --git a/pluginfile.php b/pluginfile.php index 243bc2ee4e737..24e638db1fcd2 100644 --- a/pluginfile.php +++ b/pluginfile.php @@ -18,14 +18,15 @@ /** * This script delegates file serving to individual plugins * - * @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 */ // disable moodle specific debug messages and any errors in output -define('NO_DEBUG_DISPLAY', true); +//define('NO_DEBUG_DISPLAY', true); +//TODO: uncomment this once the file api stabilises a bit more require_once('config.php'); require_once('lib/filelib.php'); @@ -43,16 +44,16 @@ // extract relative path components $args = explode('/', ltrim($relativepath, '/')); -if (count($args) == 0) { // always at least user id +if (count($args) < 3) { // always at least context, component and filearea print_error('invalidarguments'); } $contextid = (int)array_shift($args); -$filearea = array_shift($args); +$component = clean_param(array_shift($args), PARAM_SAFEDIR); +$filearea = clean_param(array_shift($args), PARAM_SAFEDIR); + +list($context, $course, $cm) = get_context_info_array($contextid); -if (!$context = get_context_instance_by_id($contextid)) { - send_file_not_found(); -} $fs = get_file_storage(); // If the file is a Flash file and that the user flash player is outdated return a flash upgrader MDL-20841 @@ -60,116 +61,158 @@ if (!empty($CFG->excludeoldflashclients) && $mimetype == 'application/x-shockwave-flash'&& !empty($SESSION->flashversion)) { $userplayerversion = explode('.', $SESSION->flashversion); $requiredplayerversion = explode('.', $CFG->excludeoldflashclients); - $sendflashupgrader = true; -} -if (!empty($sendflashupgrader) && (($userplayerversion[0] < $requiredplayerversion[0]) || + if (($userplayerversion[0] < $requiredplayerversion[0]) || ($userplayerversion[0] == $requiredplayerversion[0] && $userplayerversion[1] < $requiredplayerversion[1]) || ($userplayerversion[0] == $requiredplayerversion[0] && $userplayerversion[1] == $requiredplayerversion[1] - && $userplayerversion[2] < $requiredplayerversion[2]))) { + && $userplayerversion[2] < $requiredplayerversion[2])) { $path = $CFG->dirroot."/lib/flashdetect/flashupgrade.swf"; // Alternate content asking user to upgrade Flash $filename = "flashupgrade.swf"; - $lifetime = 0; // Do not cache - send_file($path, $filename, $lifetime, 0, false, false, $mimetype); + send_file($path, $filename, O, 0, false, false, 'application/x-shockwave-flash'); // Do not cache + } +} -} else if ($context->contextlevel == CONTEXT_SYSTEM) { - if ($filearea === 'blog_attachment' || $filearea === 'blog_post') { +// ======================================================================================================================== +if ($component === 'blog') { + // Blog file serving + if ($context->contextlevel != CONTEXT_SYSTEM) { + send_file_not_found(); + } + if ($filearea !== 'attachment' and $filearea !== 'post') { + send_file_not_found(); + } - if (empty($CFG->bloglevel)) { - print_error('siteblogdisable', 'blog'); - } - if ($CFG->bloglevel < BLOG_GLOBAL_LEVEL) { - require_login(); - if (isguestuser()) { - print_error('noguest'); - } - if ($CFG->bloglevel == BLOG_USER_LEVEL) { - if ($USER->id != $entry->userid) { - send_file_not_found(); - } - } - } - $entryid = (int)array_shift($args); - if (!$entry = $DB->get_record('post', array('module'=>'blog', 'id'=>$entryid))) { - send_file_not_found(); - } - if ('publishstate' === 'public') { - if ($CFG->forcelogin) { - require_login(); - } + if (empty($CFG->bloglevel)) { + print_error('siteblogdisable', 'blog'); + } - } else if ('publishstate' === 'site') { - require_login(); - //ok - } else if ('publishstate' === 'draft') { - require_login(); + if ($CFG->bloglevel < BLOG_GLOBAL_LEVEL) { + require_login(); + if (isguestuser()) { + print_error('noguest'); + } + if ($CFG->bloglevel == BLOG_USER_LEVEL) { if ($USER->id != $entry->userid) { send_file_not_found(); } } + } + $entryid = (int)array_shift($args); + if (!$entry = $DB->get_record('post', array('module'=>'blog', 'id'=>$entryid))) { + send_file_not_found(); + } - //TODO: implement shared course and shared group access - - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.$filearea.$entryid.$relativepath; + if ('publishstate' === 'public') { + if ($CFG->forcelogin) { + require_login(); + } - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + } else if ('publishstate' === 'site') { + require_login(); + //ok + } else if ('publishstate' === 'draft') { + require_login(); + if ($USER->id != $entry->userid) { send_file_not_found(); } + } + + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + + if (!$file = $fs->get_file($context->id, $component, $filearea, $entryid, $filepath, $filename) or $file->is_directory()) { + send_file_not_found(); + } - send_stored_file($file, 10*60, 0, true); // download MUST be forced - security! - } else if ($filearea === 'grade_outcome' || $filearea === 'grade_scale') { // CONTEXT_SYSTEM + send_stored_file($file, 10*60, 0, true); // download MUST be forced - security! + +// ======================================================================================================================== +} else if ($component === 'grade') { + if (($filearea === 'outcome' or $filearea === 'scale') and $context->contextlevel == CONTEXT_SYSTEM) { + // Global gradebook files if ($CFG->forcelogin) { require_login(); } - $fullpath = $context->id.$filearea.implode('/', $args); + $fullpath = "/$context->id/$component/$filearea/".implode('/', $args); if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); // unlock session during fileserving - send_stored_file($file, 60*60, 0, $forcedownload); // TODO: change timeout? + send_stored_file($file, 60*60, 0, $forcedownload); - } else if ($filearea === 'tag_description') { // CONTEXT_SYSTEM + } else if ($filearea === 'feedback' and $context->contextlevel == CONTEXT_COURSE) { + //TODO: nobody implemented this yet in grade edit form!! + send_file_not_found(); - // All tag descriptions are going to be public but we still need to respect forcelogin - if ($CFG->forcelogin) { - require_login(); + if ($CFG->forcelogin || $course->id !== SITEID) { + require_login($course); } - $fullpath = $context->id.$filearea.implode('/', $args); + $fullpath = "/$context->id/$component/$filearea/".implode('/', $args); if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); // unlock session during fileserving - send_stored_file($file, 60*60, 0, true); // TODO: change timeout? + send_stored_file($file, 60*60, 0, $forcedownload); + } else { + send_file_not_found(); + } - } else if ($filearea === 'calendar_event_description') { // CONTEXT_SYSTEM +// ======================================================================================================================== +} else if ($component === 'tag') { + if ($filearea === 'description' and $context->contextlevel == CONTEXT_SYSTEM) { - // All events here are public the one requirement is that we respect forcelogin + // All tag descriptions are going to be public but we still need to respect forcelogin if ($CFG->forcelogin) { require_login(); } - $fullpath = $context->id.$filearea.implode('/', $args); + $fullpath = "/$context->id/tage/description/".implode('/', $args); if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); // unlock session during fileserving - send_stored_file($file, 60*60, 0, $forcedownload); // TODO: change timeout? + send_stored_file($file, 60*60, 0, true); } else { send_file_not_found(); } -} else if ($context->contextlevel == CONTEXT_USER) { +// ======================================================================================================================== +} else if ($component === 'calendar') { + if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_SYSTEM) { - if ($filearea === 'calendar_event_description') { // CONTEXT_USER + // All events here are public the one requirement is that we respect forcelogin + if ($CFG->forcelogin) { + require_login(); + } + + // Get the event if from the args array + $eventid = array_shift($args); + + // Load the event from the database + if (!$event = $DB->get_record('event', array('id'=>(int)$eventid, 'eventtype'=>'site'))) { + send_file_not_found(); + } + // Check that we got an event and that it's userid is that of the user + + // Get the file and serve if successful + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename) or $file->is_directory()) { + send_file_not_found(); + } + + session_get_instance()->write_close(); // unlock session during fileserving + send_stored_file($file, 60*60, 0, $forcedownload); + + } else if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_USER) { // Must be logged in, if they are not then they obviously can't be this user require_login(); @@ -181,209 +224,248 @@ // Get the event if from the args array $eventid = array_shift($args); - if ((int)$eventid <= 0) { - send_file_not_found(); - } - // Load the event from the database - $event = $DB->get_record('event', array('id'=>(int)$eventid)); - // Check that we got an event and that it's userid is that of the user - if (!$event || $event->userid !== $USER->id) { + // Load the event from the database - user id must match + if (!$event = $DB->get_record('event', array('id'=>(int)$eventid, 'userid'=>$USER->id, 'eventtype'=>'user'))) { send_file_not_found(); } - // Get the file and serve if succesfull - $fullpath = $context->id.$filearea.$eventid.'/'.implode('/', $args); - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + // Get the file and serve if successful + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename) or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); // unlock session during fileserving - send_stored_file($file, 60*60, 0, $forcedownload); // TODO: change timeout? - } else if ($filearea === 'user_profile') { // CONTEXT_USER + send_stored_file($file, 60*60, 0, $forcedownload); - if ($CFG->forcelogin) { - require_login(); + } else if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_COURSE) { + + // Respect forcelogin and require login unless this is the site.... it probably + // should NEVER be the site + if ($CFG->forcelogin || $course->id !== SITEID) { + require_login($course); } - $userid = array_shift($args); - if ((int)$userid <= 0) { + // Must be able to at least view the course + if (!is_enrolled($context) and !is_viewing($context)) { + //TODO: hmm, do we really want to block guests here? send_file_not_found(); } - if (!empty($CFG->forceloginforprofiles)) { - require_login(); - if (isguestuser()) { - send_file_not_found(); - } - - if ($USER->id !== $userid) { - $usercontext = get_context_instance(CONTEXT_USER, $userid); - // The browsing user is not the current user - if (!has_coursecontact_role($userid) && !has_capability('moodle/user:viewdetails', $usercontext)) { - send_file_not_found(); - } + // Get the event id + $eventid = array_shift($args); - $canview = false; - if (has_capability('moodle/user:viewdetails', $usercontext)) { - $canview = true; - } else { - $courses = enrol_get_my_courses(); - } + // Load the event from the database we need to check whether it is + // a) valid course event + // b) a group event + // Group events use the course context (there is no group context) + if (!$event = $DB->get_record('event', array('id'=>(int)$eventid, 'courseid'=>$course->id))) { + send_file_not_found(); + } - while (!$canview && count($courses) > 0) { - $course = array_shift($courses); - if (has_capability('moodle/user:viewdetails', get_context_instance(CONTEXT_COURSE, $course->id))) { - $canview = true; - } - } + // If its a group event require either membership of view all groups capability + if ($event->eventtype === 'group') { + if (!has_capability('moodle/site:accessallgroups', $context) && !groups_is_member($event->groupid, $USER->id)) { + send_file_not_found(); } + } else if ($event->eventtype === 'course') { + //ok + } else { + // some other type + send_file_not_found(); } - $fullpath = $context->id.$filearea.$userid.'/'.implode('/', $args); - - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + // If we get this far we can serve the file + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename) or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); // unlock session during fileserving - send_stored_file($file, 60*60, 0, true); - } + send_stored_file($file, 60*60, 0, $forcedownload); - send_file_not_found(); + } else { + send_file_not_found(); + } +// ======================================================================================================================== +} else if ($component === 'user') { + if ($filearea === 'private' and $context->contextlevel == CONTEXT_USER) { + require_login(); -} else if ($context->contextlevel == CONTEXT_COURSECAT) { - if ($filearea == 'coursecat_intro') { - if ($CFG->forcelogin) { - // no login necessary - unless login forced everywhere - require_login(); + if (isguestuser()) { + send_file_not_found(); } - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.'coursecat_intro0'.$relativepath; + if ($USER->id !== $context->instanceid) { + send_file_not_found(); + } - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->get_filename() == '.') { + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, $component, $filearea, 0, $filepath, $filename) or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); // unlock session during fileserving - send_stored_file($file, 60*60, 0, $forcedownload); - } else if ($filearea == 'category_description') { + send_stored_file($file, 0, 0, true); // must force download - security! + + } else if ($filearea === 'profile' and $context->contextlevel == CONTEXT_USER) { + if ($CFG->forcelogin) { - // no login necessary - unless login forced everywhere require_login(); } - $itemid = (int)array_shift($args); - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.'category_description'.$itemid.$relativepath; + $userid = $context->instanceid; - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->get_filename() == '.') { - send_file_not_found(); - } + if ($USER->id == $userid) { + // always can access own - session_get_instance()->write_close(); // unlock session during fileserving - send_stored_file($file, 60*60, 0, $forcedownload); - } else { - send_file_not_found(); - } + } else if (!empty($CFG->forceloginforprofiles)) { + require_login(); + if (isguestuser()) { + send_file_not_found(); + } -} else if ($context->contextlevel == CONTEXT_COURSE) { - if (!$course = $DB->get_record('course', array('id'=>$context->instanceid))) { - print_error('invalidcourseid'); - } + // we allow access to site profile of all course contacts (usually teachers) + if (!has_coursecontact_role($userid) && !has_capability('moodle/user:viewdetails', $context)) { + send_file_not_found(); + } - if ($filearea === 'course_backup') { - require_login($course); - require_capability('moodle/backup:downloadfile', $context); + $canview = false; + if (has_capability('moodle/user:viewdetails', $context)) { + $canview = true; + } else { + $courses = enrol_get_my_courses(); + } - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.'course_backup0'.$relativepath; + while (!$canview && count($courses) > 0) { + $course = array_shift($courses); + if (has_capability('moodle/user:viewdetails', get_context_instance(CONTEXT_COURSE, $course->id))) { + $canview = true; + } + } + } - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, $component, $filearea, 0, $filepath, $filename) or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); // unlock session during fileserving - send_stored_file($file, 0, 0, true); + send_stored_file($file, 0, 0, true); // must force download - security! + + } else if ($filearea === 'profile' and $context->contextlevel == CONTEXT_COURSE) { + $userid = (int)array_shift($args); + $usercontext = get_context_instance(CONTEXT_USER, $userid); - } else if ($filearea === 'course_summary') { if ($CFG->forcelogin) { require_login(); } - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.'course_summary0'.$relativepath; + if (!empty($CFG->forceloginforprofiles)) { + require_login(); + if (isguestuser()) { + print_error('noguest'); + } - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + //TODO: review this logic of user profile access prevention + if (!has_coursecontact_role($userid) and !has_capability('moodle/user:viewdetails', $usercontext)) { + print_error('usernotavailable'); + } + if (!has_capability('moodle/user:viewdetails', $context) && !has_capability('moodle/user:viewdetails', $usercontext)) { + print_error('cannotviewprofile'); + } + if (!is_enrolled($context, $userid)) { + print_error('notenrolledprofile'); + } + if (groups_get_course_groupmode($course) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) { + print_error('groupnotamember'); + } + } + + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, 'user', 'profile', 0, $filepath, $filename) or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); // unlock session during fileserving - send_stored_file($file, 60*60, 0, $forcedownload); // TODO: change timeout? + send_stored_file($file, 0, 0, true); // must force download - security! - } else if ($filearea === 'course_grade_tree_feedback') { + } else if ($filearea === 'backup' and $context->contextlevel == CONTEXT_USER) { + require_login(); - if ($CFG->forcelogin || $course->id !== SITEID) { - require_login($course); + if (isguestuser()) { + send_file_not_found(); + } + if ($USER->id != $userid) { + send_file_not_found(); } - $fullpath = $context->id.$filearea.implode('/', $args); - - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, 'user', 'backup', 0, $filepath, $filename) or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); // unlock session during fileserving - send_stored_file($file, 60*60, 0, $forcedownload); // TODO: change timeout? + send_stored_file($file, 0, 0, true); // must force download - security! - } else if ($filearea === 'calendar_event_description') { // CONTEXT_COURSE + } else { + send_file_not_found(); + } - // This is for content used in course and group events +// ======================================================================================================================== +} else if ($component === 'coursecat') { + if ($context->contextlevel != CONTEXT_COURSECAT) { + send_file_not_found(); + } - // Respect forcelogin and require login unless this is the site.... it probably - // should NEVER be the site - if ($CFG->forcelogin || $course->id !== SITEID) { - require_login($course); + if ($filearea === 'description') { + if ($CFG->forcelogin) { + // no login necessary - unless login forced everywhere + require_login(); } - // Must be able to at least view the course - if (!is_enrolled($context) and !is_viewing($context)) { + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, 'coursecat', 'description', 0, $filepath, $filename) or $file->is_directory()) { send_file_not_found(); } - // Get the event id - $eventid = array_shift($args); - if ((int)$eventid <= 0) { - send_file_not_found(); - } + session_get_instance()->write_close(); // unlock session during fileserving + send_stored_file($file, 60*60, 0, $forcedownload); + } else { + send_file_not_found(); + } - // Load the event from the database we need to check whether it is - // a) valid - // b) a group event - // Group events use the course context (there is no group context) - $event = $DB->get_record('event', array('id'=>(int)$eventid)); - if (!$event || $event->userid !== $USER->id) { - send_file_not_found(); - } +// ======================================================================================================================== +} else if ($component === 'course') { + if ($context->contextlevel != CONTEXT_COURSE) { + send_file_not_found(); + } - // If its a group event require either membership of manage groups capability - if ($event->eventtype === 'group' && !has_capability('moodle/course:managegroups', $context) && !groups_is_member($event->groupid, $USER->id)) { - send_file_not_found(); + if ($filearea === 'summary') { + if ($CFG->forcelogin) { + require_login(); } - // If we get this far we can serve the file - $fullpath = $context->id.$filearea.$eventid.'/'.implode('/', $args); - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, 'course', 'summary', 0, $filepath, $filename) or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); // unlock session during fileserving - send_stored_file($file, 60*60, 0, $forcedownload); // TODO: change timeout? + send_stored_file($file, 60*60, 0, $forcedownload); - } else if ($filearea === 'course_section') { + } else if ($filearea === 'section') { if ($CFG->forcelogin) { require_login($course); } else if ($course->id !== SITEID) { @@ -400,115 +482,147 @@ } } - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.'course_section'.$sectionid.$relativepath; - - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, 'course', 'section', $sectionid, $filepath, $filename) or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); // unlock session during fileserving - send_stored_file($file, 60*60, 0, false); // TODO: change timeout? + send_stored_file($file, 60*60, 0, $forcedownload); - } else if ($filearea === 'section_backup') { - require_login($course); - require_capability('moodle/backup:downloadfile', $context); + } else { + send_file_not_found(); + } - $sectionid = (int)array_shift($args); +} else if ($component === 'group') { + if ($context->contextlevel != CONTEXT_COURSE) { + send_file_not_found(); + } - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.'section_backup'.$sectionid.$relativepath; + require_login($course); - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + $groupid = (int)array_shift($args); + + $group = $DB->get_record('groups', array('id'=>$groupid, 'courseid'=>$course->id), '*', MUST_EXIST); + if (!has_capability('moodle/site:accessallgroups', $context) && !groups_is_member($group->id, $USER->id)) { + send_file_not_found(); + } + + if ($filearea === 'description' or $filearea === 'icon') { + + //TODO: implement group image storage in file pool + + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, 'group', 'description', $group->id, $filepath, $filename) or $file->is_directory()) { send_file_not_found(); } - session_get_instance()->write_close(); - send_stored_file($file, 60*60, 0, false); + session_get_instance()->write_close(); // unlock session during fileserving + send_stored_file($file, 60*60, 0, $forcedownload); - } else if ($filearea === 'user_profile') { - $userid = (int)array_shift($args); - $usercontext = get_context_instance(CONTEXT_USER, $userid); + } else { + send_file_not_found(); + } - if ($CFG->forcelogin) { - require_login(); - } +} else if ($component === 'grouping') { + if ($context->contextlevel != CONTEXT_COURSE) { + send_file_not_found(); + } - if (!empty($CFG->forceloginforprofiles)) { - require_login(); - if (isguestuser()) { - print_error('noguest'); - } + require_login($course); - if (!has_coursecontact_role($userid) and !has_capability('moodle/user:viewdetails', $usercontext)) { - print_error('usernotavailable'); - } - if (!has_capability('moodle/user:viewdetails', $context) && - !has_capability('moodle/user:viewdetails', $usercontext)) { - print_error('cannotviewprofile'); - } - if (!is_enrolled($context, $userid)) { - print_error('notenrolledprofile'); - } - if (groups_get_course_groupmode($course) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) { - print_error('groupnotamember'); - } - } + $groupingid = (int)array_shift($args); - $relativepath = '/'.implode('/', $args); - $fullpath = $usercontext->id.'user_profile0'.$relativepath; + // note: everybody has access to grouping desc images for now + if ($filearea === 'description') { - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, 'grouping', 'description', $groupingid->id, $filepath, $filename) or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); // unlock session during fileserving - send_stored_file($file, 0, 0, true); // must force download - security! + send_stored_file($file, 60*60, 0, $forcedownload); } else { send_file_not_found(); } -} else if ($context->contextlevel == CONTEXT_MODULE) { +// ======================================================================================================================== +} else if ($component === 'backup') { + if ($filearea === 'course' and $context->contextlevel == CONTEXT_COURSE) { + require_login($course); + require_capability('moodle/backup:downloadfile', $context); - if (!$coursecontext = get_context_instance_by_id(get_parent_contextid($context))) { - send_file_not_found(); - } + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, 'backup', 'course', 0, $filepath, $filename) or $file->is_directory()) { + send_file_not_found(); + } - if (!$course = $DB->get_record('course', array('id'=>$coursecontext->instanceid))) { - send_file_not_found(); - } - $modinfo = get_fast_modinfo($course); - if (empty($modinfo->cms[$context->instanceid])) { + session_get_instance()->write_close(); // unlock session during fileserving + send_stored_file($file, 0, 0, $forcedownload); + + } else if ($filearea === 'section' and $context->contextlevel == CONTEXT_COURSE) { + require_login($course); + require_capability('moodle/backup:downloadfile', $context); + + $sectionid = (int)array_shift($args); + + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, 'backup', 'section', $sectionid, $filepath, $filename) or $file->is_directory()) { + send_file_not_found(); + } + + session_get_instance()->write_close(); + send_stored_file($file, 60*60, 0, $forcedownload); + + } else if ($filearea === 'activity' and $context->contextlevel == CONTEXT_MODULE) { + require_login($course, false, $cm); + require_capability('moodle/backup:downloadfile', $context); + + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, 'backup', 'activity', 0, $filepath, $filename) or $file->is_directory()) { + send_file_not_found(); + } + + session_get_instance()->write_close(); + send_stored_file($file, 60*60, 0, $forcedownload); + + } else { send_file_not_found(); } - $cminfo = $modinfo->cms[$context->instanceid]; - $modname = $cminfo->modname; - $libfile = "$CFG->dirroot/mod/$modname/lib.php"; - if (!file_exists($libfile)) { +// ======================================================================================================================== +} else if (strpos($component, 'mod_') === 0) { + $modname = substr($component, 4); + if (!file_exists("$CFG->dirroot/mod/$modname/lib.php")) { send_file_not_found(); } + require_once("$CFG->dirroot/mod/$modname/lib.php"); - require_once($libfile); - if ($filearea === $modname.'_intro') { - if (!plugin_supports('mod', $modname, FEATURE_MOD_INTRO, true)) { + if ($context->contextlevel == CONTEXT_MODULE) { + if ($cm->modname !== $modname) { + // somebody tries to gain illegal access, cm type must match the component! send_file_not_found(); } - if (!$cm = get_coursemodule_from_instance($modname, $cminfo->instance, $course->id)) { + } + + if ($filearea === 'intro') { + if (!plugin_supports('mod', $modname, FEATURE_MOD_INTRO, true)) { send_file_not_found(); } require_course_login($course, true, $cm); - if (!$cminfo->uservisible) { - send_file_not_found(); - } // all users may access it - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.$filearea.'0'.$relativepath; - - $fs = get_file_storage(); - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + $filename = array_pop($args); + $filepath = '/'.implode('/', $args); + if (!$file = $fs->get_file($context->id, 'mod_'.$modname, 'intro', 0, $filepath, $filename) or $file->is_directory()) { send_file_not_found(); } @@ -516,51 +630,64 @@ // finally send the file send_stored_file($file, $lifetime, 0); - } else if ($filearea === 'activity_backup') { - require_login($course); - require_capability('moodle/backup:downloadfile', $context); - - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.'activity_backup0'.$relativepath; - - 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); } - $filefunction = $modname.'_pluginfile'; + $filefunction = $component.'_pluginfile'; + $filefunctionold = $modname.'_pluginfile'; if (function_exists($filefunction)) { // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" - $filefunction($course, $cminfo, $context, $filearea, $args, $forcedownload); + $filefunction($course, $cm, $context, $filearea, $args, $forcedownload); + } else if (function_exists($filefunctionold)) { + // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" + $filefunctionold($course, $cm, $context, $filearea, $args, $forcedownload); } send_file_not_found(); -} else if ($context->contextlevel == CONTEXT_BLOCK) { - - if (!$context = get_context_instance_by_id($contextid)) { +// ======================================================================================================================== +} else if (strpos($component, 'block_') === 0) { + $blockname = substr($component, 6); + // note: no more class methods in blocks please, that is .... + if (!file_exists("$CFG->dirroot/blocks/$blockname/lib.php")) { send_file_not_found(); } - $birecord = $DB->get_record('block_instances', array('id'=>$context->instanceid), '*',MUST_EXIST); - $blockinstance = block_instance($birecord->blockname, $birecord); + require_once("$CFG->dirroot/blocks/$blockname/lib.php"); - if (strpos(get_class($blockinstance), $filearea) !== 0) { - send_file_not_found(); + if ($context->contextlevel == CONTEXT_BLOCK) { + $birecord = $DB->get_record('block_instances', array('id'=>$context->instanceid), '*',MUST_EXIST); + if ($birecord->blockname !== $blockname) { + // somebody tries to gain illegal access, cm type must match the component! + send_file_not_found(); + } + } else { + $birecord = null; } - $itemid = array_shift($args); - $filename = array_pop($args); - $filepath = '/'.join('/', $args); - - if (method_exists($blockinstance, 'send_file')) { - $blockinstance->send_file($context, $filearea, $itemid, $filepath, $filename); + $filefunction = $component.'_pluginfile'; + if (function_exists($filefunction)) { + // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" + $filefunction($course, $birecord, $context, $filearea, $args, $forcedownload); } send_file_not_found(); +} else if (strpos($component, '_') === false) { + // all core subsystems have to be specified above, no more guessing here! + send_file_not_found(); + } else { + // try to serve general plugin file in arbitrary context + $dir = get_component_directory($component); + if (!file_exists("$dir/lib.php")) { + send_file_not_found(); + } + require_once("$dir/lib.php"); + + $filefunction = $component.'_pluginfile'; + if (function_exists($filefunction)) { + // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" + $filefunction($course, $cm, $context, $filearea, $args, $forcedownload); + } + send_file_not_found(); } diff --git a/repository/draftfiles_ajax.php b/repository/draftfiles_ajax.php new file mode 100755 index 0000000000000..4c6527d858cd6 --- /dev/null +++ b/repository/draftfiles_ajax.php @@ -0,0 +1,235 @@ +. + +/** + * Draft file ajax file manager + * + * @package core + * @subpackage repository + * @copyright 2010 Dongsheng Cai + * @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'); +require_once($CFG->libdir.'/adminlib.php'); + +require_login(); +if (isguestuser()) { + print_error('noguest'); +} +require_sesskey(); + +$action = required_param('action', PARAM_ALPHA); +$draftid = required_param('itemid', PARAM_INT); + +$user_context = get_context_instance(CONTEXT_USER, $USER->id); + +// +//NOTE TO ALL DEVELOPERS: this script must deal only with draft area of current user, it has to use only file_storage and no file_browser!! +// + +switch ($action) { + case 'dir': + $data = new stdclass; + file_get_drafarea_folders($draftid, $filepath, $data); + echo json_encode($data); + die; + + case 'list': + $filepath = optional_param('filepath', '/', PARAM_PATH); + + $data = file_get_drafarea_files($draftid, $filepath); + echo json_encode($data); + die; + + case 'mkdir': + $filepath = required_param('filepath', PARAM_PATH); + $newdirname = required_param('newdirname', PARAM_FILE); + + $fs = get_file_storage(); + $fs->create_directory($user_context->id, 'user', 'draft', $draftid, file_correct_filepath(file_correct_filepath($filepath).$newdirname)); + $return = new stdclass; + $return->filepath = $filepath; + echo json_encode($return); + die; + + case 'delete': + $filename = required_param('filename', PARAM_FILE); + $filepath = required_param('filepath', PARAM_PATH); + + $fs = get_file_storage(); + $filepath = file_correct_filepath($filepath); + $return = new stdclass; + if ($stored_file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $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); + } + die; + + case 'setmainfile': + $filename = required_param('filename', PARAM_FILE); + $filepath = required_param('filepath', PARAM_PATH); + + $filepath = file_correct_filepath($filepath); + // reset sort order + file_reset_sortorder($user_context->id, 'user', 'draft', $draftid); + // set main file + $return = file_set_sortorder($user_context->id, 'user', 'draft', $draftid, $filepath, $filename, 1); + echo json_encode($return); + die; + + case 'rename': + $filename = required_param('filename', PARAM_FILE); + $filepath = required_param('filepath', PARAM_PATH); + $newfilename = required_param('newfilename', PARAM_FILE); + + $fs = get_file_storage(); + if ($fs->file_exists($user_context->id, 'user', 'draft', $draftid, $filepath, $newfilename)) { + //bad luck, we can not rename! + echo json_encode(false); + } else if ($file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, $filename)) { + $return = new object(); + $newfile = $fs->create_file_from_storedfile(array('filename'=>$newfilename), $file); + $file->delete(); + $return->filepath = $newfile->get_filepath(); + echo json_encode($return); + } else { + echo json_encode(false); + } + die; + + case 'renamedir': + $filepath = required_param('filepath', PARAM_PATH); + $newdirname = required_param('newdirname', PARAM_FILE); + + //TODO: we must update all children too - I am going to implement low level move in file_storage (skodak) + echo json_encode(false); + die; + + case 'movedir': + $filepath = required_param('filepath', PARAM_PATH); + $newfilepath = required_param('newfilepath', PARAM_PATH); + + //TODO: we must update all children too - I am going to implement low level move in file_storage (skodak) + echo json_encode(false); + die; + + case 'movefile': + $filename = required_param('filename', PARAM_FILE); + $filepath = required_param('filepath', PARAM_PATH); + $newfilepath = required_param('newfilepath', PARAM_PATH); + + $fs = get_file_storage(); + if ($fs->file_exists($user_context->id, 'user', 'draft', $draftid, $newfilepath, $filename)) { + //bad luck, we can not rename! + echo json_encode(false); + } else if ($file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, $filename)) { + $return = new object(); + $newfile = $fs->create_file_from_storedfile(array('filepath'=>$newfilepath), $file); + $file->delete(); + $return->filepath = $newfile->get_filepath(); + echo json_encode($return); + } else { + echo json_encode(false); + } + die; + + case 'zip': + $filepath = required_param('filepath', PARAM_PATH); + + $zipper = get_file_packer('application/zip'); + $fs = get_file_storage(); + + $file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, '.'); + + $parent_path = $file->get_parent_directory()->get_filepath(); + + if ($newfile = $zipper->archive_to_storage(array($file), $user_context->id, 'user', 'draft', $draftid, $parent_path, $filepath.'.zip', $USER->id)) { + $return = new stdclass; + $return->filepath = $parent_path; + echo json_encode($return); + } else { + echo json_encode(false); + } + die; + + case 'downloaddir': + $filepath = required_param('filepath', PARAM_PATH); + + $zipper = get_file_packer('application/zip'); + $fs = get_file_storage(); + $area = file_get_draft_area_info($draftid); + if ($area['filecount'] == 0) { + echo json_encode(false); + die; + } + + $stored_file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $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 = file_draftfile_url($newdraftitemid, '/', $filename); + $return->filepath = $parent_path; + echo json_encode($return); + } else { + echo json_encode(false); + } + die; + + case 'unzip': + $filename = required_param('filename', PARAM_FILE); + $filepath = required_param('filepath', PARAM_PATH); + + $zipper = get_file_packer('application/zip'); + + $fs = get_file_storage(); + + $file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, $filename); + + if ($newfile = $file->extract_to_storage($zipper, $user_context->id, 'user', 'draft', $draftid, $filepath, $USER->id)) { + $return = new stdclass; + $return->filepath = $filepath; + echo json_encode($return); + } else { + echo json_encode(false); + } + die; + + default: + // no/unknown action? + echo json_encode(false); + die; +} diff --git a/repository/dropbox/repository.class.php b/repository/dropbox/repository.class.php index 693d8e3c72410..b80fb2bf3908b 100755 --- a/repository/dropbox/repository.class.php +++ b/repository/dropbox/repository.class.php @@ -62,8 +62,7 @@ public function __construct($repositoryid, $context = SYSCONTEXTID, $options = a $this->logged = true; } - $this->callback = new moodle_url($CFG->wwwroot.'/repository/repository_ajax.php', array( - 'callback'=>'yes', + $this->callback = new moodle_url($CFG->wwwroot.'/repository/repository_callback.php', array( 'repo_id'=>$repositoryid )); diff --git a/repository/filepicker.js b/repository/filepicker.js index 332516b60497f..27224eec5b97c 100644 --- a/repository/filepicker.js +++ b/repository/filepicker.js @@ -99,7 +99,6 @@ M.core_filepicker.init = function(Y, options) { params['accepted_types']=this.options.accepted_types; params['sesskey']=M.cfg.sesskey; params['client_id'] = args.client_id; - params['filearea'] = this.options.filearea?this.options.filearea:'user_draft'; params['itemid'] = this.options.itemid?this.options.itemid:0; params['maxbytes'] = this.options.maxbytes?this.options.maxbytes:-1; if (args['params']) { diff --git a/repository/filepicker.php b/repository/filepicker.php index 70a2a251a4127..2b7cf2e78d7cc 100755 --- a/repository/filepicker.php +++ b/repository/filepicker.php @@ -32,6 +32,8 @@ /// Wait as long as it takes for this script to finish set_time_limit(0); +die('TODO: sorry, needs to be converted to use new component and security rules'); + require_login(); // disable blocks in this page @@ -49,7 +51,6 @@ $env = optional_param('env', 'filepicker', PARAM_ALPHA); // opened in file picker, file manager or html editor $filename = optional_param('filename', '', PARAM_FILE); $fileurl = optional_param('fileurl', '', PARAM_RAW); -$filearea = optional_param('filearea', 'user_draft', PARAM_TEXT); $thumbnail = optional_param('thumbnail', '', PARAM_RAW); $targetpath = optional_param('targetpath', '', PARAM_PATH); $repo_id = optional_param('repo_id', 0, PARAM_INT); // repository ID @@ -92,7 +93,7 @@ } } -$url = new moodle_url($CFG->httpswwwroot."/repository/filepicker.php", array('ctx_id' => $contextid, 'itemid' => $itemid, 'env' => $env, 'course'=>$courseid, 'filearea'=>$filearea)); +$url = new moodle_url($CFG->httpswwwroot."/repository/filepicker.php", array('ctx_id' => $contextid, 'itemid' => $itemid, 'env' => $env, 'course'=>$courseid)); $home_url = new moodle_url($url, array('action' => 'browse')); switch ($action) { @@ -106,7 +107,7 @@ case 'deletedraft': $contextid = $user_context->id; $fs = get_file_storage(); - if ($file = $fs->get_file($contextid, 'user_draft', $itemid, $draftpath, $filename)) { + if ($file = $fs->get_file($contextid, 'user', 'draft', $itemid, $draftpath, $filename)) { if ($file->is_directory()) { if ($file->get_parent_directory()) { $draftpath = $file->get_parent_directory()->get_filepath(); @@ -244,7 +245,8 @@ $record = new stdclass; $record->filepath = $draftpath; $record->filename = $filename; - $record->filearea = 'user_draft'; + $record->component = 'user'; + $record->filearea = 'draft'; $record->itemid = $itemid; $record->license = ''; $record->author = ''; @@ -261,7 +263,7 @@ $zipper = new zip_packer(); $fs = get_file_storage(); - $file = $fs->get_file($user_context->id, $filearea, $itemid, $draftpath, '.'); + $file = $fs->get_file($user_context->id, 'user', 'draft', $itemid, $draftpath, '.'); if ($file->get_parent_directory()) { $parent_path = $file->get_parent_directory()->get_filepath(); $filename = trim($draftpath, '/').'.zip'; @@ -334,14 +336,14 @@ $zipper = new zip_packer(); $fs = get_file_storage(); - $file = $fs->get_file($user_context->id, $filearea, $itemid, $draftpath, '.'); + $file = $fs->get_file($user_context->id, 'user', 'draft', $itemid, $draftpath, '.'); if (!$file->get_parent_directory()) { $parent_path = '/'; } else { $parent_path = $file->get_parent_directory()->get_filepath(); } - $newfile = $zipper->archive_to_storage(array($file), $user_context->id, $filearea, $itemid, $parent_path, $file->get_filepath().'.zip', $USER->id); + $newfile = $zipper->archive_to_storage(array($file), $user_context->id, 'user', 'draft', $itemid, $parent_path, $file->get_filepath().'.zip', $USER->id); $url->param('action', 'browse'); $url->param('draftpath', $parent_path); @@ -351,9 +353,9 @@ case 'unzip': $zipper = new zip_packer(); $fs = get_file_storage(); - $file = $fs->get_file($user_context->id, $filearea, $itemid, $draftpath, $filename); + $file = $fs->get_file($user_context->id, 'user', 'draft', $itemid, $draftpath, $filename); - if ($newfile = $file->extract_to_storage($zipper, $user_context->id, $filearea, $itemid, $draftpath, $USER->id)) { + if ($newfile = $file->extract_to_storage($zipper, $user_context->id, 'user', 'draft', $itemid, $draftpath, $USER->id)) { $str = get_string('unziped','repository'); } else { $str = get_string('cannotunzip', 'repository'); @@ -366,8 +368,8 @@ case 'movefile': if (!empty($targetpath)) { $fb = get_file_browser(); - $file = $fb->get_file_info($user_context, $filearea, $itemid, $draftpath, $filename); - $file->copy_to_storage($user_context->id, $filearea, $itemid, $targetpath, $filename); + $file = $fb->get_file_info($user_context, 'user', 'draft', $itemid, $draftpath, $filename); + $file->copy_to_storage($user_context->id, 'user', 'draft', $itemid, $targetpath, $filename); if ($file->delete()) { $url->param('action', 'browse'); $url->param('draftpath', $targetpath); @@ -381,7 +383,7 @@ $url->param('action', 'movefile'); $url->param('draftpath', $draftpath); $url->param('filename', $filename); - file_get_user_area_folders($itemid, '/', $data); + file_get_drafarea_folders($itemid, '/', $data); print_draft_area_tree($data, true, $url); echo $OUTPUT->footer(); break; @@ -400,7 +402,7 @@ case 'mkdir': $fs = get_file_storage(); - $fs->create_directory($user_context->id, $filearea, $itemid, file_correct_filepath(file_correct_filepath($draftpath).trim($newdirname, '/'))); + $fs->create_directory($user_context->id, 'user', 'draft', $itemid, file_correct_filepath(file_correct_filepath($draftpath).trim($newdirname, '/'))); $url->param('action', 'browse'); $url->param('draftpath', $draftpath); if (!empty($newdirname)) { @@ -413,7 +415,7 @@ case 'rename': $fs = get_file_storage(); - if ($file = $fs->get_file($user_context->id, $filearea, $itemid, $draftpath, $filename)) { + if ($file = $fs->get_file($user_context->id, 'user', 'draft', $itemid, $draftpath, $filename)) { if ($file->is_directory()) { if ($file->get_parent_directory()) { $draftpath = $file->get_parent_directory()->get_filepath(); @@ -422,12 +424,12 @@ } // use file storage to create new folder $newdir = $draftpath . trim($newfilename , '/') . '/'; - $fs->create_directory($user_context->id, $filearea, $itemid, $newdir); + $fs->create_directory($user_context->id, 'user', 'draft', $itemid, $newdir); } else { // use file browser to copy file $fb = get_file_browser(); - $file = $fb->get_file_info($user_context, $filearea, $itemid, $draftpath, $filename); - $file->copy_to_storage($user_context->id, $filearea, $itemid, $draftpath, $newfilename); + $file = $fb->get_file_info($user_context, 'user', 'draft', $itemid, $draftpath, $filename); + $file->copy_to_storage($user_context->id, 'user', 'draft', $itemid, $draftpath, $newfilename); } } $file->delete(); @@ -459,7 +461,7 @@ $params['returntypes'] = 2; $repos = repository::get_instances($params); $fs = get_file_storage(); - $files = $fs->get_directory_files($user_context->id, $filearea, $itemid, $draftpath, false); + $files = $fs->get_directory_files($user_context->id, 'user', 'draft', $itemid, $draftpath, false); echo $OUTPUT->header(); if ((!empty($files) or $draftpath != '/') and $env == 'filemanager') { @@ -501,7 +503,7 @@ if (!empty($files)) { echo '
      '; foreach ($files as $file) { - $drafturl = new moodle_url($CFG->httpswwwroot.'/draftfile.php/'.$user_context->id.'/'.$filearea.'/'.$itemid.'/'.$file->get_filename()); + $drafturl = new moodle_url($CFG->httpswwwroot.'/draftfile.php/'.$user_context->id.'/user/draft/'.$itemid.'/'.$file->get_filename()); if ($file->get_filename() != '.') { // a file $fileicon = $CFG->wwwroot.'/pix/'.(file_extension_icon($file->get_filename())); diff --git a/repository/flickr/repository.class.php b/repository/flickr/repository.class.php index e7bbcf64a99cd..3f333805c5c78 100755 --- a/repository/flickr/repository.class.php +++ b/repository/flickr/repository.class.php @@ -302,7 +302,7 @@ public function type_config_form($mform) { $mform->addElement('static', null, '', $callbackurl); } else { $instance = array_shift($instances); - $callbackurl = $CFG->wwwroot.'/repository/repository_ajax.php?callback=yes&repo_id='.$instance->id; + $callbackurl = $CFG->wwwroot.'/repository/repository_callback.php?repo_id='.$instance->id; $mform->addElement('static', 'callbackurl', '', get_string('callbackurltext', 'repository_flickr', $callbackurl)); } diff --git a/repository/googledocs/repository.class.php b/repository/googledocs/repository.class.php index 1dc8bd3f9f661..f21b572cd53a2 100644 --- a/repository/googledocs/repository.class.php +++ b/repository/googledocs/repository.class.php @@ -68,7 +68,7 @@ public function print_login($ajax = true){ $ret = array(); $popup_btn = new stdclass; $popup_btn->type = 'popup'; - $returnurl = $CFG->wwwroot.'/repository/repository_ajax.php?callback=yes&repo_id='.$this->id; + $returnurl = $CFG->wwwroot.'/repository/repository_callback.php?repo_id='.$this->id; $popup_btn->url = google_authsub::login_url($returnurl, google_docs::REALM); $ret['login'] = array($popup_btn); return $ret; diff --git a/repository/lib.php b/repository/lib.php index cbdcca3aef675..43f4b85272580 100644 --- a/repository/lib.php +++ b/repository/lib.php @@ -830,6 +830,8 @@ public static function move_to_filepool($thefile, $record) { $now = time(); $record->contextid = $context->id; + $record->component = 'user'; + $record->filearea = 'draft'; $record->timecreated = $now; $record->timemodified = $now; $record->userid = $USER->id; @@ -838,8 +840,7 @@ public static function move_to_filepool($thefile, $record) { $record->itemid = 0; } $fs = get_file_storage(); - $browser = get_file_browser(); - if ($existingfile = $fs->get_file($context->id, $record->filearea, $record->itemid, $record->filepath, $record->filename)) { + if ($existingfile = $fs->get_file($context->id, $record->component, $record->filearea, $record->itemid, $record->filepath, $record->filename)) { $existingfile->delete(); } if ($file = $fs->create_file_from_pathname($record, $thefile)) { @@ -847,78 +848,17 @@ public static function move_to_filepool($thefile, $record) { $delete = unlink($thefile); unset($CFG->repository_no_delete); } - $fileinfo = $browser->get_file_info($context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename()); - if(!empty($fileinfo)) { - return array( - 'url'=>$fileinfo->get_url(), - 'id'=>$file->get_itemid(), - 'file'=>$file->get_filename(), - 'icon' => $OUTPUT->pix_url(file_extension_icon($thefile, 32))->out() - ); - } else { - return null; - } + return array( + 'url'=>file_draftfile_url($file->get_itemid(), $file->get_filepath(), $file->get_filename()), + 'id'=>$file->get_itemid(), + 'file'=>$file->get_filename(), + 'icon' => $OUTPUT->pix_url(file_extension_icon($thefile, 32))->out(), + ); } else { return null; } } - /** - * Return the user files tree in a format to be returned by the function get_listing - * @global object $CFG - * @param string $search - * @return array - */ - public static function get_user_file_tree($search = ''){ - global $CFG; - $ret = array(); - $ret['nologin'] = true; - $ret['manage'] = $CFG->wwwroot .'/files/index.php'; // temporary - $browser = get_file_browser(); - $itemid = null; - $filename = null; - $filearea = null; - $path = '/'; - $ret['dynload'] = false; - - if ($fileinfo = $browser->get_file_info(get_system_context(), $filearea, $itemid, $path, $filename)) { - - $ret['path'] = array(); - $params = $fileinfo->get_params(); - $filearea = $params['filearea']; - $ret['path'][] = repository::encode_path($filearea, $path, $fileinfo->get_visible_name()); - if ($fileinfo->is_directory()) { - $level = $fileinfo->get_parent(); - while ($level) { - $params = $level->get_params(); - $ret['path'][] = repository::encode_path($params['filearea'], $params['filepath'], $level->get_visible_name()); - $level = $level->get_parent(); - } - } - $filecount = repository::build_tree($fileinfo, $search, $ret['dynload'], $ret['list']); - $ret['path'] = array_reverse($ret['path']); - } - - if (empty($ret['list'])) { - //exit(mnet_server_fault(9016, get_string('emptyfilelist', 'repository_local'))); - throw new Exception('emptyfilelist'); - } else { - return $ret; - } - - } - - /** - * Serialize file path - * @param string $filearea - * @param string $path - * @param string $visiblename - * @return array - */ - public static function encode_path($filearea, $path, $visiblename) { - return array('path'=>serialize(array($filearea, $path)), 'name'=>$visiblename); - } - /** * Builds a tree of files This function is * then called recursively. @@ -950,7 +890,7 @@ public static function build_tree($fileinfo, $search, $dynamicmode, &$list) { $level = $child->get_parent(); while ($level) { $params = $level->get_params(); - $path[] = repository::encode_path($params['filearea'], $params['filepath'], $level->get_visible_name()); + $path[] = array($params['filepath'], $level->get_visible_name()); $level = $level->get_parent(); } @@ -989,7 +929,7 @@ public static function build_tree($fileinfo, $search, $dynamicmode, &$list) { continue; } $params = $child->get_params(); - $source = serialize(array($params['contextid'], $params['filearea'], $params['itemid'], $params['filepath'], $params['filename'])); + $source = serialize(array($params['contextid'], $params['component'], $params['filearea'], $params['itemid'], $params['filepath'], $params['filename'])); $list[] = array( 'title' => $filename, 'size' => $filesize, diff --git a/repository/local/repository.class.php b/repository/local/repository.class.php index 9ec3a64d59602..68a31490721aa 100755 --- a/repository/local/repository.class.php +++ b/repository/local/repository.class.php @@ -75,6 +75,7 @@ public function get_listing($encodedpath = '') { $itemid = $params['itemid']; $filename = $params['filename']; $filearea = $params['filearea']; + $component = $params['component']; $filepath = $params['filepath']; $context = get_context_instance_by_id($params['contextid']); } @@ -82,6 +83,7 @@ public function get_listing($encodedpath = '') { $itemid = null; $filename = null; $filearea = null; + $component = null; $filepath = null; $context = get_system_context(); } @@ -89,7 +91,7 @@ public function get_listing($encodedpath = '') { try { $browser = get_file_browser(); - if ($fileinfo = $browser->get_file_info($context, $filearea, $itemid, $filepath, $filename)) { + if ($fileinfo = $browser->get_file_info($context, $component, $filearea, $itemid, $filepath, $filename)) { // build path navigation $pathnodes = array(); $encodedpath = base64_encode(serialize($fileinfo->get_params())); @@ -117,7 +119,7 @@ public function get_listing($encodedpath = '') { $encodedpath = base64_encode(serialize($params)); // hide user_private area from local plugin, user should // use private file plugin to access private files - if ($params['filearea'] == 'user_private') { + if ($params['component'] = 'user' and $params['filearea'] == 'private') { continue; } $node = array( @@ -182,7 +184,7 @@ public function supported_returntypes() { * @param string $new_filepath the new path in draft area * @return array The information of file */ - public function copy_to_area($encoded, $new_filearea='user_draft', $new_itemid = '', $new_filepath = '/', $new_filename = '') { + public function copy_to_area($encoded, $new_filearea='ignored', $new_itemid = '', $new_filepath = '/', $new_filename = '') { global $USER, $DB; $info = array(); @@ -191,14 +193,15 @@ public function copy_to_area($encoded, $new_filearea='user_draft', $new_itemid = $user_context = get_context_instance(CONTEXT_USER, $USER->id); // the final file $contextid = $params['contextid']; + $component = $params['component']; $filearea = $params['filearea']; $filepath = $params['filepath']; $filename = $params['filename']; $fileitemid = $params['itemid']; $context = get_context_instance_by_id($contextid); try { - $file_info = $browser->get_file_info($context, $filearea, $fileitemid, $filepath, $filename); - $file_info->copy_to_storage($user_context->id, $new_filearea, $new_itemid, $new_filepath, $new_filename); + $file_info = $browser->get_file_info($context, $component, $filearea, $fileitemid, $filepath, $filename); + $file_info->copy_to_storage($user_context->id, 'user', 'draft', $new_itemid, $new_filepath, $new_filename); } catch (Exception $e) { throw $e; } diff --git a/repository/picasa/repository.class.php b/repository/picasa/repository.class.php index 8cdf4739f77c5..3b37d5867271c 100644 --- a/repository/picasa/repository.class.php +++ b/repository/picasa/repository.class.php @@ -65,7 +65,7 @@ public function check_login() { public function print_login(){ global $CFG; - $returnurl = $CFG->wwwroot.'/repository/repository_ajax.php?callback=yes&repo_id='.$this->id; + $returnurl = $CFG->wwwroot.'/repository/repository_callback.php?repo_id='.$this->id; $authurl = google_authsub::login_url($returnurl, google_picasa::REALM); if($this->options['ajax']){ $ret = array(); diff --git a/repository/recent/repository.class.php b/repository/recent/repository.class.php index e617b816dc86b..4099c9f728a72 100755 --- a/repository/recent/repository.class.php +++ b/repository/recent/repository.class.php @@ -65,20 +65,23 @@ public function search($search_text) { private function get_recent_files($limitfrom = 0, $limit = DEFAULT_RECENT_FILES_NUM) { global $USER, $DB; - // TODO: should exclude user_draft area files? + + // TODO: this is not really secure, we should validate the result with file_browser (skodak) + $sql = 'SELECT * FROM {files} files1 JOIN (SELECT contenthash, filename, MAX(id) AS id FROM {files} - WHERE userid = ? AND filename != ? AND filearea != ? + WHERE userid = :userid AND filename != :filename AND filearea != :filearea GROUP BY contenthash, filename) files2 ON files1.id = files2.id ORDER BY files1.timemodified DESC'; - $params = array('userid'=>$USER->id, 'filename'=>'.', 'filearea'=>'user_draft'); + $params = array('userid'=>$USER->id, 'filename'=>'.', 'filearea'=>'draft'); $rs = $DB->get_recordset_sql($sql, $params, $limitfrom, $limit); $result = array(); foreach ($rs as $file_record) { $info = array(); $info['contextid'] = $file_record->contextid; $info['itemid'] = $file_record->itemid; + $info['component'] = $file_record->component; $info['filearea'] = $file_record->filearea; $info['filepath'] = $file_record->filepath; $info['filename'] = $file_record->filename; @@ -162,13 +165,13 @@ public function supported_returntypes() { * * @global object $USER * @global object $DB - * @param string $encoded The information of file, it is base64 encoded php seriablized data + * @param string $encoded The information of file, it is base64 encoded php serialized data * @param string $new_filename The intended name of file * @param string $new_itemid itemid * @param string $new_filepath the new path in draft area * @return array The information of file */ - public function copy_to_area($encoded, $new_filearea='user_draft', $new_itemid = '', $new_filepath = '/', $new_filename = '') { + public function copy_to_area($encoded, $new_filearea='ignored', $new_itemid = '', $new_filepath = '/', $new_filename = '') { global $USER, $DB; $info = array(); $fs = get_file_storage(); @@ -176,7 +179,10 @@ public function copy_to_area($encoded, $new_filearea='user_draft', $new_itemid = $params = unserialize(base64_decode($encoded)); $user_context = get_context_instance(CONTEXT_USER, $USER->id); + //TODO: this is really HORRIBLE!!! Where is any security check??????? (skodak) + $contextid = $params['contextid']; + $component = $params['component']; $filearea = $params['filearea']; $filepath = $params['filepath']; $filename = $params['filename']; @@ -185,14 +191,17 @@ public function copy_to_area($encoded, $new_filearea='user_draft', $new_itemid = // XXX: // When user try to pick a file from other filearea, normally file api will use file browse to // operate the files with capability check, but in some areas, users don't have permission to - // browse the files (for example, forum_attachment area). + // browse the files (for example, forum attachment area). // // To get 'recent' plugin working, we need to use lower level file_stoarge class to bypass the // capability check, we will use a better workaround to improve it. - if ($stored_file = $fs->get_file($contextid, $filearea, $fileitemid, $filepath, $filename)) { - $file_record = array('contextid'=>$user_context->id, 'filearea'=>$new_filearea, + // + // TODO: no this is a BIG security hole, we should really use file_browser here and instead filter the available files (skodak) + // + if ($stored_file = $fs->get_file($contextid, $component, $filearea, $fileitemid, $filepath, $filename)) { + $file_record = array('contextid'=>$user_context->id, 'component'=>'user', 'filearea'=>'draft', 'itemid'=>$new_itemid, 'filepath'=>$new_filepath, 'filename'=>$new_filename); - if ($file = $fs->get_file($user_context->id, $new_filearea, $new_itemid, $new_filepath, $new_filename)) { + if ($file = $fs->get_file($user_context->id, 'user' ,'draft', $new_itemid, $new_filepath, $new_filename)) { $file->delete(); } $fs->create_file_from_storedfile($file_record, $stored_file); diff --git a/repository/repository_ajax.php b/repository/repository_ajax.php index 34d7358bfe7e9..7c5de1d7a58ab 100755 --- a/repository/repository_ajax.php +++ b/repository/repository_ajax.php @@ -35,7 +35,6 @@ /// Parameters $action = optional_param('action', '', PARAM_ALPHA); $repo_id = optional_param('repo_id', 0, PARAM_INT); // Pepository ID -$callback = optional_param('callback', '', PARAM_CLEANHTML); // Is this a callback from external site? $client_id = optional_param('client_id', '', PARAM_RAW); // Client ID $contextid = optional_param('ctx_id', SYSCONTEXTID, PARAM_INT); // Context ID $env = optional_param('env', 'filepicker', PARAM_ALPHA); // Opened in editor or moodleform @@ -46,7 +45,6 @@ $page = optional_param('page', '', PARAM_RAW); // Page $maxbytes = optional_param('maxbytes', 0, PARAM_INT); // Maxbytes $req_path = optional_param('p', '', PARAM_RAW); // Path -$saveas_filearea = optional_param('filearea', 'user_draft', PARAM_TEXT); $saveas_filename = optional_param('title', '', PARAM_FILE); // save as file name $saveas_path = optional_param('savepath', '/', PARAM_PATH); // save as file path $search_text = optional_param('s', '', PARAM_CLEANHTML); @@ -140,41 +138,6 @@ die(json_encode($err)); } - -if (!empty($callback)) { - // post callback - $repo->callback(); - // call opener window to refresh repository - // the callback url should be something like this: - // http://xx.moodle.com/repository/repository_ajax.php?callback=yes&repo_id=1&sid=xxx - // sid is the attached auth token from external source - // If Moodle is working on HTTPS mode, then we are not allowed to access - // parent window, in this case, we need to alert user to refresh the repository - // manually. - $strhttpsbug = get_string('cannotaccessparentwin', 'repository'); - $strrefreshnonjs = get_string('refreshnonjsfilepicker', 'repository'); - $js =<< - - - - - - - -EOD; - die($js); -} - /// These actions all occur on the currently active repository instance switch ($action) { case 'sign': @@ -235,7 +198,7 @@ // so we don't check user quota and maxbytes here if (in_array($repo->options['type'], array('local', 'recent', 'user'))) { try { - $fileinfo = $repo->copy_to_area($source, $saveas_filearea, $itemid, $saveas_path, $saveas_filename); + $fileinfo = $repo->copy_to_area($source, 'draft', $itemid, $saveas_path, $saveas_filename); } catch (Exception $e) { throw $e; } @@ -296,7 +259,8 @@ $record = new stdclass; $record->filepath = $saveas_path; $record->filename = $saveas_filename; - $record->filearea = $saveas_filearea; + $record->component = 'user'; + $record->filearea = 'draft'; $record->itemid = $itemid; if (!empty($file['license'])) { diff --git a/repository/repository_callback.php b/repository/repository_callback.php new file mode 100755 index 0000000000000..f24116e6b7868 --- /dev/null +++ b/repository/repository_callback.php @@ -0,0 +1,101 @@ +. + + +/** + * The Web service script that is called from the filepicker front end + * + * @since 2.0 + * @package moodlecore + * @subpackage repository + * @copyright 2009 Dongsheng Cai + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once(dirname(dirname(__FILE__)).'/config.php'); +require_once(dirname(dirname(__FILE__)).'/lib/filelib.php'); +require_once(dirname(__FILE__).'/lib.php'); + +require_login(); + +/// Parameters + +$repo_id = required_param('repo_id', PARAM_INT); // Repository ID + +$client_id = optional_param('client_id', '', PARAM_RAW); // Client ID +$contextid = optional_param('ctx_id', SYSCONTEXTID, PARAM_INT); // Context ID + +/// Headers to make it not cacheable +header('Cache-Control: no-cache, must-revalidate'); +header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); + +/// Check permissions +if (repository::check_context($contextid)) { //TODO: this is weird (skodak) + print_error('nopermissiontoaccess', 'repository'); +} + +/// Wait as long as it takes for this script to finish +set_time_limit(0); + +/// Get repository instance information +$sql = 'SELECT i.name, i.typeid, r.type FROM {repository} r, {repository_instances} i '. + 'WHERE i.id=? AND i.typeid=r.id'; + +$repository = $DB->get_record_sql($sql, array($repo_id), '*', MUST_EXIST); + +$type = $repository->type; + +if (file_exists($CFG->dirroot.'/repository/'.$type.'/repository.class.php')) { + require_once($CFG->dirroot.'/repository/'.$type.'/repository.class.php'); + $classname = 'repository_' . $type; + $repo = new $classname($repo_id, $contextid, array('ajax'=>true, 'name'=>$repository->name, 'type'=>$type, 'client_id'=>$client_id)); //TODO: this is very weird constructor! (skodak) +} else { + print_error('invalidplugin', 'repository', $type); +} + +// post callback +$repo->callback(); +// call opener window to refresh repository +// the callback url should be something like this: +// http://xx.moodle.com/repository/repository_callback.php?repo_id=1&sid=xxx +// sid is the attached auth token from external source +// If Moodle is working on HTTPS mode, then we are not allowed to access +// parent window, in this case, we need to alert user to refresh the repository +// manually. +$strhttpsbug = get_string('cannotaccessparentwin', 'repository'); +$strrefreshnonjs = get_string('refreshnonjsfilepicker', 'repository'); +$js =<< + + + + + + + +EOD; + +die($js); diff --git a/repository/upload/repository.class.php b/repository/upload/repository.class.php index 570ec06fb002b..a3ddfda40cc99 100755 --- a/repository/upload/repository.class.php +++ b/repository/upload/repository.class.php @@ -41,7 +41,6 @@ public function __construct($repositoryid, $context = SYSCONTEXTID, $options = a $this->itemid = optional_param('itemid', '', PARAM_INT); $this->license = optional_param('license', $CFG->sitedefaultlicense, PARAM_TEXT); $this->author = optional_param('author', '', PARAM_TEXT); - $this->filearea = optional_param('filearea', 'user_draft', PARAM_TEXT); $this->filepath = urldecode(optional_param('savepath', '/', PARAM_PATH)); } @@ -62,7 +61,8 @@ public function print_login() { public function upload() { try { $record = new stdclass; - $record->filearea = $this->filearea;; + $record->filearea = 'draft';; + $record->component = 'user';; $record->filepath = $this->filepath; $record->itemid = $this->itemid; $record->license = $this->license; @@ -110,17 +110,15 @@ public function supported_returntypes() { /** * Upload file to local filesystem pool * @param string $elname name of element - * @param string $filearea - * @param string $filepath - * @param string $filename - use specified filename, if not specified name of uploaded file used + * @param object $record * @param bool $override override file if exists * @return mixed stored_file object or false if error; may throw exception if duplicate found */ public function upload_to_filepool($elname, $record, $override = true) { global $USER, $CFG; $context = get_context_instance(CONTEXT_USER, $USER->id); + $fs = get_file_storage(); - $browser = get_file_browser(); if ($record->filepath !== '/') { $record->filepath = trim($record->filepath, '/'); @@ -139,16 +137,11 @@ public function upload_to_filepool($elname, $record, $override = true) { $record->filename = $_FILES[$elname]['name']; } - $userquota = file_get_user_used_space(); - if (filesize($_FILES[$elname]['tmp_name'])+$userquota>=(int)$CFG->userquota) { - throw new file_exception('userquotalimit'); - } - if (empty($record->itemid)) { $record->itemid = 0; } - if ($file = $fs->get_file($context->id, $record->filearea, $record->itemid, $record->filepath, $record->filename)) { + if ($file = $fs->get_file($context->id, 'user', 'draft', $record->itemid, $record->filepath, $record->filename)) { if ($override) { $file->delete(); } else { @@ -157,19 +150,21 @@ public function upload_to_filepool($elname, $record, $override = true) { } $record->contextid = $context->id; + $record->component = 'user'; + $record->filearea = 'draft'; $record->userid = $USER->id; $record->source = ''; try { $file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']); } catch (Exception $e) { + //TODO: ??? (skodak) $e->obj = $_FILES[$elname]; throw $e; } - $info = $browser->get_file_info($context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename()); return array( - 'url'=>$info->get_url(), + 'url'=>file_draftfile_url($file->get_itemid(), $file->get_filepath(), $file->get_filename()), 'id'=>$record->itemid, 'file'=>$file->get_filename() ); diff --git a/repository/user/repository.class.php b/repository/user/repository.class.php index e3eabc1c237fb..8759505343e2b 100755 --- a/repository/user/repository.class.php +++ b/repository/user/repository.class.php @@ -69,19 +69,23 @@ public function get_listing($encodedpath = '') { $ret['nologin'] = true; $list = array(); + //TODO: this is weird, why not only user context? (skodak) + if (!empty($encodedpath)) { $params = unserialize(base64_decode($encodedpath)); if (is_array($params)) { $itemid = $params['itemid']; $filename = $params['filename']; $filearea = $params['filearea']; + $component = $params['component']; $filepath = $params['filepath']; $context = get_context_instance_by_id($params['contextid']); } } else { $itemid = 0; $filename = null; - $filearea = 'user_private'; + $component = 'user'; + $filearea = 'private'; $filepath = '/'; $context = get_context_instance(CONTEXT_USER, $USER->id); } @@ -89,11 +93,11 @@ public function get_listing($encodedpath = '') { try { $browser = get_file_browser(); - if ($fileinfo = $browser->get_file_info($context, $filearea, $itemid, $filepath, $filename)) { + if ($fileinfo = $browser->get_file_info($context, $component, $filearea, $itemid, $filepath, $filename)) { $pathnodes = array(); $level = $fileinfo; $params = $fileinfo->get_params(); - while ($level && $params['filearea'] == 'user_private') { + while ($level && $params['filearea'] == 'private' && $params['component'] == 'user') { $encodedpath = base64_encode(serialize($level->get_params())); $pathnodes[] = array('name'=>$level->get_visible_name(), 'path'=>$encodedpath); $level = $level->get_parent(); @@ -166,7 +170,7 @@ public function supported_returntypes() { * @param string $new_filepath the new path in draft area * @return array The information of file */ - public function copy_to_area($encoded, $new_filearea='user_draft', $new_itemid = '', $new_filepath = '/', $new_filename = '') { + public function copy_to_area($encoded, $new_filearea='ignored', $new_itemid = '', $new_filepath = '/', $new_filename = '') { global $USER, $DB; $info = array(); @@ -175,14 +179,15 @@ public function copy_to_area($encoded, $new_filearea='user_draft', $new_itemid = $user_context = get_context_instance(CONTEXT_USER, $USER->id); // the final file $contextid = $params['contextid']; + $component = $params['component']; $filearea = $params['filearea']; $filepath = $params['filepath']; $filename = $params['filename']; $fileitemid = $params['itemid']; $context = get_context_instance_by_id($contextid); try { - $file_info = $browser->get_file_info($context, $filearea, $fileitemid, $filepath, $filename); - $file_info->copy_to_storage($user_context->id, $new_filearea, $new_itemid, $new_filepath, $new_filename); + $file_info = $browser->get_file_info($context, $component, $filearea, $fileitemid, $filepath, $filename); + $file_info->copy_to_storage($user_context->id, 'user', 'draft', $new_itemid, $new_filepath, $new_filename); } catch (Exception $e) { throw $e; } diff --git a/tag/edit.php b/tag/edit.php index f4693a723f1a4..5fda77b7b99af 100644 --- a/tag/edit.php +++ b/tag/edit.php @@ -54,7 +54,7 @@ $errorstring = ''; $editoroptions = array('maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$CFG->maxbytes, 'trusttext'=>false); -$tag = file_prepare_standard_editor($tag, 'description', $editoroptions, $systemcontext, 'tag_description', $tag->id); +$tag = file_prepare_standard_editor($tag, 'description', $editoroptions, $systemcontext, 'tag', 'description', $tag->id); $tagform = new tag_edit_form(null, compact('editoroptions')); if ( $tag->tagtype == 'official' ) { @@ -93,7 +93,7 @@ if (empty($errorstring)) { // All is OK, let's save it - $tagnew = file_postupdate_standard_editor($tagnew, 'description', $editoroptions, $systemcontext, 'tag_description', $tag->id); + $tagnew = file_postupdate_standard_editor($tagnew, 'description', $editoroptions, $systemcontext, 'tag', 'description', $tag->id); tag_description_set($tag_id, $tagnew->description, $tagnew->descriptionformat); diff --git a/tag/lib.php b/tag/lib.php index 9f82ea2fc0b39..3eef874146be7 100644 --- a/tag/lib.php +++ b/tag/lib.php @@ -532,7 +532,7 @@ function tag_delete($tagids) { $success &= (bool) $DB->delete_records('tag', array('id'=>$tagid)); // Delete all files associated with this tag $fs = get_file_storage(); - $files = $fs->get_area_files($context->id, 'tag_description', $tagid); + $files = $fs->get_area_files($context->id, 'tag', 'description', $tagid); foreach ($files as $file) { $file->delete(); } diff --git a/tag/locallib.php b/tag/locallib.php index c574c6ede5b95..0bc2a6dc1ea76 100644 --- a/tag/locallib.php +++ b/tag/locallib.php @@ -115,7 +115,7 @@ function tag_print_description_box($tag_object, $return=false) { if (!empty($tag_object->description)) { $options = new object(); $options->para = false; - $tag_object->description = file_rewrite_pluginfile_urls($tag_object->description, 'pluginfile.php', get_context_instance(CONTEXT_SYSTEM)->id, 'tag_description', $tag_object->id); + $tag_object->description = file_rewrite_pluginfile_urls($tag_object->description, 'pluginfile.php', get_context_instance(CONTEXT_SYSTEM)->id, 'tag', 'description', $tag_object->id); $output .= format_text($tag_object->description, $tag_object->descriptionformat, $options); } diff --git a/user/edit.php b/user/edit.php index 0d700116877d1..52caaf862f5ca 100644 --- a/user/edit.php +++ b/user/edit.php @@ -135,7 +135,7 @@ // Prepare the editor and create form $editoroptions = array('maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$CFG->maxbytes, 'trusttext'=>false, 'forcehttps'=>false); -$user = file_prepare_standard_editor($user, 'description', $editoroptions, $personalcontext, 'user_profile', $user->id); +$user = file_prepare_standard_editor($user, 'description', $editoroptions, $personalcontext, 'user', 'profile', 0); $userform = new user_edit_form(null, array('editoroptions'=>$editoroptions)); if (empty($user->country)) { // MDL-16308 - we must unset the value here so $CFG->country can be used as default one @@ -172,7 +172,7 @@ // description editor element may not exist! if (isset($usernew->description_editor)) { - $usernew = file_postupdate_standard_editor($usernew, 'description', $editoroptions, $personalcontext, 'user_profile', $usernew->id); + $usernew = file_postupdate_standard_editor($usernew, 'description', $editoroptions, $personalcontext, 'user', 'profile', 0); } $DB->update_record('user', $usernew); diff --git a/user/editadvanced.php b/user/editadvanced.php index ddaf94c5819b4..f5eea71d42213 100644 --- a/user/editadvanced.php +++ b/user/editadvanced.php @@ -110,7 +110,7 @@ if ($user->id !== -1) { $usercontext = get_context_instance(CONTEXT_USER, $user->id); $editoroptions = array('maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$CFG->maxbytes, 'trusttext'=>false, 'forcehttps'=>false); - $user = file_prepare_standard_editor($user, 'description', $editoroptions, $usercontext, 'user_profile', $user->id); + $user = file_prepare_standard_editor($user, 'description', $editoroptions, $usercontext, 'user', 'profile', 0); } else { $usercontext = null; // This is a new user, we don't want to add files here @@ -137,7 +137,7 @@ if ($usernew->id == -1) { //TODO check out if it makes sense to create account with this auth plugin and what to do with the password unset($usernew->id); - $usernew = file_postupdate_standard_editor($usernew, 'description', $editoroptions, null, 'user_profile', null); + $usernew = file_postupdate_standard_editor($usernew, 'description', $editoroptions, null, 'user', 'profile', null); $usernew->mnethostid = $CFG->mnet_localhost_id; // always local user $usernew->confirmed = 1; $usernew->timecreated = time(); @@ -146,7 +146,7 @@ $usercreated = true; } else { - $usernew = file_postupdate_standard_editor($usernew, 'description', $editoroptions, $usercontext, 'user_profile', $usernew->id); + $usernew = file_postupdate_standard_editor($usernew, 'description', $editoroptions, $usercontext, 'user', 'profile', 0); $DB->update_record('user', $usernew); // pass a true $userold here if (! $authplugin->user_update($user, $userform->get_data())) { diff --git a/user/index.php b/user/index.php index 1c08d737b266d..50999cdc95b94 100644 --- a/user/index.php +++ b/user/index.php @@ -302,7 +302,7 @@ $contentheading .= ' ' . $OUTPUT->action_icon($aurl, new pix_icon('t/edit', get_string('editgroupprofile'))); } - $group->description = file_rewrite_pluginfile_urls($group->description, 'pluginfile.php', $context->id, 'course_group_description', $group->id); + $group->description = file_rewrite_pluginfile_urls($group->description, 'pluginfile.php', $context->id, 'group', 'description', $group->id); if (!isset($group->descriptionformat)) { $group->descriptionformat = FORMAT_MOODLE; } diff --git a/user/profile.php b/user/profile.php index bd158289ecd84..584f9cab67ae4 100644 --- a/user/profile.php +++ b/user/profile.php @@ -209,7 +209,7 @@ if (!empty($CFG->profilesforenrolledusersonly) && !$currentuser && !$DB->record_exists('role_assignments', array('userid'=>$user->id))) { echo get_string('profilenotshown', 'moodle'); } else { - $user->description = file_rewrite_pluginfile_urls($user->description, 'pluginfile.php', $usercontext->id, 'user_profile', $user->id); + $user->description = file_rewrite_pluginfile_urls($user->description, 'pluginfile.php', $usercontext->id, 'user', 'profile', null); echo format_text($user->description, $user->descriptionformat); } } diff --git a/user/view.php b/user/view.php index 2d09615867d10..9f5076d288a60 100644 --- a/user/view.php +++ b/user/view.php @@ -214,7 +214,12 @@ if (!empty($CFG->profilesforenrolledusersonly) && !$DB->record_exists('role_assignments', array('userid'=>$id))) { echo get_string('profilenotshown', 'moodle'); } else { - $user->description = file_rewrite_pluginfile_urls($user->description, 'pluginfile.php', $usercontext->id, 'user_profile', $id); + if ($courseid == SITEID) { + $user->description = file_rewrite_pluginfile_urls($user->description, 'pluginfile.php', $usercontext->id, 'user', 'profile', null); + } else { + // we have to make a little detour thought the course context to verify the access control for course profile + $user->description = file_rewrite_pluginfile_urls($user->description, 'pluginfile.php', $coursecontext->id, 'user', 'profile', $user->id); + } echo format_text($user->description, $user->descriptionformat); } } diff --git a/userfile.php b/userfile.php deleted file mode 100644 index ee11ca26c12cc..0000000000000 --- a/userfile.php +++ /dev/null @@ -1,123 +0,0 @@ -. - -/** - * This script serves user's private files - * - * @package moodlecore - * @subpackage file - * @copyright 2008 Petr Skoda (http://skodak.org) - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -// disable moodle specific debug messages and any errors in output -define('NO_DEBUG_DISPLAY', true); - -require_once('config.php'); -require_once('lib/filelib.php'); - - -$relativepath = get_file_argument(); -$forcedownload = optional_param('forcedownload', 0, PARAM_BOOL); - -// relative path must start with '/' -if (!$relativepath) { - print_error('invalidargorconf'); -} else if ($relativepath{0} != '/') { - print_error('pathdoesnotstartslash'); -} - -// extract relative path components -$args = explode('/', ltrim($relativepath, '/')); - -if (count($args) == 0) { // always at least user id - print_error('invalidarguments'); -} - -$contextid = (int)array_shift($args); -$filearea = array_shift($args); - -$context = get_context_instance_by_id($contextid); -if ($context->contextlevel != CONTEXT_USER) { - print_error('invalidarguments'); -} - -$userid = $context->instanceid; - -switch ($filearea) { - case 'user_profile': - require_login(); - if (isguestuser()) { - print_error('noguest'); - } - - // access controll here must match user edit forms - if ($userid == $USER->id) { - if (!has_capability('moodle/user:editownprofile', get_context_instance(CONTEXT_SYSTEM))) { - send_file_not_found(); - } - } else { - if (!has_capability('moodle/user:editprofile', $context) and !has_capability('moodle/user:update', $context)) { - send_file_not_found(); - } - } - $itemid = 0; - $forcedownload = true; - break; - - case 'user_private': - require_login(); - if (isguestuser()) { - send_file_not_found(); - } - if ($USER->id != $userid) { - send_file_not_found(); - } - $itemid = 0; - $forcedownload = true; - break; - case 'user_backup': - require_login(); - if (isguestuser()) { - send_file_not_found(); - } - if ($USER->id != $userid) { - send_file_not_found(); - } - $itemid = 0; - $forcedownload = true; - break; - - default: - send_file_not_found(); -} - -$relativepath = '/'.implode('/', $args); - -$fs = get_file_storage(); - -$fullpath = $context->id.$filearea.$itemid.$relativepath; - -if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->get_filename() == '.') { - send_file_not_found(); -} - -// ======================================== -// finally send the file -// ======================================== -session_get_instance()->write_close(); // unlock session during fileserving -send_stored_file($file, 0, false, $forcedownload); diff --git a/version.php b/version.php index a05667a64e765..dbfb7393f40ff 100644 --- a/version.php +++ b/version.php @@ -6,7 +6,7 @@ // This is compared against the values stored in the database to determine // whether upgrades should be performed (see lib/db/*.php) - $version = 2010063000; // YYYYMMDD = date of the last version bump + $version = 2010070300; // YYYYMMDD = date of the last version bump // XX = daily increments $release = '2.0 Preview 4 (Build: 20100703)'; // Human-friendly version name