146 lines
3.3 KiB
PHP
146 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Classes;
|
|
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Symfony\Component\HttpFoundation\File\File as FileBase;
|
|
|
|
use App\Classes\FTN\Packet;
|
|
|
|
class File extends FileBase implements \Iterator
|
|
{
|
|
private const LOGKEY = 'F--';
|
|
private int $counter = 0;
|
|
private bool $isArchive = FALSE;
|
|
private bool $canHandle = FALSE;
|
|
private \ZipArchive $z;
|
|
private array $zipfile = [];
|
|
|
|
public function __construct(mixed $path,bool $checkPath=true)
|
|
{
|
|
parent::__construct($path,$checkPath);
|
|
|
|
if ($this->getExtension() === 'pkt')
|
|
$this->canHandle = TRUE;
|
|
|
|
else
|
|
switch ($x=$this->guessExtension()) {
|
|
case 'zip':
|
|
$this->canHandle = TRUE;
|
|
$this->isArchive = TRUE;
|
|
$this->z = new \ZipArchive;
|
|
$this->z->open($this->getRealPath());
|
|
break;
|
|
|
|
case NULL:
|
|
case 'bin':
|
|
if ($this->isPacket() || ($path instanceof UploadedFile && (strcasecmp($path->getClientOriginalExtension(),'pkt') === 0))) {
|
|
$this->canHandle = TRUE;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
Log::alert(sprintf('%s:? Unknown file received: %s (%s) [%s]',self::LOGKEY,$x,$this->getExtension(),$path instanceof UploadedFile ? $path->getClientOriginalExtension() : '-'));
|
|
}
|
|
}
|
|
|
|
/* ITERATOR */
|
|
|
|
public function current()
|
|
{
|
|
if ($this->isArchive) {
|
|
$this->zipfile = $this->z->statIndex($this->counter,\ZipArchive::FL_UNCHANGED);
|
|
|
|
$f = $this->z->getStream($this->zipfile['name']);
|
|
if (! $f)
|
|
throw new \Exception(sprintf('%s:Failed getting ZipArchive::stream (%s)',self::LOGKEY,$this->z->getStatusString()));
|
|
|
|
return $f;
|
|
|
|
} else {
|
|
return fopen($this->getRealPath(),'r+');
|
|
}
|
|
}
|
|
|
|
public function next()
|
|
{
|
|
$this->counter++;
|
|
}
|
|
|
|
public function key()
|
|
{
|
|
return $this->counter;
|
|
}
|
|
|
|
public function valid()
|
|
{
|
|
// If we have a pkt file, then counter can only be 1.
|
|
return $this->canHandle && (($this->isArchive && ($this->counter < $this->z->numFiles)) || $this->counter === 0);
|
|
}
|
|
|
|
public function rewind()
|
|
{
|
|
$this->counter = 0;
|
|
}
|
|
|
|
/* METHODS */
|
|
|
|
public function isArchive(): bool
|
|
{
|
|
return $this->isArchive;
|
|
}
|
|
|
|
/**
|
|
* Determine if the file is a mail packet
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function isPacket(): bool
|
|
{
|
|
return (strcasecmp($this->getExtension(),'pkt') === 0);
|
|
}
|
|
|
|
public function itemName(): string
|
|
{
|
|
return ($this->isArchive && $this->valid()) ? Arr::get(stream_get_meta_data($this->current()),'uri') : $this->getFilename();
|
|
}
|
|
|
|
public function itemSize(): int
|
|
{
|
|
return $this->isArchive ? Arr::get($this->zipfile,'size') : $this->getSize();
|
|
}
|
|
|
|
/**
|
|
* Return the name of the file, without a node ID, mtime prefix
|
|
*
|
|
* @return string
|
|
*/
|
|
public function rawName(): string
|
|
{
|
|
return preg_replace(sprintf('/^%s\.pkt$/i',Packet::regex),'\3\4',$this->getFilename());
|
|
}
|
|
|
|
/**
|
|
* Return the packet name
|
|
*
|
|
* @return string|null
|
|
* @throws \Exception
|
|
*/
|
|
public function pktName(): ?string
|
|
{
|
|
if ($this->isArchive) {
|
|
$this->zipfile = $this->z->statIndex($this->counter,\ZipArchive::FL_UNCHANGED);
|
|
|
|
$f = $this->z->getStream($this->zipfile['name']);
|
|
if (! $f)
|
|
throw new \Exception(sprintf('%s:Failed getting ZipArchive::stream (%s)',self::LOGKEY,$this->z->getStatusString()));
|
|
|
|
return preg_replace('/.pkt$/i','',Arr::get(stream_get_meta_data($f),'uri'));
|
|
|
|
} else {
|
|
return $this->isPacket() ? $this->rawName() : NULL;
|
|
}
|
|
}
|
|
} |