function webfm_send_file in Web File Manager 5
Same name and namespace in other branches
- 5.2 webfm.module \webfm_send_file()
webfm_send_file - streams a file privately for download
If $fid arg is numeric then file path is referenced via db, otherwise the arg ...is a urlencoded path that must be converted and concatenated to base file dir
Parameters
object $fid - file id:
bool $attach - 1 = attach / 0 = inline:
1 string reference to 'webfm_send_file'
- webfm_menu in ./
webfm.module - Implementation of hook_menu().
File
- ./
webfm.module, line 2431
Code
function webfm_send_file($fid, $attach = false) {
global $user;
$match = FALSE;
$f = false;
// User has either admin access, webfm access or view attach access
if ($user->uid == 1 || user_access('administer webfm')) {
// Admins have total access
$webfm_perm = WEBFM_ADMIN;
$match = TRUE;
}
else {
if (user_access('access webfm')) {
$webfm_perm = WEBFM_USER;
}
else {
if (user_access('view webfm attachments')) {
$webfm_perm = WEBFM_ATTACH_VIEW;
}
else {
$webfm_perm = 0;
}
}
}
if (is_numeric($fid)) {
if (($f = webfm_get_file_record($fid)) === FALSE) {
print theme('page', "");
return;
}
else {
if ($f->uid == $user->uid) {
// Even if file has been moved to an inaccessible dir this works
$match = TRUE;
}
}
}
else {
if ($webfm_perm == WEBFM_ADMIN) {
// Only allow admins to download files without fid
$f = new stdClass();
$str_arr = array();
$str_arr = split('[~]', rawurldecode($fid));
$f->fpath = file_directory_path() . "/" . implode('/', $str_arr);
if (!is_file($f->fpath)) {
print theme('page', "");
return;
}
else {
$match = TRUE;
}
}
else {
print theme('page', "");
return;
}
}
// Files that have been attached are always considered public to whoever can
// access that node (nodeaccess security)
if ($match == FALSE && $webfm_perm != WEBFM_ADMIN) {
if ($f->perm & WEBFM_FILE_ACCESS_PUBLIC_VIEW) {
$match = TRUE;
}
else {
if ($webfm_perm == WEBFM_USER || $webfm_perm == WEBFM_ATTACH_VIEW) {
//Check if the file is attached to a node
$query = 'SELECT nid FROM {webfm_attach} WHERE fid = %d';
$result = db_query($query, $f->fid);
if ($result !== FALSE) {
while ($dbfid = db_fetch_array($result)) {
$node = node_load($dbfid['nid']);
if (node_access('view', $node)) {
$match = TRUE;
break;
}
}
}
}
}
}
// Files that are viewable via the filebrowser UI are downloadable
if ($match == FALSE && $webfm_perm == WEBFM_USER && (webfm_file_view_access($f) || webfm_file_mod_access($f))) {
$match = TRUE;
}
if (!$match) {
drupal_access_denied();
return;
}
$name = basename($f->fpath);
//filenames in IE containing dots will screw up the
//filename unless we add this
if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) {
$name = preg_replace('/\\./', '%2e', $name, substr_count($name, '.') - 1);
}
// Get file extension
$type = webfm_mime_type($name);
//download headers:
$header = array();
if ($attach === '1') {
// prompt for download file or view
$header[] = 'Pragma: no-cache';
$header[] = 'Cache-Control: no-cache, must-revalidate';
$header[] = 'Content-Disposition: attachment; filename="' . $name . '";';
if (!empty($f->fid)) {
$cnt = array();
$cnt['dl_cnt'] = (int) $f->dl_cnt + 1;
webfm_dbupdate_file($f->fid, '', $cnt);
}
}
else {
// view file via browser
$header[] = 'Pragma: public';
// required
$header[] = 'Expires: 0';
$header[] = 'Cache-Control: must-revalidate, post-check=0, pre-check=0';
$header[] = 'Content-Transfer-Encoding: binary';
$header[] = 'Content-Disposition: inline; filename="' . $name . '";';
// consider an app run inside the browser as a 'download'
if (!empty($f->fid) && strpos($type, "application") === 0) {
$cnt = array();
$cnt['dl_cnt'] = (int) $f->dl_cnt + 1;
webfm_dbupdate_file($f->fid, '', $cnt);
}
}
$header[] = 'Content-Type: ' . $type;
$header[] = 'Content-Length: ' . (string) @filesize($f->fpath);
$header[] = 'Connection: close';
//drupal file_transfer will fail if file is not inside file system directory
file_transfer($f->fpath, $header);
}