weekly release 2.6.11+
[moodle.git] / lib / filebrowser / file_browser.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * Utility class for browsing of files.
20  *
21  * @package   core_files
22  * @copyright 2008 Petr Skoda (http://skodak.org)
23  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 defined('MOODLE_INTERNAL') || die();
28 require_once("$CFG->libdir/filebrowser/file_info.php");
30 // general area types
31 require_once("$CFG->libdir/filebrowser/file_info_stored.php");
32 require_once("$CFG->libdir/filebrowser/virtual_root_file.php");
34 // description of available areas in each context level
35 require_once("$CFG->libdir/filebrowser/file_info_context_system.php");
36 require_once("$CFG->libdir/filebrowser/file_info_context_user.php");
37 require_once("$CFG->libdir/filebrowser/file_info_context_coursecat.php");
38 require_once("$CFG->libdir/filebrowser/file_info_context_course.php");
39 require_once("$CFG->libdir/filebrowser/file_info_context_module.php");
41 /**
42  * This class provides the main entry point for other code wishing to get information about files.
43  *
44  * The whole file storage for a Moodle site can be seen as a huge virtual tree.
45  * The spine of the tree is the tree of contexts (system, course-categories,
46  * courses, modules, also users). Then, within each context, there may be any number of
47  * file areas, and a file area contains folders and files. The various file_info
48  * subclasses return info about the things in this tree. They should be obtained
49  * from an instance of this class.
50  *
51  * This virtual tree is different for each user depending of his/her current permissions.
52  * Some branches such as draft areas are hidden, but accessible.
53  *
54  * Always use this abstraction when you need to access module files from core code.
55   *
56  * @package   core_files
57  * @category  files
58  * @copyright 2008 Petr Skoda (http://skodak.org)
59  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
60 */
61 class file_browser {
63     /**
64      * Looks up file_info instance
65      *
66      * @param stdClass $context context object
67      * @param string $component component
68      * @param string $filearea file area
69      * @param int $itemid item ID
70      * @param string $filepath file path
71      * @param string $filename file name
72      * @return file_info|null file_info instance or null if not found or access not allowed
73      */
74     public function get_file_info($context = NULL, $component = NULL, $filearea = NULL, $itemid = NULL, $filepath = NULL, $filename = NULL) {
75         if (!$context) {
76             $context = context_system::instance();
77         }
78         switch ($context->contextlevel) {
79             case CONTEXT_SYSTEM:
80                 return $this->get_file_info_context_system($context, $component, $filearea, $itemid, $filepath, $filename);
81             case CONTEXT_USER:
82                 return $this->get_file_info_context_user($context, $component, $filearea, $itemid, $filepath, $filename);
83             case CONTEXT_COURSECAT:
84                 return $this->get_file_info_context_coursecat($context, $component, $filearea, $itemid, $filepath, $filename);
85             case CONTEXT_COURSE:
86                 return $this->get_file_info_context_course($context, $component, $filearea, $itemid, $filepath, $filename);
87             case CONTEXT_MODULE:
88                 return $this->get_file_info_context_module($context, $component, $filearea, $itemid, $filepath, $filename);
89         }
91         return null;
92     }
94     /**
95      * Returns info about the files at System context
96      * @todo MDL-33372 - Provide a way of displaying recent files for blog entries.
97      *
98      * @param object $context context object
99      * @param string $component component
100      * @param string $filearea file area
101      * @param int $itemid item ID
102      * @param string $filepath file path
103      * @param string $filename file name
104      * @return file_info instance or null if not found or access not allowed
105      */
106     private function get_file_info_context_system($context, $component, $filearea, $itemid, $filepath, $filename) {
107         $level = new file_info_context_system($this, $context);
108         return $level->get_file_info($component, $filearea, $itemid, $filepath, $filename);
109         // nothing supported at this context yet
110     }
112     /**
113      * Returns info about the files at User context
114      *
115      * @param stdClass $context context object
116      * @param string $component component
117      * @param string $filearea file area
118      * @param int $itemid item ID
119      * @param string $filepath file path
120      * @param string $filename file name
121      * @return file_info|null file_info instance or null if not found or access not allowed
122      */
123     private function get_file_info_context_user($context, $component, $filearea, $itemid, $filepath, $filename) {
124         global $DB, $USER;
125         if ($context->instanceid == $USER->id) {
126             $user = $USER;
127         } else {
128             $user = $DB->get_record('user', array('id'=>$context->instanceid));
129         }
131         if (isguestuser($user)) {
132             // guests do not have any files
133             return null;
134         }
136         if ($user->deleted) {
137             return null;
138         }
140         $level = new file_info_context_user($this, $context, $user);
141         return $level->get_file_info($component, $filearea, $itemid, $filepath, $filename);
142     }
144     /**
145      * Returns info about the files at Course category context
146      *
147      * @param stdClass $context context object
148      * @param string $component component
149      * @param string $filearea file area
150      * @param int $itemid item ID
151      * @param string $filepath file path
152      * @param string $filename file name
153      * @return file_info|null file_info instance or null if not found or access not allowed
154      */
155     private function get_file_info_context_coursecat($context, $component, $filearea, $itemid, $filepath, $filename) {
156         global $DB;
158         if (!$category = $DB->get_record('course_categories', array('id'=>$context->instanceid))) {
159             return null;
160         }
162         $level = new file_info_context_coursecat($this, $context, $category);
163         return $level->get_file_info($component, $filearea, $itemid, $filepath, $filename);
164     }
166     /**
167      * Returns info about the files at Course category context
168      *
169      * @param stdClass $context context object
170      * @param string $component component
171      * @param string $filearea file area
172      * @param int $itemid item ID
173      * @param string $filepath file path
174      * @param string $filename file name
175      * @return file_info|null file_info instance or null if not found or access not allowed
176      */
177     private function get_file_info_context_course($context, $component, $filearea, $itemid, $filepath, $filename) {
178         global $DB, $COURSE;
180         if ($context->instanceid == $COURSE->id) {
181             $course = $COURSE;
182         } else if (!$course = $DB->get_record('course', array('id'=>$context->instanceid))) {
183             return null;
184         }
186         $level = new file_info_context_course($this, $context, $course);
187         return $level->get_file_info($component, $filearea, $itemid, $filepath, $filename);
188     }
190     /**
191      * Returns info about the files at Course category context
192      *
193      * @param stdClass $context context object
194      * @param string $component component
195      * @param string $filearea file area
196      * @param int $itemid item ID
197      * @param string $filepath file path
198      * @param string $filename file name
199      * @return file_info|null file_info instance or null if not found or access not allowed
200      */
201     private function get_file_info_context_module($context, $component, $filearea, $itemid, $filepath, $filename) {
202         global $COURSE, $DB, $CFG;
204         static $cachedmodules = array();
206         if (!array_key_exists($context->instanceid, $cachedmodules)) {
207             $cachedmodules[$context->instanceid] = get_coursemodule_from_id('', $context->instanceid);
208         }
210         if (!($cm = $cachedmodules[$context->instanceid])) {
211             return null;
212         }
214         if ($cm->course == $COURSE->id) {
215             $course = $COURSE;
216         } else if (!$course = $DB->get_record('course', array('id'=>$cm->course))) {
217             return null;
218         }
220         $modinfo = get_fast_modinfo($course);
221         if (empty($modinfo->cms[$cm->id]->uservisible)) {
222             return null;
223         }
225         $modname = $modinfo->cms[$cm->id]->modname;
227         if (!file_exists("$CFG->dirroot/mod/$modname/lib.php")) {
228             return null;
229         }
231         // ok, we know that module exists, and user may access it
233         $level = new file_info_context_module($this, $context, $course, $cm, $modname);
234         return $level->get_file_info($component, $filearea, $itemid, $filepath, $filename);
235     }