2021-06-29 10:43:29 +00:00
< ? php
namespace App\Classes\FTN ;
use Carbon\Carbon ;
use Illuminate\Support\Arr ;
use Illuminate\Support\Collection ;
use Illuminate\Support\Facades\Log ;
2023-09-20 10:29:23 +00:00
use Illuminate\Support\Facades\Notification ;
2021-06-29 10:43:29 +00:00
use Symfony\Component\HttpFoundation\File\File ;
use App\Classes\FTN as FTNBase ;
2024-05-17 12:10:54 +00:00
use App\Exceptions\InvalidPacketException ;
use App\Models\ { Address , Domain , Echomail , Netmail , Software , Zone };
2023-09-20 10:29:23 +00:00
use App\Notifications\Netmails\EchomailBadAddress ;
2021-06-29 10:43:29 +00:00
2023-06-22 07:36:22 +00:00
/**
2023-09-14 22:09:42 +00:00
* Represents a Fidonet Packet , that contains an array of messages .
*
2024-05-17 12:10:54 +00:00
* Thus this object is iterable as an array of Echomail :: class or Netmail :: class .
2023-06-22 07:36:22 +00:00
*/
2024-05-17 12:10:54 +00:00
abstract class Packet extends FTNBase implements \Iterator , \Countable
2021-06-29 10:43:29 +00:00
{
private const LOGKEY = 'PKT' ;
2023-06-25 10:45:02 +00:00
protected const PACKED_MSG_LEAD = " \02 \00 " ;
2023-12-13 12:00:47 +00:00
protected const PACKED_END = " \00 \00 " ;
2023-06-25 10:45:02 +00:00
2024-05-17 12:10:54 +00:00
// @todo Rename this regex to something more descriptive, ie: FILENAME_REGEX
2023-11-23 12:17:13 +00:00
public const regex = '([[:xdigit:]]{4})(?:-(\d{4,10}))?-(.+)' ;
2024-05-17 12:10:54 +00:00
/**
* Packet types we support , in specific order for auto - detection to work
*
* @ var string []
*/
2023-06-26 09:19:42 +00:00
public const PACKET_TYPES = [
'2.2' => FTNBase\Packet\FSC45 :: class ,
'2+' => FTNBase\Packet\FSC48 :: class ,
'2e' => FTNBase\Packet\FSC39 :: class ,
'2.0' => FTNBase\Packet\FTS1 :: class ,
2021-06-29 10:43:29 +00:00
];
2023-06-25 10:45:02 +00:00
protected array $header ; // Packet Header
2024-05-17 12:10:54 +00:00
protected ? string $name = NULL ; // Packet name
2021-07-15 14:54:23 +00:00
public File $file ; // Packet filename
2024-05-17 12:10:54 +00:00
protected Address $fftn_p ; // Address the packet is from (when packing messages)
protected Address $tftn_p ; // Address the packet is to (when packing messages)
protected Collection $messages ; // Messages in the Packet
2021-08-13 13:46:48 +00:00
public Collection $errors ; // Messages that fail validation
2023-09-14 22:09:42 +00:00
protected int $index ; // Our array index
2021-08-24 13:42:03 +00:00
2023-06-25 10:45:02 +00:00
/* STATIC */
/**
2023-11-15 11:12:09 +00:00
* Size of the packet header
2023-06-25 10:45:02 +00:00
*
* @ return int
*/
public static function header_len () : int
2021-08-24 13:42:03 +00:00
{
2023-06-25 10:45:02 +00:00
return collect ( static :: HEADER ) -> sum ( function ( $item ) { return Arr :: get ( $item , 2 ); });
2021-08-24 13:42:03 +00:00
}
2021-07-15 14:54:23 +00:00
2022-01-20 06:54:02 +00:00
/**
2023-06-25 10:45:02 +00:00
* This function is intended to be implemented in child classes to test if the packet
* is defined by the child object
*
* @ see self :: PACKET_TYPES
* @ param string $header
* @ return bool
2022-01-20 06:54:02 +00:00
*/
2024-05-17 12:10:54 +00:00
abstract public static function is_type ( string $header ) : bool ;
2021-07-15 14:54:23 +00:00
/**
2022-11-13 13:29:55 +00:00
* Process a packet file
2021-07-15 14:54:23 +00:00
*
2023-12-13 12:00:47 +00:00
* @ param mixed $f File handler returning packet data
2022-11-13 13:29:55 +00:00
* @ param string $name
* @ param int $size
2023-09-20 10:29:23 +00:00
* @ param Domain | null $domain
2021-07-15 14:54:23 +00:00
* @ return Packet
* @ throws InvalidPacketException
*/
2023-09-20 10:29:23 +00:00
public static function process ( mixed $f , string $name , int $size , Domain $domain = NULL ) : self
2021-07-15 14:54:23 +00:00
{
2022-11-13 13:29:55 +00:00
Log :: debug ( sprintf ( '%s:+ Opening Packet [%s] with size [%d]' , self :: LOGKEY , $name , $size ));
2021-07-15 14:54:23 +00:00
2023-06-25 10:45:02 +00:00
$o = FALSE ;
$header = '' ;
2022-11-13 13:29:55 +00:00
$read_ptr = 0 ;
2021-07-15 14:54:23 +00:00
2023-06-25 10:45:02 +00:00
// Determine the type of packet
foreach ( self :: PACKET_TYPES as $type ) {
$header_len = $type :: header_len ();
// PKT Header
if ( $read_ptr < $header_len ) {
$header .= fread ( $f , $header_len - $read_ptr );
$read_ptr = ftell ( $f );
}
// Could not read header
if ( strlen ( $header ) !== $header_len )
throw new InvalidPacketException ( sprintf ( 'Length of header [%d] too short' , strlen ( $header )));
2021-07-15 14:54:23 +00:00
2023-06-25 10:45:02 +00:00
if ( $type :: is_type ( $header )) {
$o = new $type ( $header );
break ;
}
}
2021-07-15 14:54:23 +00:00
2023-06-25 10:45:02 +00:00
if ( ! $o )
throw new InvalidPacketException ( 'Cannot determine type of packet.' );
2021-07-15 14:54:23 +00:00
2022-11-13 13:29:55 +00:00
$o -> name = $name ;
2021-07-15 14:54:23 +00:00
$x = fread ( $f , 2 );
2023-12-13 12:00:47 +00:00
if ( strlen ( $x ) === 2 ) {
// End of Packet?
if ( $x === " \00 \00 " )
return $o ;
2021-07-15 14:54:23 +00:00
2023-12-13 12:00:47 +00:00
// Messages start with self::PACKED_MSG_LEAD
elseif ( $x !== self :: PACKED_MSG_LEAD )
throw new InvalidPacketException ( 'Not a valid packet: ' . bin2hex ( $x ));
2021-06-29 10:43:29 +00:00
2021-07-15 14:54:23 +00:00
// No message attached
2023-12-13 12:00:47 +00:00
} else
2024-05-17 12:10:54 +00:00
throw new InvalidPacketException ( 'Not a valid packet, not EOP or SOM:' . bin2hex ( $x ));
Log :: info ( sprintf ( '%s:- Packet [%s] is a [%s] packet, dated [%s]' , self :: LOGKEY , $o -> name , get_class ( $o ), $o -> date ));
2021-07-15 14:54:23 +00:00
2023-09-20 10:29:23 +00:00
// Work out the packet zone
if ( $o -> fz && ( $o -> fd || $domain )) {
$o -> zone = Zone :: select ( 'zones.*' )
-> join ( 'domains' ,[ 'domains.id' => 'zones.domain_id' ])
-> where ( 'zone_id' , $o -> fz )
-> where ( 'name' , $o -> fd ? : $domain -> name )
-> single ();
}
// If zone is not set, then we need to use a default zone - the messages may not be from this zone.
2024-05-17 12:10:54 +00:00
if ( empty ( $o -> zone )) {
2023-09-20 10:29:23 +00:00
Log :: alert ( sprintf ( '%s:! We couldnt work out the packet zone, so we have fallen back to the default for [%d]' , self :: LOGKEY , $o -> fz ));
2021-11-24 11:34:40 +00:00
2023-09-20 10:29:23 +00:00
$o -> zone = Zone :: where ( 'zone_id' , $o -> fz )
-> where ( 'default' , TRUE )
-> singleOrFail ();
}
2021-08-29 13:58:12 +00:00
2023-12-07 09:19:48 +00:00
$message = '' ; // Current message we are building
2023-12-13 12:00:47 +00:00
$msgbuf = '' ;
2024-05-17 12:10:54 +00:00
$leader = Message :: header_len () + strlen ( self :: PACKED_MSG_LEAD );
2021-07-15 14:54:23 +00:00
2023-12-07 09:19:48 +00:00
// We loop through reading from the buffer, to find our end of message tag
2023-12-13 12:00:47 +00:00
while (( ! feof ( $f ) && ( $readbuf = fread ( $f , $leader )))) {
$read_ptr = ftell ( $f );
$msgbuf .= $readbuf ;
// See if we have our EOM/EOP marker
if ((( $end = strpos ( $msgbuf , " \x00 " . self :: PACKED_MSG_LEAD , $leader )) !== FALSE )
|| (( $end = strpos ( $msgbuf , " \x00 " . self :: PACKED_END , $leader )) !== FALSE ))
{
// Parse our message
$o -> parseMessage ( substr ( $msgbuf , 0 , $end ));
$msgbuf = substr ( $msgbuf , $end + 3 );
continue ;
2024-05-17 12:10:54 +00:00
// If we have more to read
2023-12-13 12:00:47 +00:00
} elseif ( $read_ptr < $size ) {
continue ;
2021-08-26 12:01:16 +00:00
}
2023-12-13 12:00:47 +00:00
// If we get here
throw new InvalidPacketException ( sprintf ( 'Cannot determine END of message/packet: %s|%s' , get_class ( $o ), hex_dump ( $message )));;
2021-06-29 10:43:29 +00:00
}
2021-07-15 14:54:23 +00:00
2023-12-13 12:00:47 +00:00
if ( $msgbuf )
throw new InvalidPacketException ( sprintf ( 'Unprocessed data in packet: %s|%s' , get_class ( $o ), hex_dump ( $msgbuf )));
2021-07-30 14:35:52 +00:00
2021-07-15 14:54:23 +00:00
return $o ;
2021-06-29 10:43:29 +00:00
}
/**
2024-05-17 12:10:54 +00:00
* @ param string | null $header
* @ throws \Exception
*/
public function __construct ( string $header = NULL )
{
$this -> messages = collect ();
$this -> errors = collect ();
if ( $header )
$this -> header = unpack ( self :: unpackheader ( static :: HEADER ), $header );
}
/**
* @ throws \Exception
2021-06-29 10:43:29 +00:00
*/
2024-05-17 12:10:54 +00:00
public function __get ( $key )
2021-06-29 10:43:29 +00:00
{
2024-05-17 12:10:54 +00:00
Log :: debug ( sprintf ( '%s:/ Requesting key for Packet::class [%s]' , self :: LOGKEY , $key ));
switch ( $key ) {
// From Addresses
case 'fz' : return Arr :: get ( $this -> header , 'ozone' );
case 'fn' : return Arr :: get ( $this -> header , 'onet' );
case 'ff' : return Arr :: get ( $this -> header , 'onode' );
case 'fp' : return Arr :: get ( $this -> header , 'opoint' );
case 'fd' : return rtrim ( Arr :: get ( $this -> header , 'odomain' , " \x00 " ));
// To Addresses
case 'tz' : return Arr :: get ( $this -> header , 'dzone' );
case 'tn' : return Arr :: get ( $this -> header , 'dnet' );
case 'tf' : return Arr :: get ( $this -> header , 'dnode' );
case 'tp' : return Arr :: get ( $this -> header , 'dpoint' );
case 'td' : return rtrim ( Arr :: get ( $this -> header , 'ddomain' , " \x00 " ));
case 'date' :
return Carbon :: create (
Arr :: get ( $this -> header , 'y' ),
Arr :: get ( $this -> header , 'm' ) + 1 ,
Arr :: get ( $this -> header , 'd' ),
Arr :: get ( $this -> header , 'H' ),
Arr :: get ( $this -> header , 'M' ),
Arr :: get ( $this -> header , 'S' )
);
case 'password' :
return rtrim ( Arr :: get ( $this -> header , $key ), " \x00 " );
case 'fftn_t' :
case 'fftn' :
case 'tftn_t' :
case 'tftn' :
return parent :: __get ( $key );
case 'software' :
$code = Arr :: get ( $this -> header , 'prodcode-hi' ) << 8 | Arr :: get ( $this -> header , 'prodcode-lo' );
Software :: unguard ();
$o = Software :: singleOrNew ([ 'code' => $code , 'type' => Software :: SOFTWARE_TOSSER ]);
Software :: reguard ();
return $o ;
case 'software_ver' :
return sprintf ( '%d.%d' , Arr :: get ( $this -> header , 'prodrev-maj' ), Arr :: get ( $this -> header , 'prodrev-min' ));
case 'capability' :
// This needs to be defined in child classes, since not all children have it
return NULL ;
// Packet Type
case 'type' :
return static :: TYPE ;
// Packet name:
case 'name' :
return $this -> { $key } ? : sprintf ( '%08x' , timew ());
default :
throw new \Exception ( 'Unknown key: ' . $key );
}
2023-06-25 10:45:02 +00:00
}
2021-07-18 12:10:21 +00:00
2024-05-17 12:10:54 +00:00
/**
* Return the packet
*
* @ return string
* @ throws \Exception
*/
public function __toString () : string
2023-06-25 10:45:02 +00:00
{
2024-05-17 12:10:54 +00:00
$return = $this -> header ();
foreach ( $this -> messages as $o )
$return .= self :: PACKED_MSG_LEAD . $o -> packet ( $this -> tftn_p );
$return .= " \00 \00 " ;
return $return ;
2021-06-29 10:43:29 +00:00
}
2023-06-25 10:45:02 +00:00
/* INTERFACE */
2021-07-15 14:54:23 +00:00
/**
2023-06-25 10:45:02 +00:00
* Number of messages in this packet
2021-07-15 14:54:23 +00:00
*/
2023-06-25 10:45:02 +00:00
public function count () : int
2021-06-29 10:43:29 +00:00
{
2023-06-25 10:45:02 +00:00
return $this -> messages -> count ();
}
2021-06-29 10:43:29 +00:00
2024-05-17 12:10:54 +00:00
public function current () : Echomail | Netmail
2023-06-25 10:45:02 +00:00
{
2023-09-14 22:09:42 +00:00
return $this -> messages -> get ( $this -> index );
2023-06-25 10:45:02 +00:00
}
2021-06-29 10:43:29 +00:00
2023-06-25 10:45:02 +00:00
public function key () : mixed
{
2023-09-14 22:09:42 +00:00
return $this -> index ;
2023-06-25 10:45:02 +00:00
}
2021-09-08 12:07:00 +00:00
2023-06-25 10:45:02 +00:00
public function next () : void
{
$this -> index ++ ;
2021-06-29 10:43:29 +00:00
}
2023-06-25 10:45:02 +00:00
public function rewind () : void
2021-06-29 10:43:29 +00:00
{
2023-06-25 10:45:02 +00:00
$this -> index = 0 ;
2021-06-29 10:43:29 +00:00
}
2023-06-25 10:45:02 +00:00
public function valid () : bool
2021-06-29 10:43:29 +00:00
{
2023-09-14 22:09:42 +00:00
return ( ! is_null ( $this -> key ())) && $this -> messages -> has ( $this -> key ());
2021-06-29 10:43:29 +00:00
}
2023-06-25 10:45:02 +00:00
/* METHODS */
2021-06-29 10:43:29 +00:00
/**
2021-07-15 14:54:23 +00:00
* When creating a new packet , set the header .
2021-06-29 10:43:29 +00:00
*
2022-01-20 06:54:02 +00:00
* @ param Address $oo
2021-07-17 05:48:07 +00:00
* @ param Address $o
2023-07-23 07:27:52 +00:00
* @ param string | null $passwd Override the password used in the packet
2024-05-17 12:10:54 +00:00
* @ deprecated Use Packet :: generate (), which should generate a packet of the right type
2021-06-29 10:43:29 +00:00
*/
2023-07-23 07:27:52 +00:00
public function addressHeader ( Address $oo , Address $o , string $passwd = NULL ) : void
2021-06-29 10:43:29 +00:00
{
2023-07-11 11:34:47 +00:00
Log :: debug ( sprintf ( '%s:+ Creating packet for [%s]' , self :: LOGKEY , $o -> ftn ));
2023-06-25 10:45:02 +00:00
2021-07-15 14:54:23 +00:00
$date = Carbon :: now ();
// Create Header
$this -> header = [
2023-06-25 10:45:02 +00:00
'ozone' => $oo -> zone -> zone_id , // Orig Zone
'dzone' => $o -> zone -> zone_id , // Dest Zone
'onet' => $oo -> host_id ? : $oo -> region_id , // Orig Net
'dnet' => $o -> host_id ? : $o -> region_id , // Dest Net
'onode' => $oo -> node_id , // Orig Node
'dnode' => $o -> node_id , // Dest Node
'opoint' => $oo -> point_id , // Orig Point
'dpoint' => $o -> point_id , // Dest Point
'odomain' => $oo -> zone -> domain -> name , // Orig Domain
'ddomain' => $o -> zone -> domain -> name , // Dest Domain
2021-08-20 14:33:41 +00:00
'y' => $date -> format ( 'Y' ), // Year
'm' => $date -> format ( 'm' ) - 1 , // Month
'd' => $date -> format ( 'd' ), // Day
'H' => $date -> format ( 'H' ), // Hour
'M' => $date -> format ( 'i' ), // Minute
'S' => $date -> format ( 's' ), // Second
2023-11-24 22:47:58 +00:00
'password' => strtoupper (( ! is_null ( $passwd )) ? $passwd : $o -> session ( 'pktpass' )), // Packet Password
2021-07-15 14:54:23 +00:00
];
}
2021-06-29 10:43:29 +00:00
2023-06-25 10:45:02 +00:00
/**
2023-07-14 10:03:09 +00:00
* Add a message to this packet
2023-06-25 10:45:02 +00:00
*
* @ param Message $o
2024-05-17 12:10:54 +00:00
* @ deprecated No longer used when Address :: class is updated
2023-06-25 10:45:02 +00:00
*/
public function addMail ( Message $o ) : void
{
$this -> messages -> push ( $o );
}
2024-05-17 12:10:54 +00:00
public function for ( Address $ao ) : self
{
$this -> tftn_p = $ao ;
$this -> fftn_p = our_address ( $ao );
return $this ;
}
/**
* Generate a packet
*
* @ param Collection $msgs
* @ return string
* @ throws InvalidPacketException
*/
public function generate ( Collection $msgs ) : string
{
$this -> messages = $msgs ;
if ( empty ( $this -> tftn_p ) || empty ( $this -> fftn_p ))
throw new InvalidPacketException ( 'Cannot generate a packet without a destination address' );
return ( string ) $this ;
}
2021-07-15 14:54:23 +00:00
/**
* Parse a message in a mail packet
*
* @ param string $message
2021-09-11 13:32:10 +00:00
* @ throws InvalidPacketException | \Exception
2021-07-15 14:54:23 +00:00
*/
2021-08-29 13:58:12 +00:00
private function parseMessage ( string $message ) : void
2021-07-15 14:54:23 +00:00
{
2023-09-20 10:29:23 +00:00
Log :: info ( sprintf ( '%s:+ Processing packet message [%d] bytes' , self :: LOGKEY , strlen ( $message )));
2021-12-29 02:44:27 +00:00
2021-08-29 13:58:12 +00:00
$msg = Message :: parseMessage ( $message , $this -> zone );
2021-07-19 14:26:12 +00:00
2024-05-17 12:10:54 +00:00
// @todo If the message from domain (eg: $msg->fftn->zone->domain) is different to the packet address domain ($pkt->fftn->zone->domain), we'll skip this message
Log :: debug ( sprintf ( '%s:^ Message [%s] - Packet from domain [%d], Message domain [%d]' , self :: LOGKEY , $msg -> msgid , $this -> fftn -> zone -> domain_id , $msg -> fftn -> zone -> domain_id ));
2023-09-20 10:29:23 +00:00
2021-07-19 14:26:12 +00:00
// If the message is invalid, we'll ignore it
2021-09-11 13:32:10 +00:00
if ( $msg -> errors ) {
2022-01-15 02:06:15 +00:00
Log :: info ( sprintf ( '%s:- Message [%s] has errors' , self :: LOGKEY , $msg -> msgid ));
2021-12-29 02:44:27 +00:00
2023-09-20 10:29:23 +00:00
// If the messages is not for the right zone, we'll ignore it
if ( $msg -> errors -> messages () -> has ( 'invalid-zone' )) {
2024-05-17 12:10:54 +00:00
Log :: alert ( sprintf ( '%s:! Message [%s] is from an invalid zone [%s], packet is from [%s] - ignoring it' , self :: LOGKEY , $msg -> msgid , $msg -> fftn -> zone -> zone_id , $this -> fftn -> zone -> zone_id ));
2023-09-20 10:29:23 +00:00
if ( ! $msg -> rescanned -> count ())
2024-05-17 12:10:54 +00:00
Notification :: route ( 'netmail' , $this -> fftn ) -> notify ( new EchomailBadAddress ( $msg ));
2023-09-20 10:29:23 +00:00
return ;
}
2024-05-17 12:10:54 +00:00
// @todo If the $msg->fftn doesnt exist, we'll need to create it
// @todo If the $msg->tftn doesnt exist (netmail), we'll need to create it (ergo intransit)
/*
2023-09-20 10:29:23 +00:00
// If the to address doenst exist, we'll create a new entry
2022-12-03 05:00:38 +00:00
if ( $msg -> errors -> messages () -> has ( 'to' ) && $msg -> tzone ) {
2022-11-06 03:40:03 +00:00
try {
2023-01-01 03:30:15 +00:00
// @todo Need to work out the correct region for the host_id
2022-11-06 03:40:03 +00:00
Address :: unguard ();
$ao = Address :: firstOrNew ([
'zone_id' => $msg -> tzone -> id ,
2023-07-06 03:55:54 +00:00
//'region_id' => 0,
2022-11-06 03:40:03 +00:00
'host_id' => $msg -> tn ,
'node_id' => $msg -> tf ,
'point_id' => $msg -> tp ,
2024-05-09 11:22:30 +00:00
'active' => TRUE , // @todo This should be false, as it hasnt been assigned to the node
2022-11-06 03:40:03 +00:00
]);
Address :: reguard ();
2023-07-06 03:55:54 +00:00
if ( is_null ( $ao -> region_id ))
$ao -> region_id = $ao -> host_id ;
2022-11-06 03:40:03 +00:00
} catch ( \Exception $e ) {
2022-11-11 11:57:40 +00:00
Log :: error ( sprintf ( '%s:! Error finding/creating TO address [%s] for message' , self :: LOGKEY , $msg -> tboss ),[ 'error' => $e -> getMessage ()]);
2022-11-06 03:40:03 +00:00
$this -> errors -> push ( $msg );
return ;
}
2023-09-15 12:57:32 +00:00
$so = System :: createUnknownSystem ();
2022-11-06 03:40:03 +00:00
$so -> addresses () -> save ( $ao );
2023-09-19 00:21:17 +00:00
Log :: alert ( sprintf ( '%s:- To FTN is not defined, creating new entry for [%s] (%d)' , self :: LOGKEY , $msg -> tboss , $ao -> id ));
2022-11-06 03:40:03 +00:00
}
2023-09-20 10:29:23 +00:00
// If the from address doenst exist, we'll create a new entry
2022-12-03 05:00:38 +00:00
if ( $msg -> errors -> messages () -> has ( 'from' ) && $msg -> tzone ) {
2021-09-12 12:09:45 +00:00
try {
2023-01-01 03:30:15 +00:00
// @todo Need to work out the correct region for the host_id
2021-09-12 12:09:45 +00:00
Address :: unguard ();
$ao = Address :: firstOrNew ([
'zone_id' => $msg -> fzone -> id ,
2023-07-06 03:55:54 +00:00
//'region_id' => 0,
2021-09-12 12:09:45 +00:00
'host_id' => $msg -> fn ,
'node_id' => $msg -> ff ,
'point_id' => $msg -> fp ,
2024-05-09 11:22:30 +00:00
'active' => TRUE , // @todo This should be FALSE as it hasnt been assigned to the node
2021-09-12 12:09:45 +00:00
]);
Address :: reguard ();
2023-07-06 03:55:54 +00:00
if ( is_null ( $ao -> region_id ))
$ao -> region_id = $ao -> host_id ;
2021-09-12 12:09:45 +00:00
} catch ( \Exception $e ) {
2022-11-11 11:57:40 +00:00
Log :: error ( sprintf ( '%s:! Error finding/creating FROM address [%s] for message' , self :: LOGKEY , $msg -> fboss ),[ 'error' => $e -> getMessage ()]);
2021-09-11 13:32:10 +00:00
$this -> errors -> push ( $msg );
return ;
}
2021-08-24 13:42:03 +00:00
2023-09-15 12:57:32 +00:00
$so = System :: createUnknownSystem ();
2021-09-11 13:32:10 +00:00
$so -> addresses () -> save ( $ao );
2023-09-19 00:21:17 +00:00
Log :: alert ( sprintf ( '%s:- From FTN is not defined, creating new entry for [%s] (%d)' , self :: LOGKEY , $msg -> fboss , $ao -> id ));
2022-11-06 03:40:03 +00:00
}
2024-05-17 12:10:54 +00:00
*/
2021-09-12 12:09:45 +00:00
2024-05-17 12:10:54 +00:00
// If the from/to user is missing
if ( $msg -> errors -> messages () -> has ( 'from' ) || $msg -> errors -> messages () -> has ( 'to' )) {
2021-09-11 13:32:10 +00:00
Log :: error ( sprintf ( '%s:! Skipping message [%s] due to errors (%s)...' , self :: LOGKEY , $msg -> msgid , join ( ',' , $msg -> errors -> messages () -> keys ())));
$this -> errors -> push ( $msg );
2024-05-17 12:10:54 +00:00
2021-09-11 13:32:10 +00:00
return ;
2021-08-24 13:42:03 +00:00
}
2021-07-19 14:26:12 +00:00
}
2021-09-11 13:32:10 +00:00
2023-09-14 22:09:42 +00:00
$this -> messages -> push ( $msg );
2021-06-29 10:43:29 +00:00
}
2023-12-13 12:00:47 +00:00
2024-05-17 12:10:54 +00:00
/** @deprecated Is this used? */
2023-12-13 12:00:47 +00:00
public function pluck ( string $key ) : Collection
{
2024-05-17 12:10:54 +00:00
throw new \Exception ( sprintf ( '%s:! This function is deprecated - [%s]' , self :: LOGKEY , $key ));
2023-12-13 12:00:47 +00:00
return $this -> messages -> pluck ( $key );
}
2021-06-29 10:43:29 +00:00
}