'datetime:Y-m-d H:i:s', 'msg' => CompressedString::class, 'msg_src' => CompressedString::class, 'sent_at' => 'datetime:Y-m-d H:i:s', ]; public function __set($key,$value) { switch ($key) { case 'set_path': case 'set_pkt': case 'set_sender': $this->{$key} = $value; break; default: parent::__set($key,$value); } } public static function boot() { parent::boot(); static::created(function($model) { // Save the Path $ppoid = NULL; if (isset($model->set_path)) { // If there are no details (Mystic), we'll create a blank if (! $model->set_path->count()) { $model->set_path->push(['node'=>$model->set_sender,'datetime'=>Carbon::now(),'program'=>'Unknown']); } foreach ($model->set_path as $path) { $po = DB::select('INSERT INTO netmail_path (netmail_id,address_id,parent_id,datetime,program) VALUES (?,?,?,?,?) RETURNING id',[ $model->id, $path['node']->id, $ppoid, (string)$path['datetime'], $path['program'], ]); $ppoid = $po[0]->id; } if (isset($model->set_pkt) && isset($model->set_sender)) { DB::update('UPDATE netmail_path set recv_pkt=?,recv_id=? where address_id=?',[ $model->set_pkt, $model->set_sender->id, Arr::get($model->set_path->last(),'node')->id, ]); } } }); } /* RELATIONS */ public function fftn() { return $this ->belongsTo(Address::class) ->withTrashed(); } public function path() { return $this->belongsToMany(Address::class,'netmail_path') ->withPivot(['id','parent_id','datetime','program','recv_pkt','recv_id']); } public function received() { return $this->belongsToMany(Address::class,'netmail_path','netmail_id','recv_id') ->withPivot(['id','parent_id','datetime','program','recv_pkt','recv_id']); } public function tftn() { return $this ->belongsTo(Address::class); } /* METHODS */ /** * 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; try { $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; // INTL kludge // @todo Point handling FMPT/TOPT $o->intl = sprintf('%s %s',$this->tftn->ftn3d,$this->fftn->ftn3d); $o->flags = $this->flags; $o->msgid = sprintf('%s %08x',$this->fftn->ftn3d,crc32($this->id)); if ($this->replyid) $o->replyid = $this->replyid; $o->kludge->put('dbid',$this->id); $o->message = $this->msg; $o->tagline = $this->tagline; $o->tearline = $this->tearline; // VIA kludge $sysaddress = Setup::findOrFail(config('app.id'))->system->match($this->fftn->zone)->first(); $via = $this->via ?: collect(); $via->push( sprintf('%s @%s.UTC %s %d.%d/%s %s', $sysaddress->ftn3d, Carbon::now()->utc()->format('Ymd.His'), str_replace(' ','_',Setup::PRODUCT_NAME), Setup::PRODUCT_VERSION_MAJ, Setup::PRODUCT_VERSION_MIN, (new Setup)->version, Carbon::now()->format('Y-m-d'), )); $o->via = $via; $o->packed = TRUE; } catch (\Exception $e) { Log::error(sprintf('%s:Error converting netmail [%s] to a message (%d:%s)',self::LOGKEY,$this->id,$e->getLine(),$e->getMessage())); dump($this); } return $o; } public function pathorder(string $display='ftn2d',int $start=NULL): Collection { $result = collect(); if ($x=$this->path->firstWhere('pivot.parent_id',$start)) { $result->push($x->$display); $result->push($this->pathorder($display,$x->pivot->id)); } return $result->flatten()->filter(); } }