174 lines
4.4 KiB
PHP
174 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Carbon\Carbon;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\File as FileFacade;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Storage;
|
|
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;
|
|
|
|
protected $casts = [
|
|
'kludges' => CollectionOrNull::class,
|
|
'rogue_seenby' => CollectionOrNull::class,
|
|
'rogue_path' => CollectionOrNull::class,
|
|
'desc' => CompressedString::class,
|
|
'ldesc' => CompressedString::class,
|
|
'size' => 'int',
|
|
];
|
|
|
|
private const cast_utf8 = [
|
|
'desc',
|
|
'ldesc',
|
|
];
|
|
|
|
protected $dates = ['datetime'];
|
|
|
|
public function __set($key,$value)
|
|
{
|
|
switch ($key) {
|
|
case 'fullname':
|
|
case 'replaces':
|
|
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();
|
|
|
|
static::creating(function($model) {
|
|
Log::debug(sprintf('%s:- Storing file [%s] in [%s]',self::LOGKEY,$model->fullname,$model->full_storage_path));
|
|
|
|
// Store file
|
|
if (Storage::put($model->full_storage_path,Storage::disk('local')->get($model->fullname),'public')) {
|
|
unlink(Storage::disk('local')->path($model->fullname));
|
|
} else {
|
|
throw new \Exception(sprintf('Unable to move file [%s] to [%s]',$model->fullname,$model->full_storage_path));
|
|
};
|
|
|
|
// Delete anything being replaced
|
|
// @todo implement replace
|
|
});
|
|
|
|
// @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',self::LOGKEY,$model->id));
|
|
return;
|
|
}
|
|
|
|
$so = Setup::findOrFail(config('app.id'));
|
|
|
|
// Our address
|
|
$ftns = $so
|
|
->system
|
|
->match($model->fftn->zone,Address::NODE_ACTIVE|Address::NODE_PVT|Address::NODE_HOLD);
|
|
|
|
// Add our address to the seenby;
|
|
$model->set_seenby = $model->set_seenby->merge($ftns->pluck('id'))->unique();
|
|
$model->set_path = $model->set_path->merge([[
|
|
'address'=>$ftns->first(),
|
|
'datetime'=>($x=Carbon::now())->timestamp,
|
|
'extra'=>sprintf('%s %s (%s)',$x->toRfc7231String(),$so::PRODUCT_NAME,$so->version),
|
|
]]);
|
|
|
|
// Make sure all the path is in the seenby
|
|
$model->set_seenby = $model->set_seenby->merge($model->set_path->pluck('address.id'))->unique();
|
|
|
|
// Save the seenby
|
|
$model->seenby()->sync($model->set_seenby);
|
|
|
|
// Save the Path
|
|
$ppoid = NULL;
|
|
foreach ($model->set_path as $path) {
|
|
$po = DB::select('INSERT INTO file_path (file_id,address_id,parent_id,datetime,extra) VALUES (?,?,?,?,?) RETURNING id',[
|
|
$model->id,
|
|
$path['address']->id,
|
|
$ppoid,
|
|
Carbon::createFromTimestamp($path['datetime']),
|
|
$path['extra'],
|
|
]);
|
|
|
|
$ppoid = $po[0]->id;
|
|
}
|
|
|
|
// See if we need to export this message.
|
|
$exportto = $model->filearea->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 file [%s] to [%s]',self::LOGKEY,$model->id,$exportto->join(',')));
|
|
|
|
// Save the seenby for the exported systems
|
|
$model->seenby()->syncWithPivotValues($exportto,['export_at'=>Carbon::now()],FALSE);
|
|
}
|
|
});
|
|
}
|
|
|
|
/* 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','extra']);
|
|
}
|
|
|
|
/* ATTRIBUTES */
|
|
|
|
public function getFullStoragePathAttribute(): string
|
|
{
|
|
return sprintf('%04X/%s',$this->filearea_id,$this->file);
|
|
}
|
|
|
|
/* METHODS */
|
|
|
|
public function jsonSerialize(): array
|
|
{
|
|
return $this->encode();
|
|
}
|
|
}
|