new parameter forcedownload; merged from MOODLE_15_STABLE
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<?php // $Id$
|
||||
// This script fetches files from the dataroot directory
|
||||
// Syntax: file.php/courseid/dir/dir/dir/filename.ext
|
||||
// file.php/courseid/dir/dir/dir/filename.ext?forcedownload=1 (download instead of inline)
|
||||
// file.php/courseid/dir (returns index.html from dir)
|
||||
// Workaround: file.php?file=/courseid/dir/dir/dir/filename.ext
|
||||
// Test: file.php/testslasharguments
|
||||
@@ -16,6 +17,7 @@
|
||||
|
||||
|
||||
$relativepath = get_file_argument('file.php');
|
||||
$forcedownload = optional_param('forcedownload', 0, PARAM_BOOL);
|
||||
|
||||
// relative path must start with '/', because of backup/restore!!!
|
||||
if (!$relativepath) {
|
||||
@@ -86,10 +88,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
// security: force download of all attachments submitted by students
|
||||
if ((count($args) >= 3)
|
||||
and (strtolower($args[1]) == 'moddata')
|
||||
and ((strtolower($args[2]) == 'forum')
|
||||
or (strtolower($args[2]) == 'assignment')
|
||||
or (strtolower($args[2]) == 'glossary')
|
||||
or (strtolower($args[2]) == 'wiki')
|
||||
or (strtolower($args[2]) == 'exercise')
|
||||
or (strtolower($args[2]) == 'workshop')
|
||||
)) {
|
||||
$forcedownload = 1; // force download of all attachments
|
||||
}
|
||||
|
||||
// security: some protection of hidden resource files
|
||||
// warning: it may break backwards compatibility
|
||||
// TODO: case sensitive in PostgresQL, case insensitive in MySQL (ok?)
|
||||
// TODO: should we protect directories too?
|
||||
if ((!empty($CFG->preventaccesstohiddenfiles))
|
||||
and (count($args) >= 2)
|
||||
and (!isteacher($course->id))) {
|
||||
@@ -131,7 +144,7 @@
|
||||
// ========================================
|
||||
session_write_close(); // unlock session during fileserving
|
||||
$filename = $args[count($args)-1];
|
||||
send_file($pathname, $filename, $lifetime, !empty($CFG->filteruploadedfiles));
|
||||
send_file($pathname, $filename, $lifetime, !empty($CFG->filteruploadedfiles), false, $forcedownload);
|
||||
|
||||
function not_found($courseid) {
|
||||
global $CFG;
|
||||
|
||||
+41
-8
@@ -136,26 +136,37 @@ function mimeinfo($element, $filename) {
|
||||
}
|
||||
}
|
||||
|
||||
function send_file($path, $filename, $lifetime=86400 , $filter=false, $pathisstring=false) {
|
||||
function send_file($path, $filename, $lifetime=86400 , $filter=false, $pathisstring=false,$forcedownload=false) {
|
||||
|
||||
$mimetype = mimeinfo('type', $filename);
|
||||
$mimetype = $forcedownload ? 'application/force-download' : mimeinfo('type', $filename);
|
||||
$lastmodified = $pathisstring ? time() : filemtime($path);
|
||||
$filesize = $pathisstring ? strlen($path) : filesize($path);
|
||||
|
||||
//IE compatibiltiy HACK!
|
||||
if(ini_get('zlib.output_compression')) {
|
||||
ini_set('zlib.output_compression', 'Off');
|
||||
}
|
||||
|
||||
@header('Last-Modified: '. gmdate('D, d M Y H:i:s', $lastmodified) .' GMT');
|
||||
if ($lifetime > 0) {
|
||||
@header('Cache-control: max-age='.$lifetime);
|
||||
@header('Expires: '. gmdate('D, d M Y H:i:s', time() + $lifetime) .'GMT');
|
||||
@header('Pragma: ');
|
||||
} else {
|
||||
// this part is tricky, displaying of MS Office documents in IE needs
|
||||
// to store the file on disk, but no-cache may prevent it
|
||||
// This part is tricky, displaying of MS Office documents in IE needs
|
||||
// to store the file on disk, but no-cache may prevent it.
|
||||
// HTTPS:// sites might have problems with following code in IE, tweak it yourself if needed ;-)
|
||||
@header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=10');
|
||||
@header('Expires: '. gmdate('D, d M Y H:i:s', 0) .'GMT');
|
||||
@header('Pragma: no-cache');
|
||||
}
|
||||
@header('Accept-Ranges: none'); // PDF compatibility
|
||||
@header('Content-disposition: inline; filename='.$filename);
|
||||
@header('Accept-Ranges: none'); // Comment out if PDFs do not work...
|
||||
|
||||
if ($forcedownload) {
|
||||
@header('Content-disposition: attachment; filename='.$filename);
|
||||
} else {
|
||||
@header('Content-disposition: inline; filename='.$filename);
|
||||
}
|
||||
|
||||
if (!$filter) {
|
||||
@header('Content-length: '.$filesize);
|
||||
@@ -167,7 +178,7 @@ function send_file($path, $filename, $lifetime=86400 , $filter=false, $pathisstr
|
||||
if ($pathisstring) {
|
||||
echo $path;
|
||||
}else {
|
||||
readfile($path);
|
||||
readfile_chunked($path);
|
||||
}
|
||||
} else { // Try to put the file through filters
|
||||
global $course; // HACK!
|
||||
@@ -199,7 +210,7 @@ function send_file($path, $filename, $lifetime=86400 , $filter=false, $pathisstr
|
||||
if ($pathisstring) {
|
||||
echo $path;
|
||||
}else {
|
||||
readfile($path);
|
||||
readfile_chunked($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -344,5 +355,27 @@ function fulldelete($location) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function readfile_chunked($filename,$retbytes=true) {
|
||||
$chunksize = 1*(1024*1024); // 1MB chunks
|
||||
$buffer = '';
|
||||
$cnt =0;// $handle = fopen($filename, 'rb');
|
||||
$handle = fopen($filename, 'rb');
|
||||
if ($handle === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!feof($handle)) {
|
||||
$buffer = fread($handle, $chunksize);
|
||||
echo $buffer;
|
||||
if ($retbytes) {
|
||||
$cnt += strlen($buffer);}
|
||||
}
|
||||
$status = fclose($handle);
|
||||
if ($retbytes && $status) {
|
||||
return $cnt; // return num. bytes delivered like readfile() does.
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user