2021-04-01 10:59:15 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Classes\File;
|
|
|
|
|
|
|
|
use Exception;
|
|
|
|
use Illuminate\Support\Facades\Log;
|
2022-11-01 11:24:36 +00:00
|
|
|
use League\Flysystem\UnreadableFileEncountered;
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-12-03 07:18:05 +00:00
|
|
|
use App\Classes\File\Send\Dynamic;
|
2023-07-19 02:32:41 +00:00
|
|
|
use App\Classes\Node;
|
2021-07-17 05:48:07 +00:00
|
|
|
use App\Models\Address;
|
|
|
|
|
2021-04-01 10:59:15 +00:00
|
|
|
/**
|
|
|
|
* Object representing the files we are sending
|
|
|
|
*
|
|
|
|
* @property-read resource fd
|
2023-07-17 06:36:53 +00:00
|
|
|
* @property-read int files_size The size of the files waiting to be sent
|
|
|
|
* @property-read int mail_size The size of the mail waiting to be sent
|
|
|
|
* @property-read int togo_count The total number of items that havent been sent yet
|
|
|
|
* @property-read int total_size The size of the items waiting to be sent
|
2021-04-01 10:59:15 +00:00
|
|
|
* @property-read int total_sent
|
|
|
|
* @property-read int total_sent_bytes
|
|
|
|
*/
|
2023-07-17 06:36:53 +00:00
|
|
|
class Send extends Base
|
2021-04-01 10:59:15 +00:00
|
|
|
{
|
2021-08-18 12:11:16 +00:00
|
|
|
private const LOGKEY = 'IS-';
|
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
public const T_NONE = 0;
|
|
|
|
/** @var int This file contains a file from the DB */
|
|
|
|
public const T_FILE = (1<<0);
|
|
|
|
/** @var int This file contains a bundle of Netmail */
|
|
|
|
public const T_NETMAIL = (1<<1);
|
|
|
|
/** @var int This file contains a bundle of Echomail */
|
|
|
|
public const T_ECHOMAIL = (1<<2);
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-07-02 13:40:08 +00:00
|
|
|
private string $comp_data;
|
2024-06-17 09:03:48 +00:00
|
|
|
protected int $size = 0;
|
2021-04-01 10:59:15 +00:00
|
|
|
|
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
// Initialise our variables
|
2023-07-17 06:36:53 +00:00
|
|
|
if (get_class($this) === self::class) {
|
|
|
|
$this->list = collect();
|
|
|
|
$this->f = NULL;
|
|
|
|
}
|
2021-04-01 10:59:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function __get($key)
|
|
|
|
{
|
|
|
|
switch ($key) {
|
2023-07-17 06:36:53 +00:00
|
|
|
case 'completed':
|
|
|
|
return $this->list
|
|
|
|
->filter(function($item) { return $item->complete === TRUE; });
|
2023-07-15 12:10:05 +00:00
|
|
|
|
2021-04-01 10:59:15 +00:00
|
|
|
case 'fd':
|
2023-07-17 06:36:53 +00:00
|
|
|
return ! is_null($this->index);
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-07-02 13:40:08 +00:00
|
|
|
case 'files_count':
|
2021-04-01 10:59:15 +00:00
|
|
|
return $this->list
|
2023-06-22 07:36:22 +00:00
|
|
|
->filter(function($item) { return $item->isType(self::IS_FILE|self::IS_TIC); })
|
2021-04-01 10:59:15 +00:00
|
|
|
->count();
|
|
|
|
|
2023-07-02 13:40:08 +00:00
|
|
|
case 'files_size':
|
2021-04-01 10:59:15 +00:00
|
|
|
return $this->list
|
2023-06-22 07:36:22 +00:00
|
|
|
->filter(function($item) { return $item->isType(self::IS_FILE|self::IS_TIC); })
|
2023-07-02 13:40:08 +00:00
|
|
|
->sum(function($item) { return $item->size; });
|
2021-04-01 10:59:15 +00:00
|
|
|
|
|
|
|
case 'mail_count':
|
|
|
|
return $this->list
|
|
|
|
->filter(function($item) { return $item->isType(self::IS_ARC|self::IS_PKT); })
|
2023-07-17 06:36:53 +00:00
|
|
|
->count();
|
2021-04-01 10:59:15 +00:00
|
|
|
|
|
|
|
case 'mail_size':
|
|
|
|
return $this->list
|
|
|
|
->filter(function($item) { return $item->isType(self::IS_ARC|self::IS_PKT); })
|
2023-07-17 06:36:53 +00:00
|
|
|
->sum(function($item) { return $item->size; });
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
case 'name':
|
|
|
|
case 'nameas':
|
2021-04-01 10:59:15 +00:00
|
|
|
case 'mtime':
|
2023-07-17 06:36:53 +00:00
|
|
|
case 'size':
|
|
|
|
case 'type':
|
|
|
|
return $this->sending->{$key};
|
2023-07-14 10:03:09 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
case 'pos':
|
|
|
|
return $this->{$key};
|
2023-07-14 10:03:09 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
case 'sending':
|
|
|
|
return $this->list->get($this->index);
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
case 'togo_count':
|
2021-04-01 10:59:15 +00:00
|
|
|
return $this->list
|
2023-07-17 06:36:53 +00:00
|
|
|
->filter(function($item) { return $item->complete === FALSE; })
|
|
|
|
->count();
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
case 'total_sent':
|
|
|
|
return $this->completed
|
|
|
|
->count();
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
case 'total_sent_bytes':
|
|
|
|
return $this->completed
|
|
|
|
->sum(function($item) { return $item->size; });
|
2021-04-01 10:59:15 +00:00
|
|
|
|
|
|
|
case 'total_size':
|
|
|
|
return $this->list
|
2023-07-17 06:36:53 +00:00
|
|
|
->sum(function($item) { return $item->size; });
|
2021-04-01 10:59:15 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
throw new Exception('Unknown key: '.$key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-07-17 06:36:53 +00:00
|
|
|
* Close the file descriptor of the file we are sending
|
2021-04-01 10:59:15 +00:00
|
|
|
*
|
2023-07-17 06:36:53 +00:00
|
|
|
* @param bool $successful
|
2023-07-19 02:32:41 +00:00
|
|
|
* @param Node $node
|
2021-04-01 10:59:15 +00:00
|
|
|
* @throws Exception
|
|
|
|
*/
|
2023-07-19 02:32:41 +00:00
|
|
|
public function close(bool $successful,Node $node): void
|
2021-04-01 10:59:15 +00:00
|
|
|
{
|
2023-07-17 06:36:53 +00:00
|
|
|
if (! $this->fd)
|
|
|
|
throw new Exception('No file to close');
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
if ($successful) {
|
|
|
|
$end = time()-$this->start;
|
2023-12-18 11:44:55 +00:00
|
|
|
Log::info(sprintf('%s:- Closing [%s], sent in [%d] with [%s] items',self::LOGKEY,$this->sending->nameas,$end,$this->sending->dbids->count()));
|
2024-10-09 03:11:11 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
Log::alert(sprintf('%s:- Closing [%s], file NOT SENT successfully',self::LOGKEY,$this->sending->nameas));
|
2021-04-01 10:59:15 +00:00
|
|
|
}
|
2023-07-17 06:36:53 +00:00
|
|
|
|
2023-07-19 02:32:41 +00:00
|
|
|
$this->sending->close($successful,$node);
|
2023-07-17 06:36:53 +00:00
|
|
|
$this->index = NULL;
|
2021-04-01 10:59:15 +00:00
|
|
|
}
|
|
|
|
|
2023-12-03 07:18:05 +00:00
|
|
|
public function dynamic(Address $ao): bool
|
|
|
|
{
|
|
|
|
$file = FALSE;
|
|
|
|
|
|
|
|
// If the node is marked as hold - dont send any files.
|
|
|
|
if ($ao->system->hold) {
|
2023-12-18 11:44:55 +00:00
|
|
|
Log::info(sprintf('%s:- System [%d] is marked as hold - not checking for files.',self::LOGKEY,$ao->system_id));
|
2023-12-03 07:18:05 +00:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Files
|
|
|
|
if (($x=$ao->dynamicWaiting())->count()) {
|
|
|
|
Log::debug(sprintf('%s:- [%d] Dynamic Files(s) added for sending to [%s]',self::LOGKEY,$x->count(),$ao->ftn));
|
|
|
|
|
|
|
|
// Add Files
|
|
|
|
foreach ($x as $do)
|
|
|
|
$this->list->push(new Dynamic($do,$ao,self::T_FILE));
|
|
|
|
|
|
|
|
$file = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $file;
|
|
|
|
}
|
|
|
|
|
2023-07-02 13:40:08 +00:00
|
|
|
/*
|
|
|
|
private function compress(string $comp_mode): void
|
|
|
|
{
|
|
|
|
switch ($comp_mode) {
|
|
|
|
case 'BZ2':
|
|
|
|
$this->comp_data = bzcompress($buf);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'GZ':
|
|
|
|
$this->comp_data = gzcompress($buf);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2021-04-01 10:59:15 +00:00
|
|
|
/**
|
|
|
|
* Check if we are at the end of the file
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function feof(): bool
|
|
|
|
{
|
2023-07-17 06:36:53 +00:00
|
|
|
return $this->sending->feof();
|
2023-06-22 07:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add our mail to the send queue
|
|
|
|
*
|
|
|
|
* @param Address $ao
|
|
|
|
* @return bool
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function files(Address $ao): bool
|
|
|
|
{
|
|
|
|
$file = FALSE;
|
|
|
|
|
|
|
|
// If the node is marked as hold - dont send any files.
|
|
|
|
if ($ao->system->hold) {
|
2023-12-18 11:44:55 +00:00
|
|
|
Log::info(sprintf('%s:- System [%d] is marked as hold - not checking for files.',self::LOGKEY,$ao->system_id));
|
2023-06-22 07:36:22 +00:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Files
|
2024-11-26 11:07:07 +00:00
|
|
|
if (($x=$ao->getFiles())->count()) {
|
2024-06-26 12:37:38 +00:00
|
|
|
Log::info(sprintf('%s:- [%d] Files(s) added for sending to [%s]',self::LOGKEY,$x->count(),$ao->ftn));
|
2023-06-22 07:36:22 +00:00
|
|
|
|
|
|
|
// Add Files
|
2023-07-02 13:40:08 +00:00
|
|
|
foreach ($x as $fo) {
|
2023-07-17 06:36:53 +00:00
|
|
|
$this->list->push(new File($fo,self::T_FILE));
|
|
|
|
$this->list->push(new Tic($fo,$ao,self::T_NONE));
|
2023-06-22 07:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$file = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $file;
|
2021-04-01 10:59:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Open a file for sending
|
|
|
|
*
|
2023-07-02 13:40:08 +00:00
|
|
|
* @param string $compress
|
2021-04-01 10:59:15 +00:00
|
|
|
* @return bool
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
2023-07-02 13:40:08 +00:00
|
|
|
public function open(string $compress=''): bool
|
2021-04-01 10:59:15 +00:00
|
|
|
{
|
2024-06-27 05:26:28 +00:00
|
|
|
Log::debug(sprintf('%s:+ File Open to send',self::LOGKEY));
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
if ((($this->index=$this->list->search(function($item) { return $item->complete === FALSE; })) !== FALSE)
|
|
|
|
&& $this->sending->open())
|
2021-07-17 05:48:07 +00:00
|
|
|
{
|
2024-06-27 05:26:28 +00:00
|
|
|
Log::info(sprintf('%s:- Content Send item [#%d] (%s) with size [%d]',self::LOGKEY,$this->index,$this->sending->nameas,$this->sending->size));
|
2023-07-15 12:10:05 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
$this->pos = 0;
|
2021-07-17 05:48:07 +00:00
|
|
|
$this->start = time();
|
|
|
|
|
2023-07-02 13:40:08 +00:00
|
|
|
/*
|
|
|
|
if ($compress)
|
|
|
|
$this->comp_data = $this->compdata($compress);
|
|
|
|
*/
|
|
|
|
|
2021-07-17 05:48:07 +00:00
|
|
|
return TRUE;
|
2023-06-22 07:36:22 +00:00
|
|
|
|
|
|
|
} else {
|
2024-11-05 13:18:29 +00:00
|
|
|
Log::error(sprintf('%s:- No files to open',self::LOGKEY));
|
|
|
|
$this->index = NULL;
|
|
|
|
|
|
|
|
return FALSE;
|
2023-06-22 07:36:22 +00:00
|
|
|
}
|
2021-04-01 10:59:15 +00:00
|
|
|
}
|
|
|
|
|
2021-07-17 05:48:07 +00:00
|
|
|
/**
|
|
|
|
* Add our mail to the send queue
|
|
|
|
*
|
|
|
|
* @param Address $ao
|
2022-12-02 14:09:41 +00:00
|
|
|
* @return bool
|
2021-07-17 05:48:07 +00:00
|
|
|
* @throws Exception
|
|
|
|
*/
|
2024-05-19 13:28:45 +00:00
|
|
|
public function mail(Address $ao): bool
|
2021-07-17 05:48:07 +00:00
|
|
|
{
|
2022-12-02 14:09:41 +00:00
|
|
|
$mail = FALSE;
|
|
|
|
|
2022-01-15 11:38:45 +00:00
|
|
|
// If the node is marked as hold - dont send any mail.
|
|
|
|
if ($ao->system->hold) {
|
2023-10-04 04:49:44 +00:00
|
|
|
Log::info(sprintf('%s:- System [%d] is marked as hold - not checking for mail.',self::LOGKEY,$ao->system_id));
|
2022-12-02 14:09:41 +00:00
|
|
|
|
|
|
|
return FALSE;
|
2022-01-15 11:38:45 +00:00
|
|
|
}
|
|
|
|
|
2021-07-17 05:48:07 +00:00
|
|
|
// Netmail
|
2024-05-19 13:28:45 +00:00
|
|
|
if ($x=$ao->getNetmail()) {
|
2023-10-04 04:49:44 +00:00
|
|
|
Log::debug(sprintf('%s:- Netmail(s) added for sending to [%s]',self::LOGKEY,$ao->ftn));
|
2021-07-18 12:10:21 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
$this->list->push(new Mail($x,self::T_NETMAIL));
|
2022-12-02 14:09:41 +00:00
|
|
|
$mail = TRUE;
|
2021-07-18 12:10:21 +00:00
|
|
|
}
|
2021-09-06 13:39:32 +00:00
|
|
|
|
|
|
|
// Echomail
|
2024-05-19 13:28:45 +00:00
|
|
|
if ($x=$ao->getEchomail()) {
|
2023-10-04 04:49:44 +00:00
|
|
|
Log::debug(sprintf('%s:- Echomail(s) added for sending to [%s]',self::LOGKEY,$ao->ftn));
|
2021-09-06 13:39:32 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
$this->list->push(new Mail($x,self::T_ECHOMAIL));
|
2022-12-02 14:09:41 +00:00
|
|
|
$mail = TRUE;
|
2021-09-06 13:39:32 +00:00
|
|
|
}
|
2022-12-02 14:09:41 +00:00
|
|
|
|
|
|
|
return $mail;
|
2021-07-17 05:48:07 +00:00
|
|
|
}
|
|
|
|
|
2021-04-01 10:59:15 +00:00
|
|
|
/**
|
|
|
|
* Read bytes of the sending file
|
|
|
|
*
|
|
|
|
* @param int $length
|
|
|
|
* @return string|null
|
2022-11-01 11:24:36 +00:00
|
|
|
* @throws UnreadableFileEncountered
|
2021-04-01 10:59:15 +00:00
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function read(int $length): ?string
|
|
|
|
{
|
2023-07-17 06:36:53 +00:00
|
|
|
if (! $this->fd)
|
2021-04-01 10:59:15 +00:00
|
|
|
throw new Exception('No file open for read');
|
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
$data = $this->sending->read($length);
|
2021-04-01 10:59:15 +00:00
|
|
|
|
|
|
|
if ($data === FALSE)
|
2023-07-02 13:40:08 +00:00
|
|
|
throw new UnreadableFileEncountered('Error reading file: '.$this->sending->name);
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
$this->pos += strlen($data);
|
|
|
|
|
2024-06-27 05:26:28 +00:00
|
|
|
Log::debug(sprintf('%s:- Content Read [%d] bytes, pos now [%d]',self::LOGKEY,strlen($data),$this->pos));
|
2023-07-17 06:36:53 +00:00
|
|
|
|
2021-04-01 10:59:15 +00:00
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Seek to a specific position of our file
|
|
|
|
*
|
|
|
|
* @param int $pos
|
|
|
|
* @return bool
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function seek(int $pos): bool
|
|
|
|
{
|
2023-07-17 06:36:53 +00:00
|
|
|
if (! $this->fd)
|
2021-04-01 10:59:15 +00:00
|
|
|
throw new Exception('No file open for seek');
|
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
if ($this->sending->seek($pos)) {
|
|
|
|
$this->pos = $pos;
|
2021-07-17 05:48:07 +00:00
|
|
|
|
2024-06-27 05:26:28 +00:00
|
|
|
Log::debug(sprintf('%s:= Content Seek to [%d]',self::LOGKEY,$this->pos));
|
2021-07-17 05:48:07 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
return TRUE;
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
} else {
|
|
|
|
Log::error(sprintf('%s:! Failed to seek to [%d]',self::LOGKEY,$pos));
|
2021-04-01 10:59:15 +00:00
|
|
|
|
2023-07-17 06:36:53 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2021-04-01 10:59:15 +00:00
|
|
|
}
|
|
|
|
}
|