From 83b80acad8431fcd56e9a331ba06c41edee48c91 Mon Sep 17 00:00:00 2001 From: David Rothstein Date: Wed, 16 Jul 2014 16:03:02 -0400 Subject: Drupal 7.29 --- includes/file.inc | 81 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 17 deletions(-) (limited to 'includes/file.inc') diff --git a/includes/file.inc b/includes/file.inc index 834699f18..d3008cc4f 100644 --- a/includes/file.inc +++ b/includes/file.inc @@ -1999,23 +1999,7 @@ function file_download() { $target = implode('/', $args); $uri = $scheme . '://' . $target; if (file_stream_wrapper_valid_scheme($scheme) && file_exists($uri)) { - // Let other modules provide headers and controls access to the file. - // module_invoke_all() uses array_merge_recursive() which merges header - // values into a new array. To avoid that and allow modules to override - // headers instead, use array_merge() to merge the returned arrays. - $headers = array(); - foreach (module_implements('file_download') as $module) { - $function = $module . '_file_download'; - $result = $function($uri); - if ($result == -1) { - // Throw away the headers received so far. - $headers = array(); - break; - } - if (isset($result) && is_array($result)) { - $headers = array_merge($headers, $result); - } - } + $headers = file_download_headers($uri); if (count($headers)) { file_transfer($uri, $headers); } @@ -2027,6 +2011,69 @@ function file_download() { drupal_exit(); } +/** + * Retrieves headers for a private file download. + * + * Calls all module implementations of hook_file_download() to retrieve headers + * for files by the module that originally provided the file. The presence of + * returned headers indicates the current user has access to the file. + * + * @param $uri + * The URI for the file whose headers should be retrieved. + * + * @return + * If access is allowed, headers for the file, suitable for passing to + * file_transfer(). If access is not allowed, an empty array will be returned. + * + * @see file_transfer() + * @see file_download_access() + * @see hook_file_downlaod() + */ +function file_download_headers($uri) { + // Let other modules provide headers and control access to the file. + // module_invoke_all() uses array_merge_recursive() which merges header + // values into a new array. To avoid that and allow modules to override + // headers instead, use array_merge() to merge the returned arrays. + $headers = array(); + foreach (module_implements('file_download') as $module) { + $function = $module . '_file_download'; + $result = $function($uri); + if ($result == -1) { + // Throw away the headers received so far. + $headers = array(); + break; + } + if (isset($result) && is_array($result)) { + $headers = array_merge($headers, $result); + } + } + return $headers; +} + +/** + * Checks that the current user has access to a particular file. + * + * The return value of this function hinges on the return value from + * file_download_headers(), which is the function responsible for collecting + * access information through hook_file_download(). + * + * If immediately transferring the file to the browser and the headers will + * need to be retrieved, the return value of file_download_headers() should be + * used to determine access directly, so that access checks will not be run + * twice. + * + * @param $uri + * The URI for the file whose access should be retrieved. + * + * @return + * Boolean TRUE if access is allowed. FALSE if access is not allowed. + * + * @see file_download_headers() + * @see hook_file_download() + */ +function file_download_access($uri) { + return count(file_download_headers($uri)) > 0; +} /** * Finds all files that match a given mask in a given directory. -- cgit v1.2.3