MDL-14627 fixed file_browser access control
[moodle.git] / mod / folder / lib.php
CommitLineData
0e16b939 1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * Mandatory public API of folder module
20 *
9fe1fbcc
PS
21 * @package mod
22 * @subpackage folder
23 * @copyright 2009 Petr Skoda {@link http://skodak.org}
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
0e16b939 25 */
26
64f93798
PS
27defined('MOODLE_INTERNAL') || die();
28
0e16b939 29/**
30 * List of features supported in Folder module
31 * @param string $feature FEATURE_xx constant for requested feature
32 * @return mixed True if module supports feature, false if not, null if doesn't know
33 */
34function folder_supports($feature) {
35 switch($feature) {
36 case FEATURE_MOD_ARCHETYPE: return MOD_ARCHETYPE_RESOURCE;
37 case FEATURE_GROUPS: return false;
38 case FEATURE_GROUPINGS: return false;
39 case FEATURE_GROUPMEMBERSONLY: return true;
40 case FEATURE_MOD_INTRO: return true;
41 case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
42 case FEATURE_GRADE_HAS_GRADE: return false;
43 case FEATURE_GRADE_OUTCOMES: return false;
78692f23 44 case FEATURE_BACKUP_MOODLE2: return true;
0e16b939 45
46 default: return null;
47 }
48}
49
50/**
51 * Returns all other caps used in module
52 * @return array
53 */
54function folder_get_extra_capabilities() {
55 return array('moodle/site:accessallgroups');
56}
57
58/**
59 * This function is used by the reset_course_userdata function in moodlelib.
60 * @param $data the data submitted from the reset course.
61 * @return array status array
62 */
63function folder_reset_userdata($data) {
64 return array();
65}
66
67/**
68 * List of view style log actions
69 * @return array
70 */
71function folder_get_view_actions() {
72 return array('view', 'view all');
73}
74
75/**
76 * List of update style log actions
77 * @return array
78 */
79function folder_get_post_actions() {
80 return array('update', 'add');
81}
82
83/**
84 * Add folder instance.
85 * @param object $data
86 * @param object $mform
87 * @return int new folder instance id
88 */
89function folder_add_instance($data, $mform) {
90 global $DB;
91
92 $cmid = $data->coursemodule;
93 $draftitemid = $data->files;
94
95 $data->timemodified = time();
96 $data->id = $DB->insert_record('folder', $data);
97
98 // we need to use context now, so we need to make sure all needed info is already in db
99 $DB->set_field('course_modules', 'instance', $data->id, array('id'=>$cmid));
100 $context = get_context_instance(CONTEXT_MODULE, $cmid);
101
102 if ($draftitemid) {
64f93798 103 file_save_draft_area_files($draftitemid, $context->id, 'mod_folder', 'content', 0, array('subdirs'=>true));
0e16b939 104 }
105
106 return $data->id;
107}
108
109/**
110 * Update folder instance.
111 * @param object $data
112 * @param object $mform
113 * @return bool true
114 */
115function folder_update_instance($data, $mform) {
116 global $CFG, $DB;
117
118 $cmid = $data->coursemodule;
119 $draftitemid = $data->files;
120
121 $data->timemodified = time();
122 $data->id = $data->instance;
123 $data->revision++;
124
125 $DB->update_record('folder', $data);
126
127 $context = get_context_instance(CONTEXT_MODULE, $cmid);
128 if ($draftitemid = file_get_submitted_draft_itemid('files')) {
64f93798 129 file_save_draft_area_files($draftitemid, $context->id, 'mod_folder', 'content', 0, array('subdirs'=>true));
0e16b939 130 }
131
132 return true;
133}
134
135/**
136 * Delete folder instance.
137 * @param int $id
138 * @return bool true
139 */
140function folder_delete_instance($id) {
141 global $DB;
142
143 if (!$folder = $DB->get_record('folder', array('id'=>$id))) {
144 return false;
145 }
146
147 // note: all context files are deleted automatically
148
149 $DB->delete_records('folder', array('id'=>$folder->id));
150
151 return true;
152}
153
154/**
155 * Return use outline
156 * @param object $course
157 * @param object $user
158 * @param object $mod
159 * @param object $folder
160 * @return object|null
161 */
162function folder_user_outline($course, $user, $mod, $folder) {
163 global $DB;
164
165 if ($logs = $DB->get_records('log', array('userid'=>$user->id, 'module'=>'folder',
166 'action'=>'view', 'info'=>$folder->id), 'time ASC')) {
167
168 $numviews = count($logs);
169 $lastlog = array_pop($logs);
170
39790bd8 171 $result = new stdClass();
0e16b939 172 $result->info = get_string('numviews', '', $numviews);
173 $result->time = $lastlog->time;
174
175 return $result;
176 }
177 return NULL;
178}
179
180/**
181 * Return use complete
182 * @param object $course
183 * @param object $user
184 * @param object $mod
185 * @param object $folder
186 */
187function folder_user_complete($course, $user, $mod, $folder) {
188 global $CFG, $DB;
189
190 if ($logs = $DB->get_records('log', array('userid'=>$user->id, 'module'=>'folder',
191 'action'=>'view', 'info'=>$folder->id), 'time ASC')) {
192 $numviews = count($logs);
193 $lastlog = array_pop($logs);
194
195 $strmostrecently = get_string('mostrecently');
196 $strnumviews = get_string('numviews', '', $numviews);
197
198 echo "$strnumviews - $strmostrecently ".userdate($lastlog->time);
199
200 } else {
201 print_string('neverseen', 'folder');
202 }
203}
204
205/**
206 * Returns the users with data in one folder
207 *
208 * @param int $folderid
209 * @return bool false
210 */
211function folder_get_participants($folderid) {
212 return false;
213}
214
215/**
216 * Lists all browsable file areas
217 * @param object $course
218 * @param object $cm
219 * @param object $context
220 * @return array
221 */
222function folder_get_file_areas($course, $cm, $context) {
223 $areas = array();
64f93798
PS
224 $areas['content'] = get_string('foldercontent', 'folder');
225
0e16b939 226 return $areas;
227}
228
229/**
792881f0 230 * File browsing support for folder module content area.
0e16b939 231 * @param object $browser
232 * @param object $areas
233 * @param object $course
234 * @param object $cm
235 * @param object $context
236 * @param string $filearea
237 * @param int $itemid
238 * @param string $filepath
239 * @param string $filename
240 * @return object file_info instance or null if not found
241 */
242function folder_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
243 global $CFG;
244
0e16b939 245
64f93798 246 if ($filearea === 'content') {
605d358c
PS
247 if (!has_capability('mod/folder:view', $context)) {
248 return NULL;
249 }
64f93798 250 $fs = get_file_storage();
0e16b939 251
0e16b939 252 $filepath = is_null($filepath) ? '/' : $filepath;
253 $filename = is_null($filename) ? '.' : $filename;
64f93798 254 if (!$storedfile = $fs->get_file($context->id, 'mod_folder', 'content', 0, $filepath, $filename)) {
0e16b939 255 if ($filepath === '/' and $filename === '.') {
64f93798 256 $storedfile = new virtual_root_file($context->id, 'mod_folder', 'content', 0);
0e16b939 257 } else {
258 // not found
259 return null;
260 }
261 }
64f93798 262
0e16b939 263 require_once("$CFG->dirroot/mod/folder/locallib.php");
64f93798
PS
264 $urlbase = $CFG->wwwroot.'/pluginfile.php';
265
266 // students may read files here
7c78c525 267 $canwrite = has_capability('mod/folder:managefiles', $context);
0e16b939 268 return new folder_content_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, $canwrite, false);
269 }
270
271 // note: folder_intro handled in file_browser automatically
272
273 return null;
274}
275
276/**
277 * Serves the folder files.
278 *
279 * @param object $course
64f93798 280 * @param object $cm
0e16b939 281 * @param object $context
282 * @param string $filearea
283 * @param array $args
284 * @param bool $forcedownload
792881f0 285 * @return bool false if file not found, does not return if found - just send the file
0e16b939 286 */
64f93798 287function folder_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) {
0e16b939 288 global $CFG, $DB;
289
64f93798 290 if ($context->contextlevel != CONTEXT_MODULE) {
0e16b939 291 return false;
292 }
293
64f93798 294 require_course_login($course, true, $cm);
9093de63
PS
295 if (!has_capability('mod/folder:view', $context)) {
296 return false;
297 }
0e16b939 298
64f93798
PS
299 if ($filearea !== 'content') {
300 // intro is handled automatically in pluginfile.php
0e16b939 301 return false;
302 }
303
0e16b939 304 array_shift($args); // ignore revision - designed to prevent caching problems only
305
306 $fs = get_file_storage();
64f93798
PS
307 $relativepath = implode('/', $args);
308 $fullpath = "/$context->id/mod_folder/content/0/$relativepath";
0e16b939 309 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
310 return false;
311 }
312
313 // finally send the file
adbb249d
DC
314 // for folder module, we force download file all the time
315 send_stored_file($file, 86400, 0, true);
0e16b939 316}
92059c7e
SH
317
318/**
792881f0 319 * This function extends the global navigation for the site.
92059c7e
SH
320 * It is important to note that you should not rely on PAGE objects within this
321 * body of code as there is no guarantee that during an AJAX request they are
322 * available
323 *
324 * @param navigation_node $navigation The folder node within the global navigation
325 * @param stdClass $course The course object returned from the DB
326 * @param stdClass $module The module object returned from the DB
792881f0 327 * @param stdClass $cm The course module instance returned from the DB
92059c7e
SH
328 */
329function folder_extend_navigation($navigation, $course, $module, $cm) {
330 /**
331 * This is currently just a stub so that it can be easily expanded upon.
332 * When expanding just remove this comment and the line below and then add
333 * you content.
334 */
335 $navigation->nodetype = navigation_node::NODETYPE_LEAF;
78692f23 336}