clrghouz/app/Models/File.php

233 lines
6.0 KiB
PHP
Raw Normal View History

2022-11-01 11:24:36 +00:00
<?php
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
2022-11-01 11:24:36 +00:00
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
2022-11-01 11:24:36 +00:00
use Rennokki\QueryCache\Traits\QueryCacheable;
use App\Casts\{CollectionOrNull,CompressedString};
use App\Traits\EncodeUTF8;
class File extends Model
{
use SoftDeletes,EncodeUTF8,QueryCacheable;
private const LOGKEY = 'MF-';
private bool $no_export = FALSE;
public string $prefix = '';
public Collection $set_path;
public Collection $set_seenby;
2022-11-01 11:24:36 +00:00
protected $casts = [
'kludges' => CollectionOrNull::class,
'datetime' => 'datetime:Y-m-d H:i:s',
2022-11-01 11:24:36 +00:00
'desc' => CompressedString::class,
'ldesc' => CompressedString::class,
'rogue_seenby' => CollectionOrNull::class,
'rogue_path' => CollectionOrNull::class,
2022-11-01 11:24:36 +00:00
'size' => 'int',
];
private const cast_utf8 = [
'desc',
'ldesc',
];
public static function boot()
{
parent::boot();
static::creating(function($model) {
if (! $model->filearea_id) {
Log::alert(sprintf('%s:- File has no filearea, not processing creating [%s]',self::LOGKEY,$model->name));
return;
}
Log::info(sprintf('%s:- Storing file [%s] in [%s]',self::LOGKEY,$model->recvd_rel_name,$model->rel_name));
$srcfs = Storage::disk(config('fido.local_disk'));
$tgtfs = Storage::disk(config('fido.file_disk'));
// Delete anything being replaced
foreach (self::where('name',$model->name)->where('filearea_id',$model->filearea_id)->get() as $fo) {
Log::info(sprintf('%s:%% Deleting old file record [%d] for file [%s]',self::LOGKEY,$fo->id,$fo->rel_name));
$tgtfs->move($fo->rel_name,$fo->relname.'.'.$fo->id);
$fo->delete();
}
2022-11-01 11:24:36 +00:00
// Store file
if ($tgtfs->put($model->rel_name,$srcfs->get($model->recvd_rel_name),'public')) {
$srcfs->delete($model->recvd_rel_name);
} else {
throw new \Exception(sprintf('Unable to move file [%s] to [%s]',$model->recvd_rel_name,$model->rel_name));
2023-06-27 07:39:11 +00:00
}
2022-11-01 11:24:36 +00:00
});
// @todo if the file 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->filearea_id) {
Log::alert(sprintf('%s:- File has no filearea, not exporting [%d]',self::LOGKEY,$model->id));
2022-11-01 11:24:36 +00:00
return;
}
$rogue = collect();
$seenby = collect();
$path = collect();
2022-11-01 11:24:36 +00:00
$so = Setup::findOrFail(config('app.id'));
$zone = $model->fftn->zone;
2022-11-01 11:24:36 +00:00
// Parse PATH
foreach ($model->set_path as $line) {
$matches = [];
preg_match(sprintf('#^(%s)\ ?([0-9]+)\ ?(.*)$#',Address::ftn_regex),$line,$matches);
2022-11-01 11:24:36 +00:00
if ($x=Arr::get($matches,1)) {
$ftn = Address::parseFTN($x);
2022-11-01 11:24:36 +00:00
// If domain should be flattened, look for node regardless of zone (within the list of zones for the domain)
$ao = ($zone->domain->flatten)
? Address::findZone($zone->domain,$ftn['n'],$ftn['f'],0)
: Address::findFTN($x);
if (! $ao)
$ao = Address::createFTN($x,System::createUnknownSystem());
$path->push(['address'=>$ao,'datetime'=>Carbon::createFromTimestamp($matches[9]),'extra'=>$matches[10]]);
}
}
2022-11-01 11:24:36 +00:00
// Save the Path
$ppoid = NULL;
foreach ($path as $item) {
2022-11-01 11:24:36 +00:00
$po = DB::select('INSERT INTO file_path (file_id,address_id,parent_id,datetime,extra) VALUES (?,?,?,?,?) RETURNING id',[
$model->id,
$item['address']->id,
2022-11-01 11:24:36 +00:00
$ppoid,
$item['datetime'],
$item['extra'],
2022-11-01 11:24:36 +00:00
]);
$ppoid = $po[0]->id;
}
// Make sure all the path is in the seenby
// Add zone to seenby
$model->set_seenby = $model->set_seenby->merge($path->pluck('address.ftn3d'))->unique()->filter();
foreach ($model->set_seenby as $sb) {
$ftn = Address::parseFTN($x);
$ao = ($zone->domain->flatten)
? Address::findZone($zone->domain,$ftn['n'],$ftn['f'],0)
: Address::findFTN($x);
if ($ao)
$seenby->push($ao->id);
else
$rogue->push($sb);
}
$model->rogue_seenby = $rogue;
$model->seenby()->sync($seenby);
$model->save();
2023-09-05 09:57:34 +00:00
// See if we need to export this file.
2023-07-29 03:17:36 +00:00
if ($model->filearea->sec_read) {
$exportto = $model
->filearea
->addresses
2023-09-05 09:57:34 +00:00
->filter(function($item) use ($model) { return $item->security >= $model->filearea->sec_read; })
2023-07-29 03:17:36 +00:00
->pluck('id')
->diff($model->set_seenby);
if ($exportto->count()) {
if ($model->no_export) {
Log::alert(sprintf('%s:- NOT processing exporting of message by configuration [%s] to [%s]',self::LOGKEY,$model->id,$exportto->join(',')));
2023-07-29 03:17:36 +00:00
return;
}
Log::info(sprintf('%s:- Exporting file [%s] to [%s]',self::LOGKEY,$model->id,$exportto->join(',')));
2023-07-29 03:17:36 +00:00
// Save the seenby for the exported systems
$model->seenby()->syncWithPivotValues($exportto,['export_at'=>Carbon::now()],FALSE);
2022-11-01 11:24:36 +00:00
}
}
});
}
/* RELATIONS */
public function filearea()
{
return $this->belongsTo(Filearea::class);
}
public function fftn()
{
return $this->belongsTo(Address::class)
->withTrashed();
}
public function seenby()
{
return $this->belongsToMany(Address::class,'file_seenby')
->ftnOrder();
}
public function path()
{
return $this->belongsToMany(Address::class,'file_path')
->withPivot(['id','parent_id','datetime','extra']);
2022-11-01 11:24:36 +00:00
}
/* ATTRIBUTES */
/**
* Return the relative path to Storage::disk() in the store
*
* @return string
*/
public function getRelNameAttribute(): string
{
return sprintf('%04X/%s',$this->filearea_id,$this->name);
}
/**
* Return the relative path to Storage::disk() in the inbound;
*
* @return string
*/
public function getRecvdRelNameAttribute(): string
{
return sprintf('%s/%s',config('fido.dir'),$this->recvd_pref_name);
}
/**
* This is the name of the file, with the sender prefix
*
* @return string
*/
public function getRecvdPrefNameAttribute(): string
{
return sprintf('%s%s',$this->prefix ? $this->prefix.'-' : '',$this->name);
}
2022-11-01 11:24:36 +00:00
/* METHODS */
public function jsonSerialize(): array
{
return $this->encode();
}
}