2018-12-26 10:31:57 +01:00
|
|
|
<?php
|
|
|
|
/*****************************************************************************
|
|
|
|
* Download.php
|
|
|
|
* Contains the code to download an album.
|
|
|
|
*
|
|
|
|
* Kabuki CMS (C) 2013-2019, Aaron van Geffen
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2020-03-01 17:00:18 +01:00
|
|
|
class Download
|
2018-12-26 10:31:57 +01:00
|
|
|
{
|
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
// Ensure we're logged in at this point.
|
|
|
|
$user = Registry::get('user');
|
|
|
|
if (!$user->isLoggedIn())
|
|
|
|
throw new NotAllowedException();
|
|
|
|
|
2020-03-01 17:00:18 +01:00
|
|
|
if (!isset($_GET['tag']))
|
|
|
|
throw new UserFacingException('No album or tag has been specified for download.');
|
2018-12-26 10:31:57 +01:00
|
|
|
|
|
|
|
$tag = (int)$_GET['tag'];
|
|
|
|
$album = Tag::fromId($tag);
|
|
|
|
|
2020-03-01 17:00:18 +01:00
|
|
|
if (isset($_SESSION['current_export']))
|
|
|
|
throw new UserFacingException('An export of "' . $tag->tag . '" is ongoing. Please try again later.');
|
2018-12-26 10:31:57 +01:00
|
|
|
|
2020-03-01 17:00:18 +01:00
|
|
|
// So far so good?
|
|
|
|
$this->exportAlbum($album);
|
|
|
|
exit;
|
2018-12-26 10:31:57 +01:00
|
|
|
}
|
|
|
|
|
2020-03-01 17:07:10 +01:00
|
|
|
private function exportAlbum(Tag $album)
|
2018-12-26 10:31:57 +01:00
|
|
|
{
|
2019-09-29 14:47:56 +02:00
|
|
|
$files = [];
|
2018-12-26 10:31:57 +01:00
|
|
|
|
2019-09-29 14:47:56 +02:00
|
|
|
$album_ids = array_merge([$album->id_tag], $this->getChildAlbumIds($album->id_tag));
|
2018-12-26 10:31:57 +01:00
|
|
|
foreach($album_ids as $album_id)
|
|
|
|
{
|
2020-03-01 17:07:10 +01:00
|
|
|
$iterator = AssetIterator::getByOptions(['id_tag' => $album_id]);
|
|
|
|
while ($asset = $iterator->next())
|
|
|
|
$files[] = join(DIRECTORY_SEPARATOR, [$asset->getSubdir(), $asset->getFilename()]);
|
2018-12-26 10:31:57 +01:00
|
|
|
}
|
|
|
|
|
2019-09-29 14:47:56 +02:00
|
|
|
$descriptorspec = [
|
|
|
|
0 => ['pipe', 'r'],
|
|
|
|
1 => ['pipe', 'w'],
|
|
|
|
];
|
2018-12-26 10:31:57 +01:00
|
|
|
|
2020-03-01 17:07:10 +01:00
|
|
|
$command = 'tar -cf - -C ' . escapeshellarg(ASSETSDIR) . ' --null -T -';
|
2018-12-26 10:31:57 +01:00
|
|
|
|
|
|
|
$proc = proc_open($command, $descriptorspec, $pipes, ASSETSDIR);
|
|
|
|
|
|
|
|
if(!$proc)
|
|
|
|
throw new UnexpectedValueException('Could not execute TAR command');
|
|
|
|
|
|
|
|
if(!$pipes[0])
|
|
|
|
throw new UnexpectedValueException('Could not open pipe for STDIN');
|
|
|
|
|
|
|
|
if(!$pipes[1])
|
|
|
|
throw new UnexpectedValueException('Could not open pipe for STDOUT');
|
|
|
|
|
|
|
|
$album_name = $album->tag;
|
|
|
|
|
|
|
|
header('Pragma: no-cache');
|
|
|
|
header('Content-Description: File Download');
|
|
|
|
header('Content-disposition: attachment; filename="' . $album_name . '.tar"');
|
|
|
|
header('Content-Type: application/octet-stream');
|
|
|
|
header('Content-Transfer-Encoding: binary');
|
|
|
|
|
|
|
|
foreach($files as $file)
|
|
|
|
fwrite($pipes[0], $file . "\0");
|
|
|
|
|
|
|
|
fclose($pipes[0]);
|
|
|
|
|
|
|
|
while($chunk = stream_get_contents($pipes[1], 4096))
|
|
|
|
echo $chunk;
|
|
|
|
|
|
|
|
fclose($pipes[1]);
|
|
|
|
|
|
|
|
proc_close($proc);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function getChildAlbumIds($parent_id)
|
|
|
|
{
|
2019-09-29 14:47:56 +02:00
|
|
|
$ids = [];
|
2018-12-26 10:31:57 +01:00
|
|
|
|
|
|
|
$albums = Tag::getAlbums($parent_id, 0, PHP_INT_MAX, 'object');
|
|
|
|
foreach($albums as $album)
|
|
|
|
{
|
|
|
|
$ids[] = $album->id_tag;
|
|
|
|
$ids = array_merge($ids, $this->getChildAlbumIds($album->id_tag));
|
|
|
|
}
|
|
|
|
|
|
|
|
return $ids;
|
|
|
|
}
|
|
|
|
}
|