<?php namespace App\Classes\File; use Carbon\Carbon; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Storage; use App\Classes\Node; use App\Models\File as FileModel; final class File extends Send { private const LOGKEY = 'ISF'; /** @var mixed Our open file descriptor */ private mixed $fd; /** * @throws \Exception */ public function __construct(FileModel $file,int $type) { parent::__construct(); $this->f = $file; $this->ftype = ((($type&0xff)<<8)|self::IS_FILE); } public function __get($key) { switch ($key) { case 'dbids': return collect([$this->f->id]); case 'full_name': case 'nameas': return $this->f->name; case 'mtime': return $this->f->datetime->timestamp; case 'name': return $this->f->{$key}; case 'type': return ($this->ftype&0xff00)>>8; default: return parent::__get($key); } } public function close(bool $successful,Node $node): void { if ($successful) { $this->complete = TRUE; if (($this->type === Send::T_FILE) && ($x=$this->dbids)->count() && $node->aka_remote_authed->count()) DB::table('file_seenby') ->whereIn('file_id',$x) ->whereIn('address_id',$node->aka_remote_authed->pluck('id')) ->update([ 'sent_at'=>Carbon::now(), ]); } fclose($this->fd); } public function feof(): bool { return feof($this->fd); } /** * Open a file for sending * * @param string $compress The compression method that will be used (not implemented) * @return bool */ public function open(string $compress=''): bool { $this->size = $this->f->size; // If sending file is a File::class, then our file is s3 $this->fd = ($this->nameas && $this->f instanceof FileModel) ? Storage::readStream($this->f->rel_name) : fopen($this->full_name,'rb'); if (! $this->fd) { Log::error(sprintf('%s:! Unable to open file [%s] for reading',self::LOGKEY,$this->full_name)); return FALSE; } Log::info(sprintf('%s:= File [%s] opened with size [%d]',self::LOGKEY,$this->full_name,$this->size)); return TRUE; } public function read(int $length): string { return fread($this->fd,$length); } public function seek(int $pos): bool { return (fseek($this->fd,$pos,SEEK_SET) === 0); } }