2010-03-10 15:03:40 +03:00
< ? php
/**
* ownCloud
*
2010-05-04 00:26:34 +04:00
* @ author Frank Karlitschek
2012-05-26 21:14:24 +04:00
* @ copyright 2012 Frank Karlitschek frank @ owncloud . org
2010-05-04 00:26:34 +04:00
*
2010-03-10 15:03:40 +03:00
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
2010-05-04 00:26:34 +04:00
* License as published by the Free Software Foundation ; either
2010-03-10 15:03:40 +03:00
* version 3 of the License , or any later version .
2010-05-04 00:26:34 +04:00
*
2010-03-10 15:03:40 +03:00
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details .
2010-05-04 00:26:34 +04:00
*
2011-02-09 17:50:27 +03:00
* You should have received a copy of the GNU Affero General Public
2010-03-10 15:03:40 +03:00
* License along with this library . If not , see < http :// www . gnu . org / licenses />.
2010-05-04 00:26:34 +04:00
*
2010-03-10 15:03:40 +03:00
*/
/**
* Class for fileserver access
*
*/
2011-07-29 23:36:03 +04:00
class OC_Files {
2010-05-08 00:50:59 +04:00
static $tmpFiles = array ();
2010-04-25 16:21:04 +04:00
2012-09-21 15:30:39 +04:00
/**
* get the filesystem info
2012-10-21 01:54:37 +04:00
* @ param string $path
2012-09-21 15:30:39 +04:00
* @ return array
*
* returns an associative array with the following keys :
* - size
* - mtime
* - mimetype
* - encrypted
* - versioned
*/
public static function getFileInfo ( $path ) {
2012-10-21 04:12:58 +04:00
$path = \OC\Files\Filesystem :: normalizePath ( $path );
/**
* @ var \OC\Files\Storage\Storage $storage
* @ var string $path
*/
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $path );
$cache = $storage -> getCache ();
$data = $cache -> get ( $internalPath );
if ( $data [ 'mimetype' ] === 'httpd/unix-directory' ){
//add the sizes of other mountpoints to the folder
$mountPoints = \OC\Files\Filesystem :: getMountPoints ( $path );
foreach ( $mountPoints as $mountPoint ){
$subStorage = \OC\Files\Filesystem :: getStorage ( $mountPoint );
$subCache = $subStorage -> getCache ();
$rootEntry = $subCache -> get ( '' );
$data [ 'size' ] += $rootEntry [ 'size' ];
2012-10-09 01:37:50 +04:00
}
2012-09-21 15:30:39 +04:00
}
2012-10-21 04:12:58 +04:00
return $data ;
2012-09-21 15:30:39 +04:00
}
2010-04-25 16:21:04 +04:00
/**
* get the content of a directory
2012-10-21 04:12:58 +04:00
* @ param string $directory path under datadirectory
* @ return array
2010-04-25 16:21:04 +04:00
*/
2012-09-07 17:22:01 +04:00
public static function getDirectoryContent ( $directory , $mimetype_filter = '' ) {
2012-10-21 04:12:58 +04:00
$path = \OC\Files\Filesystem :: normalizePath ( $directory );
/**
* @ var \OC\Files\Storage\Storage $storage
* @ var string $path
*/
list ( $storage , $internalPath ) = \OC\Files\Filesystem :: resolvePath ( $path );
$cache = $storage -> getCache ();
$files = $cache -> getFolderContents ( $internalPath ); //TODO: mimetype_filter
//add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders
$mountPoints = \OC\Files\Filesystem :: getMountPoints ( $directory );
$dirLength = strlen ( $path );
foreach ( $mountPoints as $mountPoint ){
$subStorage = \OC\Files\Filesystem :: getStorage ( $mountPoint );
$subCache = $subStorage -> getCache ();
$rootEntry = $subCache -> get ( '' );
$relativePath = trim ( substr ( $mountPoint , $dirLength ), '/' );
if ( $pos = strpos ( $relativePath , '/' )){ //mountpoint inside subfolder add size to the correct folder
$entryName = substr ( $relativePath , 0 , $pos );
foreach ( $files as & $entry ){
if ( $entry [ 'name' ] === $entryName ){
$entry [ 'size' ] += $rootEntry [ 'size' ];
}
2012-07-26 00:33:08 +04:00
}
2012-10-21 04:12:58 +04:00
} else { //mountpoint in this folder, add an entry for it
$rootEntry [ 'name' ] = $relativePath ;
$files [] = $rootEntry ;
2012-07-11 02:56:22 +04:00
}
2010-04-25 16:21:04 +04:00
}
2012-10-21 04:12:58 +04:00
2012-01-31 19:33:47 +04:00
usort ( $files , " fileCmp " ); //TODO: remove this once ajax is merged
2011-11-09 21:41:57 +04:00
return $files ;
2010-04-25 16:21:04 +04:00
}
2012-09-25 19:57:54 +04:00
public static function searchByMime ( $mimetype_filter ) {
$files = array ();
$dirs_to_check = array ( '' );
while ( ! empty ( $dirs_to_check )) {
// get next subdir to check
$dir = array_pop ( $dirs_to_check );
$dir_content = self :: getDirectoryContent ( $dir , $mimetype_filter );
foreach ( $dir_content as $file ) {
if ( $file [ 'type' ] == 'file' ) {
$files [] = $dir . '/' . $file [ 'name' ];
}
else {
$dirs_to_check [] = $dir . '/' . $file [ 'name' ];
}
}
}
return $files ;
}
2010-04-25 16:21:04 +04:00
/**
* return the content of a file or return a zip file containning multiply files
*
* @ param dir $dir
2011-04-18 17:02:10 +04:00
* @ param file $file ; seperated list of files to download
2012-05-25 02:48:10 +04:00
* @ param boolean $only_header ; boolean to only send header of the request
2010-04-25 16:21:04 +04:00
*/
2012-09-07 17:22:01 +04:00
public static function get ( $dir , $files , $only_header = false ) {
if ( strpos ( $files , ';' )) {
2010-05-02 01:09:36 +04:00
$files = explode ( ';' , $files );
}
2011-06-19 17:08:28 +04:00
2012-09-07 17:22:01 +04:00
if ( is_array ( $files )) {
2012-03-19 14:56:02 +04:00
self :: validateZipDownload ( $dir , $files );
2012-03-16 19:25:15 +04:00
$executionTime = intval ( ini_get ( 'max_execution_time' ));
set_time_limit ( 0 );
2010-04-25 16:21:04 +04:00
$zip = new ZipArchive ();
2012-04-14 00:59:47 +04:00
$filename = OC_Helper :: tmpFile ( '.zip' );
2012-10-21 04:12:58 +04:00
if ( $zip -> open ( $filename , ZIPARCHIVE :: CREATE | ZIPARCHIVE :: OVERWRITE ) !== true ) {
2010-04-25 16:21:04 +04:00
exit ( " cannot open < $filename > \n " );
}
2012-09-07 17:22:01 +04:00
foreach ( $files as $file ) {
2010-05-08 00:50:59 +04:00
$file = $dir . '/' . $file ;
2012-10-10 15:18:36 +04:00
if ( \OC\Files\Filesystem :: is_file ( $file )) {
$tmpFile = OC_F\OC\Files\Filesystemilesystem :: toTmpFile ( $file );
2010-05-08 00:50:59 +04:00
self :: $tmpFiles [] = $tmpFile ;
$zip -> addFile ( $tmpFile , basename ( $file ));
2012-10-10 15:18:36 +04:00
} elseif ( \OC\Files\Filesystem :: is_dir ( $file )) {
2011-09-18 22:57:05 +04:00
self :: zipAddDir ( $file , $zip );
2010-04-25 16:21:04 +04:00
}
}
$zip -> close ();
2012-03-16 19:25:15 +04:00
set_time_limit ( $executionTime );
2012-10-10 15:18:36 +04:00
} elseif ( \OC\Files\Filesystem :: is_dir ( $dir . '/' . $files )) {
2012-03-19 14:56:02 +04:00
self :: validateZipDownload ( $dir , $files );
2012-03-16 19:25:15 +04:00
$executionTime = intval ( ini_get ( 'max_execution_time' ));
set_time_limit ( 0 );
2010-04-25 16:21:04 +04:00
$zip = new ZipArchive ();
2012-04-14 00:59:47 +04:00
$filename = OC_Helper :: tmpFile ( '.zip' );
2012-10-21 04:12:58 +04:00
if ( $zip -> open ( $filename , ZIPARCHIVE :: CREATE | ZIPARCHIVE :: OVERWRITE ) !== true ) {
2010-04-25 16:21:04 +04:00
exit ( " cannot open < $filename > \n " );
}
2010-05-08 00:50:59 +04:00
$file = $dir . '/' . $files ;
2011-09-18 22:57:05 +04:00
self :: zipAddDir ( $file , $zip );
2010-04-25 16:21:04 +04:00
$zip -> close ();
2012-03-16 19:25:15 +04:00
set_time_limit ( $executionTime );
2010-04-25 16:21:04 +04:00
} else {
$zip = false ;
2010-05-08 00:50:59 +04:00
$filename = $dir . '/' . $files ;
2010-04-25 16:21:04 +04:00
}
2012-05-05 18:49:22 +04:00
@ ob_end_clean ();
2012-10-21 02:13:16 +04:00
if ( $zip or \OC\Files\Filesystem :: isReadable ( $filename )) {
2011-08-12 14:03:59 +04:00
header ( 'Content-Disposition: attachment; filename="' . basename ( $filename ) . '"' );
2010-06-25 15:24:27 +04:00
header ( 'Content-Transfer-Encoding: binary' );
2012-02-14 02:48:05 +04:00
OC_Response :: disableCaching ();
2012-09-07 17:22:01 +04:00
if ( $zip ) {
2012-05-15 13:57:24 +04:00
ini_set ( 'zlib.output_compression' , 'off' );
2010-09-26 21:09:16 +04:00
header ( 'Content-Type: application/zip' );
2010-07-07 14:30:30 +04:00
header ( 'Content-Length: ' . filesize ( $filename ));
} else {
2012-10-10 15:18:36 +04:00
header ( 'Content-Type: ' . \OC\Files\Filesystem :: getMimeType ( $filename ));
2010-07-07 14:30:30 +04:00
}
2012-10-10 15:18:36 +04:00
} elseif ( $zip or ! \OC\Files\Filesystem :: file_exists ( $filename )) {
2010-06-25 15:24:27 +04:00
header ( " HTTP/1.0 404 Not Found " );
2011-07-29 23:36:03 +04:00
$tmpl = new OC_Template ( '' , '404' , 'guest' );
2011-04-18 15:16:32 +04:00
$tmpl -> assign ( 'file' , $filename );
$tmpl -> printPage ();
2010-06-25 15:24:27 +04:00
} else {
header ( " HTTP/1.0 403 Forbidden " );
die ( '403 Forbidden' );
2010-05-08 00:50:59 +04:00
}
2012-09-07 17:22:01 +04:00
if ( $only_header ) {
2012-05-25 02:48:10 +04:00
if ( ! $zip )
2012-10-10 15:18:36 +04:00
header ( " Content-Length: " . \OC\Files\Filesystem :: filesize ( $filename ));
2012-05-25 02:48:10 +04:00
return ;
}
2012-09-07 17:22:01 +04:00
if ( $zip ) {
2012-05-01 22:32:13 +04:00
$handle = fopen ( $filename , 'r' );
if ( $handle ) {
$chunkSize = 8 * 1024 ; // 1 MB chunks
while ( ! feof ( $handle )) {
echo fread ( $handle , $chunkSize );
flush ();
}
}
2010-06-25 15:24:27 +04:00
unlink ( $filename );
} else {
2012-10-10 15:18:36 +04:00
\OC\Files\Filesystem :: readfile ( $filename );
2010-06-25 15:24:27 +04:00
}
2012-09-07 17:22:01 +04:00
foreach ( self :: $tmpFiles as $tmpFile ) {
if ( file_exists ( $tmpFile ) and is_file ( $tmpFile )) {
2010-05-08 00:50:59 +04:00
unlink ( $tmpFile );
}
2010-04-25 16:21:04 +04:00
}
}
2010-05-04 00:26:34 +04:00
2012-09-07 17:22:01 +04:00
public static function zipAddDir ( $dir , $zip , $internalDir = '' ) {
2011-09-18 22:57:05 +04:00
$dirname = basename ( $dir );
$zip -> addEmptyDir ( $internalDir . $dirname );
$internalDir .= $dirname .= '/' ;
$files = OC_Files :: getdirectorycontent ( $dir );
2012-09-07 17:22:01 +04:00
foreach ( $files as $file ) {
2011-09-18 22:57:05 +04:00
$filename = $file [ 'name' ];
$file = $dir . '/' . $filename ;
2012-10-10 15:18:36 +04:00
if ( \OC\Files\Filesystem :: is_file ( $file )) {
$tmpFile = \OC\Files\Filesystem :: toTmpFile ( $file );
2011-09-18 22:57:05 +04:00
OC_Files :: $tmpFiles [] = $tmpFile ;
$zip -> addFile ( $tmpFile , $internalDir . $filename );
2012-10-10 15:18:36 +04:00
} elseif ( \OC\Files\Filesystem :: is_dir ( $file )) {
2011-09-18 22:57:05 +04:00
self :: zipAddDir ( $file , $zip , $internalDir );
}
}
}
2010-04-25 16:21:04 +04:00
/**
* move a file or folder
*
* @ param dir $sourceDir
* @ param file $source
* @ param dir $targetDir
* @ param file $target
*/
2012-09-07 17:22:01 +04:00
public static function move ( $sourceDir , $source , $targetDir , $target ) {
if ( OC_User :: isLoggedIn () && ( $sourceDir != '' || $source != 'Shared' )) {
2012-01-15 00:13:46 +04:00
$targetFile = self :: normalizePath ( $targetDir . '/' . $target );
$sourceFile = self :: normalizePath ( $sourceDir . '/' . $source );
2012-10-10 15:18:36 +04:00
return \OC\Files\Filesystem :: rename ( $sourceFile , $targetFile );
2012-06-29 17:23:04 +04:00
} else {
return false ;
2010-05-11 22:35:29 +04:00
}
}
2010-05-04 00:26:34 +04:00
2010-05-11 22:35:29 +04:00
/**
* copy a file or folder
*
* @ param dir $sourceDir
* @ param file $source
* @ param dir $targetDir
* @ param file $target
*/
2012-09-07 17:22:01 +04:00
public static function copy ( $sourceDir , $source , $targetDir , $target ) {
if ( OC_User :: isLoggedIn ()) {
2010-05-11 22:35:29 +04:00
$targetFile = $targetDir . '/' . $target ;
$sourceFile = $sourceDir . '/' . $source ;
2012-10-10 15:18:36 +04:00
return \OC\Files\Filesystem :: copy ( $sourceFile , $targetFile );
2010-04-25 16:21:04 +04:00
}
}
2010-05-04 00:26:34 +04:00
2010-04-25 16:21:04 +04:00
/**
* create a new file or folder
*
* @ param dir $dir
* @ param file $name
* @ param type $type
*/
2012-09-07 17:22:01 +04:00
public static function newFile ( $dir , $name , $type ) {
if ( OC_User :: isLoggedIn ()) {
2010-05-08 00:50:59 +04:00
$file = $dir . '/' . $name ;
2012-09-07 17:22:01 +04:00
if ( $type == 'dir' ) {
2012-10-10 15:18:36 +04:00
return \OC\Files\Filesystem :: mkdir ( $file );
2012-09-07 17:22:01 +04:00
} elseif ( $type == 'file' ) {
2012-10-10 15:18:36 +04:00
$fileHandle = \OC\Files\Filesystem :: fopen ( $file , 'w' );
2012-09-07 17:22:01 +04:00
if ( $fileHandle ) {
2010-05-11 22:35:29 +04:00
fclose ( $fileHandle );
return true ;
} else {
return false ;
}
2010-04-25 16:21:04 +04:00
}
}
}
2010-05-04 00:26:34 +04:00
2010-04-25 16:21:04 +04:00
/**
* deletes a file or folder
*
* @ param dir $dir
* @ param file $name
*/
2012-09-07 17:22:01 +04:00
public static function delete ( $dir , $file ) {
2012-06-04 12:42:09 +04:00
if ( OC_User :: isLoggedIn () && ( $dir != '' || $file != 'Shared' )) {
2010-05-08 00:50:59 +04:00
$file = $dir . '/' . $file ;
2012-10-10 15:18:36 +04:00
return \OC\Files\Filesystem :: unlink ( $file );
2010-04-25 16:21:04 +04:00
}
}
2010-05-04 00:26:34 +04:00
2012-03-16 19:25:15 +04:00
/**
* checks if the selected files are within the size constraint . If not , outputs an error page .
*
* @ param dir $dir
* @ param files $files
*/
2012-03-19 14:56:02 +04:00
static function validateZipDownload ( $dir , $files ) {
2012-03-21 16:05:15 +04:00
if ( ! OC_Config :: getValue ( 'allowZipDownload' , true )) {
2012-08-31 01:51:44 +04:00
$l = OC_L10N :: get ( 'lib' );
2012-03-19 14:56:02 +04:00
header ( " HTTP/1.0 409 Conflict " );
$tmpl = new OC_Template ( '' , 'error' , 'user' );
$errors = array (
array (
'error' => $l -> t ( 'ZIP download is turned off.' ),
'hint' => $l -> t ( 'Files need to be downloaded one by one.' ) . '<br/><a href="javascript:history.back()">' . $l -> t ( 'Back to Files' ) . '</a>' ,
)
);
$tmpl -> assign ( 'errors' , $errors );
$tmpl -> printPage ();
exit ;
}
2012-03-21 16:05:15 +04:00
$zipLimit = OC_Config :: getValue ( 'maxZipInputSize' , OC_Helper :: computerFileSize ( '800 MB' ));
2012-03-16 19:25:15 +04:00
if ( $zipLimit > 0 ) {
$totalsize = 0 ;
2012-09-07 17:22:01 +04:00
if ( is_array ( $files )) {
foreach ( $files as $file ) {
2012-10-10 15:18:36 +04:00
$totalsize += \OC\Files\Filesystem :: filesize ( $dir . '/' . $file );
2012-03-16 19:25:15 +04:00
}
} else {
2012-10-10 15:18:36 +04:00
$totalsize += \OC\Files\Filesystem :: filesize ( $dir . '/' . $files );
2012-03-16 19:25:15 +04:00
}
if ( $totalsize > $zipLimit ) {
2012-08-31 01:51:44 +04:00
$l = OC_L10N :: get ( 'lib' );
2012-03-16 19:25:15 +04:00
header ( " HTTP/1.0 409 Conflict " );
$tmpl = new OC_Template ( '' , 'error' , 'user' );
$errors = array (
array (
'error' => $l -> t ( 'Selected files too large to generate zip file.' ),
'hint' => 'Download the files in smaller chunks, seperately or kindly ask your administrator.<br/><a href="javascript:history.back()">' . $l -> t ( 'Back to Files' ) . '</a>' ,
)
);
$tmpl -> assign ( 'errors' , $errors );
$tmpl -> printPage ();
exit ;
}
}
}
2010-04-25 17:04:13 +04:00
/**
* try to detect the mime type of a file
*
2010-05-08 00:50:59 +04:00
* @ param string path
2010-04-25 17:04:13 +04:00
* @ return string guessed mime type
*/
2012-09-07 17:22:01 +04:00
static function getMimeType ( $path ) {
2012-10-10 15:18:36 +04:00
return \OC\Files\Filesystem :: getMimeType ( $path );
2010-04-25 20:27:02 +04:00
}
2011-03-02 01:20:16 +03:00
2010-07-07 14:30:30 +04:00
/**
* get a file tree
*
* @ param string path
* @ return array
*/
2012-09-07 17:22:01 +04:00
static function getTree ( $path ) {
2012-10-10 15:18:36 +04:00
return \OC\Files\Filesystem :: getTree ( $path );
2010-07-07 14:30:30 +04:00
}
2011-03-02 01:20:16 +03:00
2010-07-06 14:50:37 +04:00
/**
* pull a file from a remote server
* @ param string source
* @ param string token
* @ param string dir
* @ param string file
* @ return string guessed mime type
*/
2012-09-07 17:22:01 +04:00
static function pull ( $source , $token , $dir , $file ) {
2011-10-20 01:38:35 +04:00
$tmpfile = tempnam ( get_temp_dir (), 'remoteCloudFile' );
2010-07-06 14:50:37 +04:00
$fp = fopen ( $tmpfile , 'w+' );
$url = $source .= " /files/pull.php?token= $token " ;
$ch = curl_init ();
curl_setopt ( $ch , CURLOPT_URL , $url );
curl_setopt ( $ch , CURLOPT_FILE , $fp );
curl_exec ( $ch );
fclose ( $fp );
$info = curl_getinfo ( $ch );
$httpCode = $info [ 'http_code' ];
curl_close ( $ch );
2012-09-07 17:22:01 +04:00
if ( $httpCode == 200 or $httpCode == 0 ) {
2012-10-10 15:18:36 +04:00
\OC\Files\Filesystem :: fromTmpFile ( $tmpfile , $dir . '/' . $file );
2010-07-06 14:50:37 +04:00
return true ;
} else {
return false ;
}
}
2012-03-16 19:25:15 +04:00
2011-05-29 19:43:13 +04:00
/**
* set the maximum upload size limit for apache hosts using . htaccess
* @ param int size filesisze in bytes
2012-04-13 13:25:38 +04:00
* @ return false on failure , size on success
2011-05-29 19:43:13 +04:00
*/
2012-09-07 17:22:01 +04:00
static function setUploadLimit ( $size ) {
2012-04-13 13:25:38 +04:00
//don't allow user to break his config -- upper boundary
if ( $size > PHP_INT_MAX ) {
//max size is always 1 byte lower than computerFileSize returns
if ( $size > PHP_INT_MAX + 1 )
return false ;
$size -= 1 ;
} else {
$size = OC_Helper :: humanFileSize ( $size );
$size = substr ( $size , 0 , - 1 ); //strip the B
$size = str_replace ( ' ' , '' , $size ); //remove the space between the size and the postfix
}
2012-04-13 12:43:19 +04:00
2012-04-13 13:25:38 +04:00
//don't allow user to break his config -- broken or malicious size input
2012-04-13 12:43:19 +04:00
if ( intval ( $size ) == 0 ) {
return false ;
}
$htaccess = @ file_get_contents ( OC :: $SERVERROOT . '/.htaccess' ); //supress errors in case we don't have permissions for
if ( ! $htaccess ) {
return false ;
}
$phpValueKeys = array (
'upload_max_filesize' ,
'post_max_size'
);
foreach ( $phpValueKeys as $key ) {
$pattern = '/php_value ' . $key . ' (\S)*/' ;
$setting = 'php_value ' . $key . ' ' . $size ;
$hasReplaced = 0 ;
$content = preg_replace ( $pattern , $setting , $htaccess , 1 , $hasReplaced );
2012-10-21 04:12:58 +04:00
if ( $content !== null ) {
2012-04-13 12:43:19 +04:00
$htaccess = $content ;
}
if ( $hasReplaced == 0 ) {
$htaccess .= " \n " . $setting ;
}
}
2012-06-05 13:50:21 +04:00
//check for write permissions
if ( is_writable ( OC :: $SERVERROOT . '/.htaccess' )) {
file_put_contents ( OC :: $SERVERROOT . '/.htaccess' , $htaccess );
2012-08-29 10:38:33 +04:00
return OC_Helper :: computerFileSize ( $size );
2012-06-05 13:50:21 +04:00
} else { OC_Log :: write ( 'files' , 'Can\'t write upload limit to ' . OC :: $SERVERROOT . '/.htaccess. Please check the file permissions' , OC_Log :: WARN ); }
2012-08-29 10:38:33 +04:00
2012-04-13 12:43:19 +04:00
return false ;
2011-05-29 19:43:13 +04:00
}
2012-01-15 00:13:46 +04:00
/**
* normalize a path , removing any double , add leading / , etc
* @ param string $path
* @ return string
*/
2012-09-07 17:22:01 +04:00
static public function normalizePath ( $path ) {
2012-01-15 00:13:46 +04:00
$path = '/' . $path ;
$old = '' ;
2012-09-07 17:22:01 +04:00
while ( $old != $path ) { //replace any multiplicity of slashes with a single one
2012-01-15 00:13:46 +04:00
$old = $path ;
$path = str_replace ( '//' , '/' , $path );
}
return $path ;
}
2010-04-25 16:21:04 +04:00
}
2012-01-31 19:33:47 +04:00
2012-09-07 17:22:01 +04:00
function fileCmp ( $a , $b ) {
if ( $a [ 'type' ] == 'dir' and $b [ 'type' ] != 'dir' ) {
2012-01-31 19:33:47 +04:00
return - 1 ;
2012-09-07 17:22:01 +04:00
} elseif ( $a [ 'type' ] != 'dir' and $b [ 'type' ] == 'dir' ) {
2012-01-31 19:33:47 +04:00
return 1 ;
} else {
return strnatcasecmp ( $a [ 'name' ], $b [ 'name' ]);
}
}