mirror of
				https://github.com/filegator/filegator.git
				synced 2025-10-29 12:26:15 +01: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');
 | |
|     }
 | |
| }
 |