From d118ab71e6aa4f300ba6e42663d13a63a2323122 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 21 Dec 2020 21:37:10 +0000 Subject: files_ng: implement directory and bulk file download --- Zotlabs/Module/Attach.php | 128 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 110 insertions(+), 18 deletions(-) (limited to 'Zotlabs/Module/Attach.php') diff --git a/Zotlabs/Module/Attach.php b/Zotlabs/Module/Attach.php index 490d5edd0..86183056c 100644 --- a/Zotlabs/Module/Attach.php +++ b/Zotlabs/Module/Attach.php @@ -1,46 +1,100 @@ false]; + + $channel_id = ((x($_REQUEST, 'channel_id')) ? intval($_REQUEST['channel_id']) : 0); + $channel = channelx_by_n($channel_id); + + if (! $channel) { + notice(t('Channel not found.') . EOL); + return; + } + + $zip_dir = 'store/[data]/' . $channel['channel_address'] . '/tmp'; + if (! is_dir($zip_dir)) + mkdir($zip_dir, STORAGE_DEFAULT_PERMISSIONS, true); + + $rnd = random_string(10); + + $zip_file = 'download_' . $rnd . '.zip'; + $zip_path = $zip_dir . '/' . $zip_file; + + $zip = new ZipArchive(); -class Attach extends \Zotlabs\Web\Controller { + if ($zip->open($zip_path, ZipArchive::CREATE) === true) { + + $filename = self::zip_archive_handler($zip, $attach_ids); + + $zip->close(); + + header('Content-Type: application/zip'); + header('Content-Disposition: attachment; filename="' . $filename . '"'); + header('Content-Length: ' . filesize($zip_path)); + + $istream = fopen($zip_path, 'rb'); + $ostream = fopen('php://output', 'wb'); + + if ($istream && $ostream) { + pipe_streams($istream,$ostream); + fclose($istream); + fclose($ostream); + } + + unlink($zip_path); + killme(); + } + } + } + + function get() { - function init() { - if(argc() < 2) { notice( t('Item not available.') . EOL); return; } - + $r = attach_by_hash(argv(1),get_observer_hash(),((argc() > 2) ? intval(argv(2)) : 0)); - + if(! $r['success']) { notice( $r['message'] . EOL); return; } - + $c = q("select channel_address from channel where channel_id = %d limit 1", intval($r['data']['uid']) ); - + if(! $c) return; - - + + $unsafe_types = array('text/html','text/css','application/javascript'); - + if(in_array($r['data']['filetype'],$unsafe_types) && (! channel_codeallowed($r['data']['uid']))) { - header('Content-type: text/plain'); + header('Content-Type: text/plain'); } else { - header('Content-type: ' . $r['data']['filetype']); + header('Content-Type: ' . $r['data']['filetype']); } - - header('Content-disposition: attachment; filename="' . $r['data']['filename'] . '"'); + + header('Content-Disposition: attachment; filename="' . $r['data']['filename'] . '"'); if(intval($r['data']['os_storage'])) { - $fname = dbunescbin($r['data']['content']); + $fname = $r['data']['content']; if(strpos($fname,'store') !== false) $istream = fopen($fname,'rb'); else @@ -53,9 +107,47 @@ class Attach extends \Zotlabs\Web\Controller { } } else - echo dbunescbin($r['data']['content']); + echo $r['data']['content']; killme(); - + + } + + function zip_archive_handler($zip, $attach_ids, $pass = 1) { + + $observer_hash = get_observer_hash(); + $single = ((count($attach_ids) == 1) ? true : false); + $filename = 'download.zip'; + + foreach($attach_ids as $attach_id) { + + $r = attach_by_id($attach_id, $observer_hash); + + if (! $r['success']) { + continue; + } + + if ($r['data']['is_dir'] && $single && $pass === 1) + $filename = $r['data']['filename'] . '.zip'; + + if ($r['data']['is_dir']) { + $zip->addEmptyDir($r['data']['display_path']); + + $d = q("SELECT id FROM attach WHERE folder = '%s'", + dbesc($r['data']['hash']) + ); + + $attach_ids = ids_to_array($d); + self::zip_archive_handler($zip, $attach_ids, $observer_hash, $pass++); + } + else { + $file_path = $r['data']['content']; + $file_name = $r['data']['display_path']; + $zip->addFile($file_path, $file_name); + } + + } + + return $filename; } - + } -- cgit v1.2.3