forked from extern/egroupware
Add save as ZIP action
This commit is contained in:
parent
c281f19568
commit
a852eed949
@ -131,6 +131,13 @@ class filemanager_ui
|
||||
'disableClass' => 'isDir',
|
||||
'enabled' => 'javaScript:app.filemanager.is_multiple_allowed'
|
||||
),
|
||||
'saveaszip' => array(
|
||||
'caption' => lang('Save as ZIP'),
|
||||
'group' => $group,
|
||||
'allowOnMultiple' => true,
|
||||
'icon' => 'filesave',
|
||||
'postSubmit' => true
|
||||
),
|
||||
'edit' => array(
|
||||
'caption' => lang('Edit settings'),
|
||||
'group' => $group,
|
||||
@ -606,6 +613,9 @@ class filemanager_ui
|
||||
}
|
||||
return lang("Error while creating directory.");
|
||||
|
||||
case 'saveaszip':
|
||||
return egw_vfs::download_zip($selected);
|
||||
|
||||
default:
|
||||
list($action, $settings) = explode('_', $action, 2);
|
||||
switch($action)
|
||||
|
@ -1320,6 +1320,120 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
return '/webdav.php'.strtr($path,array('+' => '%2B',' ' => '%20','"' => '%22')).($force_download ? '?download' : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Download the given file list as a ZIP
|
||||
*
|
||||
* @param array $files
|
||||
*
|
||||
* @return undefined
|
||||
*/
|
||||
public static function download_zip(Array $files)
|
||||
{
|
||||
error_log(__METHOD__ . ': '.implode(',',$files));
|
||||
|
||||
// Create zip file
|
||||
$zip_file = tempnam($GLOBALS['egw_info']['server']['temp_dir'], 'zip');
|
||||
|
||||
$zip = new ZipArchive();
|
||||
$result = $zip->open($zip_file, ZipArchive::OVERWRITE);
|
||||
if($result !== TRUE)
|
||||
{
|
||||
throw new egw_exception("Cannot open zip file for writing.");
|
||||
}
|
||||
|
||||
// A nice name for the user
|
||||
$filename = $GLOBALS['egw_info']['server']['site_title'] . (count($files) == 1 ? '_'. self::basename($files[0]) : '') . '.zip';
|
||||
|
||||
// Go into directories, find them all
|
||||
$files = self::find($files);
|
||||
|
||||
// We need to remove them _after_ we're done
|
||||
$tempfiles = array();
|
||||
|
||||
// Give 1 second per file
|
||||
set_time_limit(count($files));
|
||||
|
||||
// Add files to archive
|
||||
foreach($files as $idx => &$addfile)
|
||||
{
|
||||
// Use relative paths inside zip, if we could
|
||||
//$_name = self::concat($directory,self::basename($addfile));
|
||||
$_name = $addfile;
|
||||
|
||||
// Don't go infinite with app entries
|
||||
if(self::is_link($addfile))
|
||||
{
|
||||
if(in_array($addfile, $links)) continue;
|
||||
$links[] = $addfile;
|
||||
}
|
||||
// Add directory - if empty, client app might not show it though
|
||||
if(self::is_dir($addfile))
|
||||
{
|
||||
$zip->addEmptyDir($addfile);
|
||||
}
|
||||
else if(self::is_readable($addfile))
|
||||
{
|
||||
// Copy to temp file, as ZipArchive fails to read VFS
|
||||
$temp = tempnam($GLOBALS['egw_info']['server']['temp_dir'], 'zip_');
|
||||
$from = egw_vfs::fopen($addfile,'r');
|
||||
$to = fopen($temp,'w');
|
||||
if(!stream_copy_to_stream($from,$to) || !$zip->addFile($temp, $_name))
|
||||
{
|
||||
unlink($temp);
|
||||
trigger_error("Could not add $addfile to ZIP file", E_USER_ERROR);
|
||||
continue;
|
||||
}
|
||||
// Keep temp file until _after_ zipping is done
|
||||
$tempfiles[] = $temp;
|
||||
|
||||
// Add comment in
|
||||
$props = self::propfind($addfile);
|
||||
if($props)
|
||||
{
|
||||
$comment = self::find_prop($props,'comment');
|
||||
if($comment)
|
||||
{
|
||||
$zip->setCommentName($_name, $prop['val']);
|
||||
}
|
||||
}
|
||||
$props = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Set a comment to help tell them apart
|
||||
$zip->setArchiveComment(lang('Created by %1', $GLOBALS['egw_info']['user']['account_lid']) . ' ' .egw_time::to());
|
||||
|
||||
// Record total for debug, not available after close()
|
||||
$total_files = $zip->numFiles;
|
||||
|
||||
$result = $zip->close();
|
||||
if(!$result || !filesize($zip_file))
|
||||
{
|
||||
error_log('close() result: '.array2string($result));
|
||||
return 'Error creating zip file';
|
||||
}
|
||||
|
||||
error_log("Total files: " . $total_files . " Peak memory to zip: " . self::hsize(memory_get_peak_usage(true)));
|
||||
|
||||
// Stop any buffering
|
||||
while(ob_get_level() > 0)
|
||||
ob_end_clean();
|
||||
|
||||
// Stream the file to the client
|
||||
header("Content-Type: application/zip");
|
||||
header("Content-Length: " . filesize($zip_file));
|
||||
header("Content-Disposition: attachment; filename=\"$filename\"");
|
||||
readfile($zip_file);
|
||||
|
||||
unlink($zip_file);
|
||||
foreach($tempfiles as $temp_file)
|
||||
{
|
||||
unlink($temp_file);
|
||||
}
|
||||
|
||||
common::egw_exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* We cache locks within a request, as HTTP_WebDAV_Server generates so many, that it can be a bottleneck
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user