2021-04-01 10:59:15 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Classes\File;
|
|
|
|
|
|
|
|
use Exception;
|
|
|
|
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
2023-06-22 07:36:22 +00:00
|
|
|
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
|
|
|
|
2023-06-22 07:36:22 +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
|
|
|
|
{
|
2021-08-17 13:49:39 +00:00
|
|
|
private const LOGKEY = 'I--';
|
|
|
|
|
2022-12-02 14:00:45 +00:00
|
|
|
// For deep debugging
|
|
|
|
protected bool $DEBUG = FALSE;
|
|
|
|
|
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<<6);
|
|
|
|
protected const I_SEND = (1<<7);
|
|
|
|
|
|
|
|
protected string $file_name = '';
|
|
|
|
protected int $file_size = 0;
|
|
|
|
protected int $file_mtime = 0;
|
|
|
|
protected int $file_type = 0;
|
|
|
|
protected int $action = 0;
|
2023-06-22 07:36:22 +00:00
|
|
|
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;
|
2021-04-01 10:59:15 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @throws FileNotFoundException
|
2022-11-01 11:24:36 +00:00
|
|
|
* @throws UnreadableFileEncountered
|
2021-04-01 10:59:15 +00:00
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function __construct($file,int $action)
|
|
|
|
{
|
|
|
|
$this->action |= $action;
|
|
|
|
|
|
|
|
switch ($action) {
|
|
|
|
case self::I_SEND:
|
2023-06-22 07:36:22 +00:00
|
|
|
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
|
|
|
|
2023-06-22 07:36:22 +00:00
|
|
|
if (! file_exists($file))
|
|
|
|
throw new FileNotFoundException('Item doesnt exist: '.$file);
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-06-22 07:36:22 +00:00
|
|
|
if (! is_readable($file))
|
|
|
|
throw new UnreadableFileEncountered('Item cannot be read: '.$file);
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-06-22 07:36:22 +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)));
|
|
|
|
|
|
|
|
$this->file_name = $file['name'];
|
|
|
|
$this->file_size = $file['size'];
|
|
|
|
$this->file_mtime = $file['mtime'];
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
throw new Exception('Unknown action: '.$action);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->file_type |= $this->whatType();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function __get($key)
|
|
|
|
{
|
|
|
|
switch($key) {
|
|
|
|
case 'mtime':
|
|
|
|
case 'name':
|
|
|
|
case 'size':
|
|
|
|
if ($this->action & self::I_RECV)
|
|
|
|
return $this->{'file_'.$key};
|
|
|
|
|
|
|
|
throw new Exception('Invalid request for key: '.$key);
|
|
|
|
|
|
|
|
case 'recvas':
|
2021-07-18 12:10:21 +00:00
|
|
|
return $this->file_name;
|
2021-04-01 10:59:15 +00:00
|
|
|
|
|
|
|
case 'sendas':
|
2023-06-23 07:33:47 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function isType(int $type): bool
|
|
|
|
{
|
|
|
|
return $this->file_type & $type;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function whatType(): int
|
|
|
|
{
|
|
|
|
static $ext = ['su','mo','tu','we','th','fr','sa','req'];
|
|
|
|
|
|
|
|
$x = strrchr($this->file_name,'.');
|
2021-07-18 12:10:21 +00:00
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|