mirror of
https://github.com/filegator/filegator.git
synced 2025-08-06 08:17:28 +02:00
149 lines
3.8 KiB
PHP
149 lines
3.8 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the FileGator package.
|
|
*
|
|
* (c) Milos Stojanovic <alcalbg@gmail.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE file
|
|
*/
|
|
|
|
namespace Filegator\Services\Archiver\Adapters;
|
|
|
|
use Filegator\Services\Archiver\ArchiverInterface;
|
|
use Filegator\Services\Service;
|
|
use Filegator\Services\Storage\Filesystem as Storage;
|
|
use Filegator\Services\Tmpfs\TmpfsInterface;
|
|
use League\Flysystem\Config as Flyconfig;
|
|
use League\Flysystem\Filesystem as Flysystem;
|
|
use League\Flysystem\ZipArchive\ZipArchiveAdapter;
|
|
|
|
class ZipArchiver implements Service, ArchiverInterface
|
|
{
|
|
protected $archive;
|
|
|
|
protected $storage;
|
|
|
|
protected $tmpfs;
|
|
|
|
protected $uniqid;
|
|
|
|
protected $tmp_files = [];
|
|
|
|
public function __construct(TmpfsInterface $tmpfs)
|
|
{
|
|
$this->tmpfs = $tmpfs;
|
|
}
|
|
|
|
public function init(array $config = [])
|
|
{
|
|
}
|
|
|
|
public function createArchive(Storage $storage): string
|
|
{
|
|
$this->uniqid = uniqid();
|
|
|
|
$this->archive = new Flysystem(
|
|
new ZipAdapter($this->tmpfs->getFileLocation($this->uniqid))
|
|
);
|
|
|
|
$this->storage = $storage;
|
|
|
|
return $this->uniqid;
|
|
}
|
|
|
|
public function addDirectoryFromStorage(string $path)
|
|
{
|
|
$content = $this->storage->getDirectoryCollection($path, true);
|
|
$this->archive->createDir($path);
|
|
|
|
foreach ($content->all() as $item) {
|
|
if ($item['type'] == 'dir') {
|
|
$this->archive->createDir($item['path']);
|
|
}
|
|
if ($item['type'] == 'file') {
|
|
$this->addFileFromStorage($item['path']);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function addFileFromStorage(string $path)
|
|
{
|
|
$file_uniqid = uniqid();
|
|
|
|
$file = $this->storage->readStream($path);
|
|
|
|
$this->tmpfs->write($file_uniqid, $file['stream']);
|
|
|
|
$this->archive->write($path, $this->tmpfs->getFileLocation($file_uniqid));
|
|
|
|
$this->tmp_files[] = $file_uniqid;
|
|
}
|
|
|
|
public function uncompress(string $source, string $destination, Storage $storage)
|
|
{
|
|
$name = uniqid().'.zip';
|
|
|
|
$remote_archive = $storage->readStream($source);
|
|
$this->tmpfs->write($name, $remote_archive['stream']);
|
|
|
|
$archive = new Flysystem(
|
|
new ZipAdapter($this->tmpfs->getFileLocation($name))
|
|
);
|
|
|
|
$contents = $archive->listContents('/', true);
|
|
|
|
foreach ($contents as $item) {
|
|
$stream = null;
|
|
if ($item['type'] == 'dir') {
|
|
$storage->createDir($destination, $item['path']);
|
|
}
|
|
if ($item['type'] == 'file') {
|
|
$stream = $archive->readStream($item['path']);
|
|
$storage->store($destination.'/'.$item['dirname'], $item['basename'], $stream);
|
|
}
|
|
if (is_resource($stream)) {
|
|
fclose($stream);
|
|
}
|
|
}
|
|
|
|
$this->tmpfs->remove($name);
|
|
}
|
|
|
|
public function closeArchive()
|
|
{
|
|
$this->archive->getAdapter()->getArchive()->close();
|
|
|
|
foreach ($this->tmp_files as $file) {
|
|
$this->tmpfs->remove($file);
|
|
}
|
|
}
|
|
|
|
public function storeArchive($destination, $name)
|
|
{
|
|
$this->closeArchive();
|
|
|
|
$file = $this->tmpfs->readStream($this->uniqid);
|
|
$this->storage->store($destination, $name, $file['stream']);
|
|
if (is_resource($file['stream'])) {
|
|
fclose($file['stream']);
|
|
}
|
|
|
|
$this->tmpfs->remove($this->uniqid);
|
|
}
|
|
}
|
|
|
|
class ZipAdapter extends ZipArchiveAdapter
|
|
{
|
|
public function write($path, $contents, Flyconfig $config)
|
|
{
|
|
$location = $this->applyPathPrefix($path);
|
|
|
|
// using addFile instead of addFromString
|
|
// is more memory efficient
|
|
$this->archive->addFile($contents, $location);
|
|
|
|
return compact('path', 'contents');
|
|
}
|
|
}
|