MDL-14589 initial file storage implementation, temporary file manager, migration...
[moodle.git] / file.php
1 <?php // $Id$
2       // This script fetches files from the dataroot directory
3       //
4       // You should use the get_file_url() function, available in lib/filelib.php, to link to file.php.
5       // This ensures proper formatting and offers useful options.
6       //
7       // Syntax:      file.php/courseid/dir/dir/dir/filename.ext
8       //              file.php/courseid/dir/dir/dir/filename.ext?forcedownload=1 (download instead of inline)
9       //              file.php/courseid/dir (returns index.html from dir)
10       // Workaround:  file.php?file=/courseid/dir/dir/dir/filename.ext
11       // Test:        file.php/testslasharguments
14       //TODO: Blog attachments do not have access control implemented - anybody can read them!
15       //      It might be better to move the code to separate file because the access
16       //      control is quite complex - see bolg/index.php
18     require_once('config.php');
19     require_once('lib/filelib.php');
21     if (!isset($CFG->filelifetime)) {
22         $lifetime = 86400;     // Seconds for files to remain in caches
23     } else {
24         $lifetime = $CFG->filelifetime;
25     }
27     // disable moodle specific debug messages
28     disable_debugging();
30     $relativepath = get_file_argument('file.php');
31     $forcedownload = optional_param('forcedownload', 0, PARAM_BOOL);
33     // relative path must start with '/', because of backup/restore!!!
34     if (!$relativepath) {
35         print_error('invalidargorconf');
36     } else if ($relativepath{0} != '/') {
37         print_error('pathdoesnotstartslash');
38     }
40     // extract relative path components
41     $args = explode('/', ltrim($relativepath, '/'));
43     if (count($args) == 0) { // always at least courseid, may search for index.html in course root
44         print_error('invalidarguments');
45     }
47     $courseid = (int)array_shift($args);
48     $relativepath = '/'.implode('/', $args);
50     // security: limit access to existing course subdirectories
51     if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
52         print_error('invalidcourseid');
53     }
55     if ($course->id != SITEID) {
56         require_login($course->id, true, null, false);
58     } else if ($CFG->forcelogin) {
59         if (!empty($CFG->sitepolicy)
60             and ($CFG->sitepolicy == $CFG->wwwroot.'/file.php'.$relativepath
61                  or $CFG->sitepolicy == $CFG->wwwroot.'/file.php?file='.$relativepath)) {
62             //do not require login for policy file
63         } else {
64             require_login(0, true, null, false);
65         }
66     }
68     $context = get_context_instance(CONTEXT_COURSE, $course->id);
70     $fs = get_file_storage();
72     $fullpath = $context->id.'course_content0'.$relativepath;
74     if (!$file = $fs->get_file_by_hash(sha1($fullpath))) {
75         if (strrpos($fullpath, '/') !== strlen($fullpath) -1 ) {
76             $fullpath .= '/';
77         }
78         if (!$file = $fs->get_file_by_hash(sha1($fullpath.'/.'))) {
79             not_found();
80         }
81     }
82     // do not serve dirs
83     if ($file->get_filename() == '.') {
84         if (!$file = $fs->get_file_by_hash(sha1($fullpath.'index.html'))) {
85             if (!$file = $fs->get_file_by_hash(sha1($fullpath.'index.htm'))) {
86                 if (!$file = $fs->get_file_by_hash(sha1($fullpath.'Default.htm'))) {
87                     not_found();
88                 }
89             }
90         }
91     }
93     // ========================================
94     // finally send the file
95     // ========================================
96     session_write_close(); // unlock session during fileserving
97     send_stored_file($file, $lifetime, $CFG->filteruploadedfiles, $forcedownload);
99     function not_found() {
100         global $CFG, $COURSE;
101         header('HTTP/1.0 404 not found');
102         print_error('filenotfound', 'error', $CFG->wwwroot.'/course/view.php?id='.$COURSE->id); //this is not displayed on IIS??
103     }