2003-12-26 23:03:21 +00:00
< ? php
2005-08-11 12:57:41 +00:00
// $Id$
2003-12-27 21:29:20 +00:00
2004-08-21 06:42:38 +00:00
/**
* @ file
* API for handling file uploads and server file management .
*/
2003-12-27 21:29:20 +00:00
/**
2004-01-06 19:52:14 +00:00
* @ defgroup file File interface
2003-12-27 21:29:20 +00:00
* @ {
2004-09-09 05:51:08 +00:00
* Common file handling functions .
2003-12-26 23:03:21 +00:00
*/
define ( 'FILE_DOWNLOADS_PUBLIC' , 1 );
define ( 'FILE_DOWNLOADS_PRIVATE' , 2 );
2004-08-17 21:35:26 +00:00
define ( 'FILE_CREATE_DIRECTORY' , 1 );
define ( 'FILE_MODIFY_PERMISSIONS' , 2 );
2004-09-17 18:18:04 +00:00
define ( 'FILE_EXISTS_RENAME' , 0 );
define ( 'FILE_EXISTS_REPLACE' , 1 );
define ( 'FILE_EXISTS_ERROR' , 2 );
2003-12-26 23:03:21 +00:00
/**
* Create the download path to a file .
2004-09-17 18:18:04 +00:00
*
* @ param $path Path to the file to generate URL for
* @ return URL pointing to the file
2003-12-26 23:03:21 +00:00
*/
function file_create_url ( $path ) {
2005-11-12 09:23:50 +00:00
if ( strpos ( $path , file_directory_path ()) !== false ) {
$path = trim ( substr ( $path , strlen ( file_directory_path ())), '\\/' );
2003-12-27 14:28:23 +00:00
}
2004-01-13 10:33:02 +00:00
switch ( variable_get ( 'file_downloads' , FILE_DOWNLOADS_PUBLIC )) {
2003-12-26 23:03:21 +00:00
case FILE_DOWNLOADS_PUBLIC :
2005-11-12 09:23:50 +00:00
return $GLOBALS [ 'base_url' ] . '/' . file_directory_path () . '/' . str_replace ( '\\' , '/' , $path );
2003-12-26 23:03:21 +00:00
case FILE_DOWNLOADS_PRIVATE :
2005-09-13 19:05:34 +00:00
return url ( 'system/files' , 'file=' . $path , NULL , TRUE );
2003-12-26 23:03:21 +00:00
}
}
/**
2004-09-17 18:18:04 +00:00
* Make sure the destination is a complete path and resides in the
* file system directory , if it is not prepend the
2003-12-26 23:03:21 +00:00
* file system directory .
2004-09-17 18:18:04 +00:00
*
2004-10-19 18:02:31 +00:00
* @ param $dest Path to verify
2004-09-17 18:18:04 +00:00
* @ return Path to file with file system directory appended if necessary .
2005-05-14 21:05:08 +00:00
* Returns FALSE if the path is invalid ( i . e . outside the configured 'files' - directory ) .
2003-12-26 23:03:21 +00:00
*/
function file_create_path ( $dest = 0 ) {
2005-11-12 09:23:50 +00:00
$file_path = file_directory_path ();
2003-12-26 23:03:21 +00:00
if ( ! $dest ) {
2005-05-14 21:05:08 +00:00
return $file_path ;
2003-12-26 23:03:21 +00:00
}
2005-05-18 05:17:11 +00:00
// file_check_location() checks whether the destination is inside the Drupal files directory.
2005-05-14 21:05:08 +00:00
if ( file_check_location ( $dest , $file_path )) {
2003-12-26 23:03:21 +00:00
return $dest ;
}
2005-05-18 05:17:11 +00:00
// check if the destination is instead inside the Drupal temporary files directory.
2005-11-12 09:23:50 +00:00
else if ( file_check_location ( $dest , file_directory_temp ())) {
2005-05-18 05:17:11 +00:00
return $dest ;
}
2005-11-12 09:23:50 +00:00
// Not found, try again with prefixed directory path.
2005-05-14 21:05:08 +00:00
else if ( file_check_location ( $file_path . '/' . $dest , $file_path )) {
return $file_path . '/' . $dest ;
}
// File not found.
return FALSE ;
2003-12-26 23:03:21 +00:00
}
/**
2005-11-04 20:19:14 +00:00
* Check that the directory exists and is writable . Directories need to
* have execute permissions to be considered a directory by FTP servers , etc .
2003-12-26 23:03:21 +00:00
*
* @ param $directory Path to extract and verify directory for .
2004-08-17 21:35:26 +00:00
* @ param $mode Try to create the directory if it does not exist .
* @ param $form_item Optional name for a field item to attach potential errors to .
2003-12-26 23:03:21 +00:00
* @ return False when directory not found , or true when directory exists .
*/
2004-08-17 21:35:26 +00:00
function file_check_directory ( & $directory , $mode = 0 , $form_item = NULL ) {
2003-12-26 23:03:21 +00:00
$directory = rtrim ( $directory , '/\\' );
2004-08-17 21:35:26 +00:00
// Check if directory exists.
if ( ! is_dir ( $directory )) {
2005-11-04 20:19:14 +00:00
if (( $mode & FILE_CREATE_DIRECTORY ) && @ mkdir ( $directory )) {
2005-05-05 22:22:46 +00:00
drupal_set_message ( t ( 'The directory %directory has been created.' , array ( '%directory' => theme ( 'placeholder' , $directory ))));
2005-11-04 20:19:14 +00:00
@ chmod ( $directory , 0775 ); // Necessary for non-webserver users.
2004-08-17 21:35:26 +00:00
}
else {
if ( $form_item ) {
2005-03-31 09:25:33 +00:00
form_set_error ( $form_item , t ( 'The directory %directory does not exist.' , array ( '%directory' => theme ( 'placeholder' , $directory ))));
2004-08-17 21:35:26 +00:00
}
return false ;
}
}
// Check to see if the directory is writable.
if ( ! is_writable ( $directory )) {
2005-11-04 20:19:14 +00:00
if (( $mode & FILE_MODIFY_PERMISSIONS ) && @ chmod ( $directory , 0775 )) {
2005-05-05 22:22:46 +00:00
drupal_set_message ( t ( 'The permissions of directory %directory have been changed to make it writable.' , array ( '%directory' => theme ( 'placeholder' , $directory ))));
2004-08-17 21:35:26 +00:00
}
else {
2005-05-05 22:22:46 +00:00
form_set_error ( $form_item , t ( 'The directory %directory is not writable' , array ( '%directory' => theme ( 'placeholder' , $directory ))));
watchdog ( 'file system' , t ( 'The directory %directory is not writable, because it does not have the correct permissions set.' , array ( '%directory' => theme ( 'placeholder' , $directory ))), WATCHDOG_ERROR );
2004-08-17 21:35:26 +00:00
return false ;
}
}
return true ;
2003-12-26 23:03:21 +00:00
}
/**
* Checks path to see if it is a directory , or a dir / file .
*
* @ param $path
*/
function file_check_path ( & $path ) {
// Check if path is a directory.
if ( file_check_directory ( $path )) {
return '' ;
}
// Check if path is a possible dir/file.
$filename = basename ( $path );
$path = dirname ( $path );
if ( file_check_directory ( $path )) {
return $filename ;
}
return false ;
}
/**
2005-12-17 17:24:46 +00:00
* Check if $source is a valid file upload . If so , process $_FILES
* and return its contents as an object .
2003-12-26 23:03:21 +00:00
*
* @ param $source
*/
function file_check_upload ( $source ) {
2003-12-27 19:21:48 +00:00
if ( is_object ( $source )) {
2004-08-17 21:35:26 +00:00
if ( is_file ( $source -> filepath )) {
2003-12-27 19:21:48 +00:00
return $source ;
}
}
elseif ( $_FILES [ " edit " ][ " name " ][ $source ] && is_uploaded_file ( $_FILES [ " edit " ][ " tmp_name " ][ $source ])) {
2005-01-24 21:20:16 +00:00
$file = new StdClass ();
2004-08-17 21:35:26 +00:00
$file -> filename = trim ( basename ( $_FILES [ " edit " ][ " name " ][ $source ]), '.' );
$file -> filepath = $_FILES [ " edit " ][ " tmp_name " ][ $source ];
2005-11-29 20:17:10 +00:00
if ( function_exists ( 'mime_content_type' )) {
$file -> filemime = mime_content_type ( $file -> filepath );
if ( $file -> filemime != $_FILES [ " edit " ][ " type " ][ $source ]) {
2005-12-12 11:36:56 +00:00
watchdog ( 'file' , t ( 'For %file the system thinks its MIME type is %detected while the user has given %given for MIME type' , array ( '%file' => theme ( 'placeholder' , $file -> filepath ), '%detected' => theme ( 'placeholder' , $file -> filemime ), '%given' => theme ( 'placeholder' , $_FILES [ 'edit' ][ 'type' ][ $source ]))));
2005-11-29 20:17:10 +00:00
}
}
else {
$file -> filemime = $_FILES [ " edit " ][ " type " ][ $source ];
}
2005-11-30 19:28:18 +00:00
if ((( substr ( $file -> filemime , 0 , 5 ) == 'text/' || strpos ( $file -> filemime , 'javascript' )) && ( substr ( $file -> filename , - 4 ) != '.txt' )) || preg_match ( '/\.(php|pl|py|cgi|asp)$/i' , $file -> filename )) {
2005-11-29 20:17:10 +00:00
$file -> filemime = 'text/plain' ;
rename ( $file -> filepath , $file -> filepath . '.txt' );
$file -> filepath .= '.txt' ;
$file -> filename .= '.txt' ;
}
2003-12-26 23:03:21 +00:00
$file -> error = $_FILES [ " edit " ][ " error " ][ $source ];
2004-08-17 21:35:26 +00:00
$file -> filesize = $_FILES [ " edit " ][ " size " ][ $source ];
$file -> source = $source ;
2003-12-26 23:03:21 +00:00
return $file ;
}
2004-08-17 21:35:26 +00:00
else {
// In case of previews return previous file object.
if ( file_exists ( $_SESSION [ 'file_uploads' ][ $source ] -> filepath )) {
return $_SESSION [ 'file_uploads' ][ $source ];
}
}
2003-12-26 23:03:21 +00:00
}
/**
* Check if a file is really located inside $directory . Should be used to make
* sure a file specified is really located within the directory to prevent
* exploits .
*
* @ code
* // Returns false:
* file_check_location ( '/www/example.com/files/../../../etc/passwd' , '/www/example.com/files' );
* @ endcode
*
* @ param $source A string set to the file to check .
* @ param $directory A string where the file should be located .
* @ return 0 for invalid path or the real path of the source .
*/
function file_check_location ( $source , $directory = 0 ) {
2005-05-17 20:49:54 +00:00
$check = realpath ( $source );
if ( $check ) {
$source = $check ;
}
else {
// This file does not yet exist
$source = realpath ( dirname ( $source )) . '/' . basename ( $source );
}
2004-01-29 11:39:22 +00:00
$directory = realpath ( $directory );
2003-12-26 23:03:21 +00:00
if ( $directory && strpos ( $source , $directory ) !== 0 ) {
return 0 ;
}
return $source ;
}
/**
2004-09-17 18:18:04 +00:00
* Copies a file to a new location . This is a powerful function that in many ways
2003-12-26 23:03:21 +00:00
* performs like an advanced version of copy () .
* - Checks if $source and $dest are valid and readable / writable .
* - Performs a file copy if $source is not equal to $dest .
2004-09-17 18:18:04 +00:00
* - If file already exists in $dest either the call will error out , replace the
* file or rename the file based on the $replace parameter .
2003-12-26 23:03:21 +00:00
*
* @ param $source A string specifying the file location of the original file .
* This parameter will contain the resulting destination filename in case of
* success .
* @ param $dest A string containing the directory $source should be copied to .
2004-09-17 18:18:04 +00:00
* @ param $replace Replace behavior when the destination file already exists .
* - FILE_EXISTS_REPLACE - Replace the existing file
* - FILE_EXISTS_RENAME - Append _ { incrementing number } until the filename is unique
* - FILE_EXISTS_ERROR - Do nothing and return false .
2003-12-26 23:03:21 +00:00
* @ return True for success , false for failure .
*/
2004-09-17 18:18:04 +00:00
function file_copy ( & $source , $dest = 0 , $replace = FILE_EXISTS_RENAME ) {
2003-12-26 23:03:21 +00:00
$dest = file_create_path ( $dest );
$directory = $dest ;
$basename = file_check_path ( $directory );
// Make sure we at least have a valid directory.
if ( $basename === false ) {
2005-05-05 22:22:46 +00:00
drupal_set_message ( t ( 'The selected file %file could not be uploaded, because the destination %directory is not properly configured.' , array ( '%file' => theme ( 'placeholder' , $source ), '%directory' => theme ( 'placeholder' , $dest ))), 'error' );
watchdog ( 'file system' , t ( 'The selected file %file could not not be uploaded, because the destination %directory could not be found, or because its permissions do not allow the file to be written.' , array ( '%file' => theme ( 'placeholder' , $source ), '%directory' => theme ( 'placeholder' , $dest ))), WATCHDOG_ERROR );
2003-12-26 23:03:21 +00:00
return 0 ;
}
// Process a file upload object.
if ( is_object ( $source )) {
$file = $source ;
2004-08-17 21:35:26 +00:00
$source = $file -> filepath ;
2003-12-26 23:03:21 +00:00
if ( ! $basename ) {
2004-08-17 21:35:26 +00:00
$basename = $file -> filename ;
2003-12-26 23:03:21 +00:00
}
}
$source = realpath ( $source );
if ( ! file_exists ( $source )) {
2005-05-05 22:22:46 +00:00
drupal_set_message ( t ( 'The selected file %file could not be copied, because no file by that name exists. Please check that you supplied the correct filename.' , array ( '%file' => theme ( 'placeholder' , $source ))), 'error' );
2003-12-26 23:03:21 +00:00
return 0 ;
}
2005-05-05 22:22:46 +00:00
// If the destination file is not specified then use the filename of the source file.
2003-12-26 23:03:21 +00:00
$basename = $basename ? $basename : basename ( $source );
2004-08-24 19:21:30 +00:00
$dest = $directory . '/' . $basename ;
2003-12-26 23:03:21 +00:00
2004-08-17 21:35:26 +00:00
// Make sure source and destination filenames are not the same, makes no sense
// to copy it if they are. In fact copying the file will most likely result in
// a 0 byte file. Which is bad. Real bad.
if ( $source != realpath ( $dest )) {
2004-09-17 18:18:04 +00:00
if ( file_exists ( $dest )) {
switch ( $replace ) {
case FILE_EXISTS_RENAME :
// Destination file already exists and we can't replace is so we try and
// and find a new filename.
if ( $pos = strrpos ( $basename , '.' )) {
$name = substr ( $basename , 0 , $pos );
$ext = substr ( $basename , $pos );
}
else {
$name = $basename ;
}
$counter = 0 ;
do {
$dest = $directory . '/' . $name . '_' . $counter ++ . $ext ;
} while ( file_exists ( $dest ));
break ;
case FILE_EXISTS_ERROR :
2005-05-05 22:22:46 +00:00
drupal_set_message ( t ( 'The selected file %file could not be copied, because a file by that name already exists in the destination.' , array ( '%file' => theme ( 'placeholder' , $source ))), 'error' );
2004-09-17 18:18:04 +00:00
return 0 ;
}
2004-08-17 21:35:26 +00:00
}
2003-12-26 23:03:21 +00:00
2004-10-28 23:42:36 +00:00
if ( !@ copy ( $source , $dest )) {
2005-05-05 22:22:46 +00:00
drupal_set_message ( t ( 'The selected file %file could not be copied.' , array ( '%file' => theme ( 'placeholder' , $source ))), 'error' );
2004-08-17 21:35:26 +00:00
return 0 ;
}
2005-11-04 20:19:14 +00:00
// Give everyone read access so that FTP'd users or
// non-webserver users can see/read these files.
@ chmod ( $dest , 0664 );
2003-12-26 23:03:21 +00:00
}
if ( is_object ( $file )) {
2004-08-17 21:35:26 +00:00
$file -> filename = $basename ;
$file -> filepath = $dest ;
2003-12-26 23:03:21 +00:00
$source = $file ;
}
else {
$source = $dest ;
}
2004-08-17 21:35:26 +00:00
2003-12-26 23:03:21 +00:00
return 1 ; // Everything went ok.
}
2004-09-17 18:18:04 +00:00
/**
* Moves a file to a new location .
* - Checks if $source and $dest are valid and readable / writable .
* - Performs a file move if $source is not equal to $dest .
* - If file already exists in $dest either the call will error out , replace the
* file or rename the file based on the $replace parameter .
*
* @ param $source A string specifying the file location of the original file .
* This parameter will contain the resulting destination filename in case of
* success .
* @ param $dest A string containing the directory $source should be copied to .
* @ param $replace Replace behavior when the destination file already exists .
* - FILE_EXISTS_REPLACE - Replace the existing file
* - FILE_EXISTS_RENAME - Append _ { incrementing number } until the filename is unique
* - FILE_EXISTS_ERROR - Do nothing and return false .
* @ return True for success , false for failure .
*/
function file_move ( & $source , $dest = 0 , $replace = FILE_EXISTS_RENAME ) {
2004-08-17 21:35:26 +00:00
$path_original = is_object ( $source ) ? $source -> filepath : $source ;
2003-12-26 23:03:21 +00:00
if ( file_copy ( $source , $dest , $replace )) {
2004-08-17 21:35:26 +00:00
$path_current = is_object ( $source ) ? $source -> filepath : $source ;
if ( $path_original == $path_current || file_delete ( $path_original )) {
2003-12-26 23:03:21 +00:00
return 1 ;
}
2005-05-05 22:22:46 +00:00
drupal_set_message ( t ( 'The removal of the original file %file has failed.' , array ( '%file' => theme ( 'placeholder' , $source ))), 'error' );
2003-12-26 23:03:21 +00:00
}
return 0 ;
}
2004-08-17 21:35:26 +00:00
function file_create_filename ( $basename , $directory ) {
2004-08-24 19:21:30 +00:00
$dest = $directory . '/' . $basename ;
2004-08-17 21:35:26 +00:00
if ( file_exists ( $dest )) {
// Destination file already exists, generate an alternative.
if ( $pos = strrpos ( $basename , '.' )) {
$name = substr ( $basename , 0 , $pos );
$ext = substr ( $basename , $pos );
}
else {
$name = $basename ;
}
$counter = 0 ;
do {
2004-08-24 19:21:30 +00:00
$dest = $directory . '/' . $name . '_' . $counter ++ . $ext ;
2004-08-17 21:35:26 +00:00
} while ( file_exists ( $dest ));
}
return $dest ;
}
2003-12-27 19:21:48 +00:00
function file_delete ( $path ) {
if ( is_file ( $path )) {
2004-08-17 21:35:26 +00:00
return unlink ( $path );
2003-12-27 19:21:48 +00:00
}
2003-12-26 23:03:21 +00:00
}
/**
* Saves a file upload to a new location . The source file is validated as a
* proper upload and handled as such .
*
* @ param $source A string specifying the name of the upload field to save .
* This parameter will contain the resulting destination filename in case of
* success .
* @ param $dest A string containing the directory $source should be copied to ,
* will use the temporary directory in case no other value is set .
2004-01-02 23:12:44 +00:00
* @ param $replace A boolean , set to true if the destination should be replaced
2003-12-26 23:03:21 +00:00
* when in use , but when false append a _X to the filename .
* @ return An object containing file info or 0 in case of error .
*/
2004-09-17 18:18:04 +00:00
function file_save_upload ( $source , $dest = 0 , $replace = FILE_EXISTS_RENAME ) {
2003-12-26 23:03:21 +00:00
// Make sure $source exists in $_FILES.
if ( $file = file_check_upload ( $source )) {
2003-12-27 19:21:48 +00:00
if ( ! $dest ) {
2005-11-12 09:23:50 +00:00
$dest = file_directory_temp ();
2003-12-26 23:03:21 +00:00
$temporary = 1 ;
2004-08-17 21:35:26 +00:00
if ( is_file ( $file -> filepath )) {
2003-12-26 23:03:21 +00:00
// If this file was uploaded by this user before replace the temporary copy.
2006-02-22 19:16:37 +00:00
$replace = FILE_EXISTS_REPLACE ;
2003-12-26 23:03:21 +00:00
}
}
// Check for file upload errors.
switch ( $file -> error ) {
2005-05-05 22:22:46 +00:00
case 0 : // UPLOAD_ERR_OK: File uploaded successfully
2004-02-27 11:25:13 +00:00
break ;
2005-05-05 22:22:46 +00:00
case 1 : // UPLOAD_ERR_INI_SIZE: File size exceeded php.ini value
case 2 : // UPLOAD_ERR_FORM_SIZE: File size exceeded MAX_FILE_SIZE form value
drupal_set_message ( t ( 'The file %file could not be saved, because it exceeds the maximum allowed size for uploads.' , array ( '%file' => theme ( 'placeholder' , $source ))), 'error' );
2004-02-27 11:25:13 +00:00
return 0 ;
2005-05-05 22:22:46 +00:00
case 3 : // UPLOAD_ERR_PARTIAL: File was only partially uploaded
case 4 : // UPLOAD_ERR_NO_FILE: No file was uploaded
drupal_set_message ( t ( 'The file %file could not be saved, because the upload did not complete.' , array ( '%file' => theme ( 'placeholder' , $source ))), 'error' );
2003-12-26 23:03:21 +00:00
return 0 ;
2004-02-27 11:25:13 +00:00
default : // Unknown error
2005-05-05 22:22:46 +00:00
drupal_set_message ( t ( 'The file %file could not be saved. An unknown error has occurred.' , array ( '%file' => theme ( 'placeholder' , $source ))), 'error' );
2003-12-26 23:03:21 +00:00
return 0 ;
}
2003-12-27 19:21:48 +00:00
unset ( $_SESSION [ 'file_uploads' ][ is_object ( $source ) ? $source -> source : $source ]);
2003-12-26 23:03:21 +00:00
if ( file_move ( $file , $dest , $replace )) {
if ( $temporary ) {
2004-08-17 21:35:26 +00:00
$_SESSION [ 'file_uploads' ][ is_object ( $source ) ? $source -> source : $source ] = $file ;
2003-12-26 23:03:21 +00:00
}
return $file ;
}
return 0 ;
}
return 0 ;
}
2004-06-04 18:00:48 +00:00
/**
* Save a string to the specified destination
*
* @ param $data A string containing the contents of the file
* @ param $dest A string containing the destination location
*
* @ return A string containing the resulting filename or 0 on error
*/
2004-10-26 20:57:34 +00:00
function file_save_data ( $data , $dest , $replace = FILE_EXISTS_RENAME ) {
2005-11-12 09:23:50 +00:00
$temp = file_directory_temp ();
2004-06-04 18:00:48 +00:00
$file = tempnam ( $temp , 'file' );
2004-08-17 21:35:26 +00:00
if ( ! $fp = fopen ( $file , 'wb' )) {
2005-05-05 22:22:46 +00:00
drupal_set_message ( t ( 'The file could not be created.' ), 'error' );
2004-06-04 18:00:48 +00:00
return 0 ;
}
fwrite ( $fp , $data );
fclose ( $fp );
2004-09-13 23:30:58 +00:00
if ( ! file_move ( $file , $dest , $replace )) {
2004-06-04 18:00:48 +00:00
return 0 ;
}
return $file ;
}
2003-12-26 23:03:21 +00:00
/**
* Transfer file using http to client . Pipes a file through Drupal to the
* client .
*
* @ param $source File to transfer .
* @ param $headers An array of http headers to send along with file .
*/
function file_transfer ( $source , $headers ) {
ob_end_clean ();
foreach ( $headers as $header ) {
2005-11-30 15:31:23 +00:00
// To prevent HTTP header injection, we delete new lines that are
// not followed by a space or a tab.
// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
$header = preg_replace ( '/\r?\n(?!\t| )/' , '' , $header );
2003-12-26 23:03:21 +00:00
header ( $header );
}
$source = file_create_path ( $source );
// Transfer file in 1024 byte chunks to save memory usage.
2005-05-06 09:31:45 +00:00
if ( $fd = fopen ( $source , 'rb' )) {
while ( ! feof ( $fd )) {
print fread ( $fd , 1024 );
}
fclose ( $fd );
}
else {
drupal_not_found ();
2003-12-26 23:03:21 +00:00
}
exit ();
}
/**
* Call modules to find out if a file is accessible for a given user .
*/
function file_download () {
$file = $_GET [ 'file' ];
if ( file_exists ( file_create_path ( $file ))) {
$list = module_list ();
foreach ( $list as $module ) {
$headers = module_invoke ( $module , 'file_download' , $file );
2006-01-18 19:18:30 +00:00
if ( is_array ( $headers )) {
2003-12-26 23:03:21 +00:00
file_transfer ( $file , $headers );
}
2006-01-18 19:18:30 +00:00
elseif ( $headers == - 1 ) {
drupal_access_denied ();
}
2003-12-26 23:03:21 +00:00
}
}
2003-12-27 14:28:23 +00:00
drupal_not_found ();
2003-12-26 23:03:21 +00:00
}
/**
2004-11-24 22:44:01 +00:00
* Finds all files that match a given mask in a given
* directory .
2004-09-17 18:18:04 +00:00
*
2004-11-24 22:44:01 +00:00
* @ param $dir
* The base directory for the scan .
* @ param $mask
* The regular expression of the files to find .
* @ param $nomask
* An array of files / directories to ignore .
* @ param $callback
* The callback function to call for each match .
* @ param $recurse
* When TRUE , the directory scan will recurse the entire tree
* starting at the provided directory .
* @ param $key
* The key to be used for the returned array of files . Possible
* values are " filename " , for the path starting with $dir ,
* " basename " , for the basename of the file , and " name " for the name
* of the file without an extension .
2005-03-08 22:06:11 +00:00
* @ param $min_depth
* Minimum depth of directories to return files from .
* @ param $depth
2005-03-31 21:18:08 +00:00
* Current depth of recursion . This parameter is only used internally and should not be passed .
2004-11-24 22:44:01 +00:00
*
* @ return
* An associative array ( keyed on the provided key ) of objects with
* " path " , " basename " , and " name " members corresponding to the
* matching files .
2003-12-26 23:03:21 +00:00
*/
2005-03-08 22:10:26 +00:00
function file_scan_directory ( $dir , $mask , $nomask = array ( '.' , '..' , 'CVS' ), $callback = 0 , $recurse = TRUE , $key = 'filename' , $min_depth = 0 , $depth = 0 ) {
2004-11-24 22:44:01 +00:00
$key = ( in_array ( $key , array ( 'filename' , 'basename' , 'name' )) ? $key : 'filename' );
2003-12-26 23:03:21 +00:00
$files = array ();
2004-11-24 22:44:01 +00:00
2003-12-26 23:03:21 +00:00
if ( is_dir ( $dir ) && $handle = opendir ( $dir )) {
while ( $file = readdir ( $handle )) {
if ( ! in_array ( $file , $nomask )) {
2004-09-17 18:18:04 +00:00
if ( is_dir ( " $dir / $file " ) && $recurse ) {
2005-03-08 22:10:26 +00:00
$files = array_merge ( $files , file_scan_directory ( " $dir / $file " , $mask , $nomask , $callback , $recurse , $key , $min_depth , $depth + 1 ));
2003-12-26 23:03:21 +00:00
}
2005-03-08 22:06:11 +00:00
elseif ( $depth >= $min_depth && ereg ( $mask , $file )) {
2004-11-24 22:44:01 +00:00
$filename = " $dir / $file " ;
$basename = basename ( $file );
$name = substr ( $basename , 0 , strrpos ( $basename , '.' ));
$files [ $$key ] = new stdClass ();
$files [ $$key ] -> filename = $filename ;
$files [ $$key ] -> basename = $basename ;
$files [ $$key ] -> name = $name ;
2003-12-26 23:03:21 +00:00
if ( $callback ) {
2004-11-24 22:44:01 +00:00
$callback ( $filename );
2003-12-26 23:03:21 +00:00
}
}
}
}
2004-11-24 22:44:01 +00:00
2003-12-26 23:03:21 +00:00
closedir ( $handle );
}
2004-11-24 22:44:01 +00:00
2003-12-26 23:03:21 +00:00
return $files ;
}
2005-11-12 09:23:50 +00:00
/**
* Determine the default temporary directory .
*/
function file_directory_temp () {
$temporary_directory = variable_get ( 'file_directory_temp' , NULL );
if ( is_null ( $temporary_directory )) {
$directories = array ();
// Has PHP been set with an upload_tmp_dir?
if ( ini_get ( 'upload_tmp_dir' )) {
$directories [] = ini_get ( 'upload_tmp_dir' );
}
// Operating system specific dirs.
if ( substr ( PHP_OS , 0 , 3 ) == 'WIN' ) {
$directories [] = 'c:\\windows\\temp' ;
$directories [] = 'c:\\winnt\\temp' ;
$path_delimiter = '\\' ;
}
else {
$directories [] = '/tmp' ;
$path_delimiter = '/' ;
}
foreach ( $directories as $directory ) {
if ( ! $temporary_directory && is_dir ( $directory )) {
$temporary_directory = $directory ;
}
}
// if a directory has been found, use it, otherwise default to 'files/tmp' or 'files\\tmp';
$temporary_directory = $temporary_directory ? $temporary_directory : file_directory_path () . $path_delimiter . 'tmp' ;
variable_set ( 'file_directory_temp' , $temporary_directory );
}
return $temporary_directory ;
}
/**
* Determine the default 'files' directory .
*/
function file_directory_path () {
return variable_get ( 'file_directory_path' , 'files' );
}
2005-08-25 21:14:17 +00:00