file width.html was added on branch MOODLE_15_STABLE on 2005-07-07 16:14:37 +0000
[moodle.git] / file.php
blob0e18cb55eb4ccbba0792b7cf221e1a02b72924e5
1 <?php // $Id$
2 // This script fetches files from the dataroot directory
3 // Syntax: file.php/courseid/dir/dir/dir/filename.ext
4 // file.php/courseid/dir (returns index.html from dir)
5 // Workaround: file.php?file=/courseid/dir/dir/dir/filename.ext
6 // Test: file.php/testslasharguments
8 require_once('config.php');
9 require_once('lib/filelib.php');
11 if (empty($CFG->filelifetime)) {
12 $lifetime = 86400; // Seconds for files to remain in caches
13 } else {
14 $lifetime = $CFG->filelifetime;
18 $relativepath = get_file_argument('file.php');
20 // relative path must start with '/', because of backup/restore!!!
21 if (!$relativepath) {
22 error('No valid arguments supplied or incorrect server configuration');
23 } else if ($relativepath{0} != '/') {
24 error('No valid arguments supplied, path does not start with slash!');
27 $pathname = $CFG->dataroot.$relativepath;
29 // extract relative path components
30 $args = explode('/', trim($relativepath, '/'));
31 if (count($args) == 0) { // always at least courseid, may search for index.html in course root
32 error('No valid arguments supplied');
35 // security: limit access to existing course subdirectories
36 // note: course ID must be specified
37 // note: the lang field is needed for the course language switching hack in weblib.php
38 if (!$course = get_record_sql("SELECT id, lang FROM {$CFG->prefix}course WHERE id='".(int)$args[0]."'")) {
39 error('Invalid course ID');
42 // security: prevent access to "000" or "1 something" directories
43 if ($args[0] != $course->id) {
44 error('Invalid course ID');
47 // security: login to course if necessary
48 if ($course->id != SITEID) {
49 require_login($course->id);
50 } else if ($CFG->forcelogin) {
51 require_login();
54 // security: only editing teachers can access backups
55 if ((!isteacheredit($course->id))
56 and (count($args) >= 2)
57 and (strtolower($args[1]) == 'backupdata')) {
59 error('Access not allowed');
62 if (is_dir($pathname)) {
63 if (file_exists($pathname.'/index.html')) {
64 $pathname = rtrim($pathname, '/').'/index.html';
65 $args[] = 'index.html';
66 } else if (file_exists($pathname.'/index.htm')) {
67 $pathname = rtrim($pathname, '/').'/index.htm';
68 $args[] = 'index.htm';
69 } else if (file_exists($pathname.'/Default.htm')) {
70 $pathname = rtrim($pathname, '/').'/Default.htm';
71 $args[] = 'Default.htm';
72 } else {
73 // security: do not return directory node!
74 not_found($course->id);
78 // security: teachers can view all assignments, students only their own
79 if ((count($args) >= 3)
80 and (strtolower($args[1]) == 'moddata')
81 and (strtolower($args[2]) == 'assignment')) {
83 $lifetime = 0; // do not cache assignments, students may reupload them
84 if ((!isteacher($course->id)) && (count($args) != 6 || $args[4] != $USER->id)) {
85 error('Access not allowed');
89 // security: some protection of hidden resource files
90 // warning: it may break backwards compatibility
91 // TODO: case sensitive in PostgresQL, case insensitive in MySQL (ok?)
92 // TODO: should we protect directories too?
93 if ((!empty($CFG->preventaccesstohiddenfiles))
94 and (count($args) >= 2)
95 and (!isteacher($course->id))) {
97 $reference = ltrim($relativepath, "/{$args[0]}/");
99 $sql = "SELECT COUNT(r.id) " .
100 "FROM {$CFG->prefix}resource r, " .
101 "{$CFG->prefix}course_modules cm, " .
102 "{$CFG->prefix}modules m " .
103 "WHERE r.course = '{$course->id}' " .
104 "AND m.name = 'resource' " .
105 "AND cm.module = m.id " .
106 "AND cm.instance = r.id " .
107 "AND cm.visible = 0 " .
108 "AND r.type = 'file' " .
109 "AND r.reference = '{$reference}'";
110 if (count_records_sql($sql)) {
111 error('Access not allowed');
115 // check that file exists
116 if (!file_exists($pathname)) {
117 not_found($course->id);
120 // extra security: keep symbolic links inside dataroot/courseid if required
121 /*if (!empty($CFG->checksymlinks)) {
122 $realpath = realpath($pathname);
123 $realdataroot = realpath($CFG->dataroot.'/'.$course->id);
124 if (strpos($realpath, $realdataroot) !== 0) {
125 not_found($course->id);
129 // ========================================
130 // finally send the file
131 // ========================================
132 session_write_close(); // unlock session during fileserving
133 $filename = $args[count($args)-1];
134 send_file($pathname, $filename, $lifetime, !empty($CFG->filteruploadedfiles));
136 function not_found($courseid) {
137 global $CFG;
138 header('HTTP/1.0 404 not found');
139 error(get_string('filenotfound', 'error'), $CFG->wwwroot.'/course/view.php?id='.$courseid); //this is not displayed on IIS??