mirror of
https://github.com/DirectoryLister/DirectoryLister.git
synced 2025-09-01 18:03:29 +02:00
Allow to download directories as zip files
The feature adds a button to download all files in current directory as zip archive. For this function to work it is required to have 'zip' utility available on the server. To enable this function set the 'zip_dirs' option to 'true' in configuration file (it is disabled by default). By default the zip is created 'on-the-fly' and streamed to client, without any temporary file. This behaviour can be changed by setting 'zip_stream' configuration option to false. It is also possible to choose compression level for zip files - see 'zip_compression_level' configuration option. The default value is zero for perfomance reasons. The 'zip_disable' option allows to disable zip downloading for particular set of directories. It is works much the same as 'hidden_files' option. TODO: When zip is created the script tries to exclude files with respect to 'hidden files' option. But it doesn't do it very well - for example, if 'hidden_files' have 'resources/*' entry, then it will exclude the contents of 'resources' directory on any subdirectory, not just at the root level.
This commit is contained in:
@@ -20,6 +20,12 @@
|
||||
die($data);
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['zip'])) {
|
||||
$dirArray = $lister->zipDirectory($_GET['zip']);
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
// Initialize the directory array
|
||||
if (isset($_GET['dir'])) {
|
||||
@@ -42,3 +48,5 @@
|
||||
} else {
|
||||
die('ERROR: Failed to initialize theme');
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -61,6 +61,81 @@ class DirectoryLister {
|
||||
$this->_themeName = $this->_config['theme_name'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* If it is allowed to zip whole directories
|
||||
*
|
||||
* @param string $directory Relative path of directory to list
|
||||
* @return true or false
|
||||
* @access public
|
||||
*/
|
||||
public function isZipEnabled() {
|
||||
foreach ($this->_config['zip_disable'] as $disabledPath) {
|
||||
if (fnmatch($disabledPath, $this->_directory)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $this->_config['zip_dirs'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates zipfile of directory
|
||||
*
|
||||
* @param string $directory Relative path of directory to list
|
||||
* @access public
|
||||
*/
|
||||
public function zipDirectory($directory) {
|
||||
if ($this->_config['zip_dirs'])
|
||||
{
|
||||
// Cleanup directory path
|
||||
$directory = $this->setDirectoryPath($directory);
|
||||
|
||||
if ($directory != '.' && $this->_isHidden($directory)){
|
||||
echo "Access denied.";
|
||||
}
|
||||
|
||||
$filename_no_ext = basename("$directory");
|
||||
if ( $directory == '.' )
|
||||
{
|
||||
$filename_no_ext = "Home";
|
||||
}
|
||||
|
||||
// We deliver a zip file
|
||||
header("Content-Type: archive/zip");
|
||||
// Filename for the browser to save the zip file
|
||||
header("Content-Disposition: attachment; filename=\"$filename_no_ext".".zip\"");
|
||||
//change directory so the zip file doesnt have a tree structure in it.
|
||||
chdir($directory);
|
||||
|
||||
// TODO: Probably we have to parse exclude list more carefully
|
||||
$exclude_list = implode(" ", array_merge($this->_config['hidden_files'],array('index.php')));
|
||||
$exclude_list = str_replace("*", "\*", $exclude_list);
|
||||
|
||||
if ($this->_config['zip_stream'])
|
||||
{
|
||||
// zip the stuff (dir and all in there) into the streamed zip file
|
||||
$stream = popen( "/usr/bin/zip -".$this->_config['zip_compression_level']." -r -q - * -x ".$exclude_list, "r" );
|
||||
if( $stream )
|
||||
{
|
||||
fpassthru( $stream );
|
||||
fclose( $stream );
|
||||
}
|
||||
} else {
|
||||
// zip the stuff (dir and all in there) into the tmp_zip file
|
||||
exec('zip -'.$this->_config['zip_compression_level'].' -r '.$tmp_zip.' * -x '.$exclude_list);
|
||||
// get a tmp name for the .zip
|
||||
$tmp_zip = tempnam ("tmp", "tempzip") . ".zip";
|
||||
// calc the length of the zip. it is needed for the progress bar of the browser
|
||||
$filesize = filesize($tmp_zip);
|
||||
header("Content-Length: $filesize");
|
||||
// deliver the zip file
|
||||
$fp = fopen("$tmp_zip","r");
|
||||
echo fpassthru($fp);
|
||||
// clean up the tmp zip file
|
||||
unlink($tmp_zip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -341,6 +416,17 @@ class DirectoryLister {
|
||||
return $this->_directory;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get directory path variable
|
||||
*
|
||||
* @return string Sanitizd path to directory
|
||||
* @access public
|
||||
*/
|
||||
public function getDirectoryPath() {
|
||||
return $this->_directory;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@@ -34,6 +34,17 @@ return array(
|
||||
// Custom sort order
|
||||
'reverse_sort' => array(
|
||||
// 'path/to/folder'
|
||||
)
|
||||
),
|
||||
|
||||
// Allow to download directories as zip files
|
||||
'zip_dirs' => false,
|
||||
// Stream zip file content directly to the client, without any temporary file
|
||||
'zip_stream' => true,
|
||||
'zip_compression_level' => 0,
|
||||
// Disable zip downloads for particular directories
|
||||
'zip_disable' => array(
|
||||
'.' // - disable for root directory by default
|
||||
// 'path/to/folder'
|
||||
),
|
||||
|
||||
);
|
||||
|
@@ -47,6 +47,11 @@
|
||||
</p>
|
||||
|
||||
<div class="navbar-right">
|
||||
<?php if ($lister->isZipEnabled()): ?>
|
||||
<ul id="page-top-download-all" class="nav navbar-nav">
|
||||
<li><a href="?zip=<?php echo $lister->getDirectoryPath() ?>" id="download-all-link"><i class="fa fa-download fa-lg"></i></a></li>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
<ul id="page-top-nav" class="nav navbar-nav">
|
||||
<li><a href="javascript:void(0)" id="page-top-link"><i class="fa fa-arrow-circle-up fa-lg"></i></a></li>
|
||||
</ul>
|
||||
|
Reference in New Issue
Block a user