clrghouz/app/Classes/File/Item.php

188 lines
4.6 KiB
PHP
Raw Normal View History

2021-04-01 10:59:15 +00:00
<?php
namespace App\Classes\File;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Support\Facades\Storage;
2022-11-01 11:24:36 +00:00
use League\Flysystem\UnreadableFileEncountered;
2021-04-01 10:59:15 +00:00
use App\Models\File;
2021-04-01 10:59:15 +00:00
/**
* A file we are sending or receiving
*
* @property string $name
* @property string $recvas
* @property int $size
*/
class Item
{
private const LOGKEY = 'I--';
2022-12-02 14:00:45 +00:00
// For deep debugging
protected bool $DEBUG = FALSE;
/** @var int max size of file to use compression */
// @todo MAX_COMPSIZE hasnt been implemented in RECEIVE OR SEND
protected const MAX_COMPSIZE = 0x1fff;
2021-04-01 10:59:15 +00:00
protected const IS_PKT = (1<<1);
protected const IS_ARC = (1<<2);
protected const IS_FILE = (1<<3);
protected const IS_FLO = (1<<4);
protected const IS_REQ = (1<<5);
2022-11-01 11:24:36 +00:00
protected const IS_TIC = (1<<6);
2021-04-01 10:59:15 +00:00
protected const I_RECV = (1<<0);
protected const I_SEND = (1<<1);
2021-04-01 10:59:15 +00:00
protected string $file_name;
protected int $file_size;
protected int $file_mtime;
/** Current read/write pointer */
protected int $file_pos = 0;
/** File descriptor */
protected mixed $f = NULL;
protected int $type;
protected int $action;
protected File $filemodel;
2021-04-01 10:59:15 +00:00
public bool $sent = FALSE;
public bool $received = FALSE;
2021-08-12 11:59:48 +00:00
public bool $incomplete = FALSE;
/** Time we started sending/receiving */
protected int $start;
2021-04-01 10:59:15 +00:00
/**
* @throws FileNotFoundException
2022-11-01 11:24:36 +00:00
* @throws UnreadableFileEncountered
* @throws \Exception
2021-04-01 10:59:15 +00:00
*/
public function __construct($file,int $action)
{
switch ($action) {
case self::I_SEND:
if ($file instanceof File) {
$this->filemodel = $file;
// @todo We should catch any exceptions if the default storage is s3 (it is) and we cannot find the file, or the s3 call fails
$this->file_size = Storage::size($file->full_storage_path);
$this->file_mtime = Storage::lastModified($file->full_storage_path);
} else {
if (! is_string($file))
throw new \Exception('Invalid object creation - file should be a string');
2021-04-01 10:59:15 +00:00
if (! file_exists($file))
throw new FileNotFoundException('Item doesnt exist: '.$file);
2021-04-01 10:59:15 +00:00
if (! is_readable($file))
throw new UnreadableFileEncountered('Item cannot be read: '.$file);
2021-04-01 10:59:15 +00:00
$this->file_name = $file;
$x = stat($file);
$this->file_size = $x['size'];
$this->file_mtime = $x['mtime'];
}
2021-04-01 10:59:15 +00:00
break;
case self::I_RECV;
$keys = ['name','mtime','size'];
if (! is_array($file) || array_diff(array_keys($file),$keys))
throw new \Exception('Invalid object creation - file is not a valid array :'.serialize(array_diff(array_keys($file),$keys)));
2021-04-01 10:59:15 +00:00
$this->file_name = $file['name'];
$this->file_size = $file['size'];
$this->file_mtime = $file['mtime'];
break;
default:
throw new \Exception('Unknown action: '.$action);
2021-04-01 10:59:15 +00:00
}
$this->action = $action;
$this->type = $this->whatType();
2021-04-01 10:59:15 +00:00
}
/**
* @throws \Exception
2021-04-01 10:59:15 +00:00
*/
public function __get($key)
{
switch($key) {
case 'mtime':
if ($this instanceof Mail)
$this->youngest()->timestamp;
if ($this->action & self::I_RECV|self::I_SEND)
return $this->{'file_'.$key};
throw new \Exception('Invalid request for key: '.$key);
2021-04-01 10:59:15 +00:00
case 'name':
if ($this instanceof Mail)
return sprintf('%08x',timew($this->youngest()));
if ($this->action & self::I_RECV|self::I_SEND)
return $this->{'file_'.$key};
throw new \Exception('Invalid request for key: '.$key);
2021-04-01 10:59:15 +00:00
case 'size':
if ($this instanceof Mail)
return strlen($this->file);
if ($this->action & self::I_RECV|self::I_SEND)
2021-04-01 10:59:15 +00:00
return $this->{'file_'.$key};
throw new \Exception('Invalid request for key: '.$key);
2021-04-01 10:59:15 +00:00
case 'recvas':
return $this->file_name;
2021-04-01 10:59:15 +00:00
case 'sendas':
if ($this instanceof Mail)
return sprintf('%s.pkt',$this->name);
return $this->file_name ? basename($this->file_name) : $this->filemodel->name;
2021-04-01 10:59:15 +00:00
default:
throw new \Exception('Unknown key: '.$key);
2021-04-01 10:59:15 +00:00
}
}
protected function isType(int $type): bool
{
return $this->type & $type;
2021-04-01 10:59:15 +00:00
}
private function whatType(): int
{
static $ext = ['su','mo','tu','we','th','fr','sa','req'];
$x = strrchr($this->file_name,'.');
2021-04-01 10:59:15 +00:00
if (! $x || (strlen(substr($x,1)) != 3))
return self::IS_FILE;
2023-06-27 07:39:11 +00:00
if (strcasecmp(substr($x,2),'lo') === 0)
2021-04-01 10:59:15 +00:00
return self::IS_FLO;
2023-06-27 07:39:11 +00:00
if (strcasecmp(substr($x,1),'pkt') === 0)
2021-04-01 10:59:15 +00:00
return self::IS_PKT;
2023-06-27 07:39:11 +00:00
if (strcasecmp(substr($x,1),'req') === 0)
2021-04-01 10:59:15 +00:00
return self::IS_REQ;
2023-06-27 07:39:11 +00:00
if (strcasecmp(substr($x,1),'tic') === 0)
2022-11-01 11:24:36 +00:00
return self::IS_TIC;
2021-04-01 10:59:15 +00:00
for ($i=0;$i<count($ext);$i++)
if (! strncasecmp($x,'.'.$ext[$i],strlen($ext[$i])) && (preg_match('/^[0-9a-z]/',strtolower(substr($x,3,1)))))
return self::IS_ARC;
return self::IS_FILE;
}
}