<?php namespace App\Models; use Carbon\Carbon; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use Rennokki\QueryCache\Traits\QueryCacheable; use App\Classes\FTN\Message; use App\Interfaces\Packet; use App\Traits\{EncodeUTF8,MsgID}; final class Echomail extends Model implements Packet { use SoftDeletes,EncodeUTF8,MsgID,QueryCacheable; private const LOGKEY = 'ME-'; private array $set_seenby = []; private array $set_path = []; private ?string $set_packet = NULL; private bool $no_export = FALSE; protected $casts = [ 'kludges' => 'json', 'rogue_seenby' => 'json', 'rogue_path' => 'json', ]; private const cast_utf8 = [ 'to', 'from', 'subject', 'msg', 'origin', 'tearline', 'tagline', ]; protected $dates = ['datetime']; public function __set($key, $value) { switch ($key) { case 'no_export': case 'set_path': case 'set_packet': case 'set_seenby': $this->{$key} = $value; break; default: parent::__set($key,$value); } } public static function boot() { parent::boot(); // @todo if the message is updated with new SEEN-BY's from another route, we'll delete the pending export for systems (if there is one) static::created(function($model) { if (! $model->echoarea_id) { Log::alert(sprintf('%s:- Message has no echo area, not exporting',self::LOGKEY,$model->id)); return; } // Save the seenby foreach ($model->set_seenby as $aoid) { DB::insert('INSERT INTO echomail_seenby (echomail_id,address_id,packet) VALUES (?,?,?)',[ $model->id, $aoid, $model->set_packet, ]); } // Save the Path $ppoid = NULL; foreach ($model->set_path as $aoid) { $po = DB::select('INSERT INTO echomail_path (echomail_id,address_id,parent_id) VALUES (?,?,?) RETURNING id',[ $model->id, $aoid, $ppoid, ]); $ppoid = $po[0]->id; } // See if we need to export this message. $exportto = $model->echoarea->addresses->pluck('id')->diff($model->set_seenby); if ($exportto->count()) { if ($model->no_export) { Log::debug(sprintf('%s:- NOT processing exporting of message by configuration [%s] to [%s]',self::LOGKEY,$model->id,$exportto->join(','))); return; } Log::debug(sprintf('%s:- Exporting message [%s] to [%s]',self::LOGKEY,$model->id,$exportto->join(','))); // Save the seenby for the exported systems $export_at = Carbon::now(); foreach ($exportto as $aoid) { DB::insert('INSERT INTO echomail_seenby (echomail_id,address_id,export_at) VALUES (?,?,?)',[ $model->id, $aoid, $export_at, ]); } } }); } /* RELATIONS */ public function echoarea() { return $this->belongsTo(Echoarea::class); } public function fftn() { return $this->belongsTo(Address::class) ->withTrashed(); } public function seenby() { return $this->belongsToMany(Address::class,'echomail_seenby') ->ftnOrder(); } public function path() { return $this->belongsToMany(Address::class,'echomail_path'); } /* METHODS */ public function jsonSerialize(): array { return $this->encode(); } /** * Return this model as a packet */ public function packet(Address $ao): Message { Log::debug(sprintf('%s:Bundling [%s]',self::LOGKEY,$this->id)); // @todo Dont bundle mail to nodes that have been disabled, or addresses that have been deleted $o = new Message; $o->header = [ 'onode' => $this->fftn->node_id, 'dnode' => $ao->node_id, 'onet' => $this->fftn->host_id, 'dnet' => $ao->host_id, 'flags' => 0, // @todo? 'cost' => 0, 'date'=>$this->datetime->format('d M y H:i:s'), ]; $o->tzutc = $this->datetime->utcOffset($this->tzoffset)->getOffsetString(''); $o->user_to = $this->to; $o->user_from = $this->from; $o->subject = $this->subject; $o->echoarea = $this->echoarea->name; $o->flags = $this->flags; if ($this->kludges) $o->kludge = $this->kludges; $o->kludge->put('dbid',$this->id); $o->msgid = $this->msgid; if ($this->replyid) $o->replyid = $this->replyid; $o->message = $this->msg; if ($this->tagline) $o->tagline = $this->tagline; if ($this->tearline) $o->tearline = $this->tearline; if ($this->origin) $o->origin = $this->origin; // @todo SEENBY // @todo PATH $o->packed = TRUE; return $o; } }