141 lines
4.7 KiB
PHP
141 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Traits\HasCreatorAndUpdater;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Str;
|
|
use Kalnoy\Nestedset\NodeTrait;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Kalnoy\NestedSet\DescendantsRelation;
|
|
|
|
class File extends Model
|
|
{
|
|
use HasFactory, HasCreatorAndUpdater, NodeTrait, SoftDeletes; // adds node and recycle bin functionality to files
|
|
|
|
// returns the user this file or folder belongs to
|
|
public function user(): BelongsTo {
|
|
return $this->belongsTo(User::class, 'created_by');
|
|
}
|
|
|
|
// returns the parent file or folder for this file or folder
|
|
public function parent(): BelongsTo {
|
|
return $this->belongsTo(File::class, 'parent_id');
|
|
}
|
|
|
|
// returns whether or not the current folder is a root-level folder
|
|
public function isRoot() {
|
|
// is there a parent_id for this folder?
|
|
return $this->parent_id == null;
|
|
}
|
|
|
|
// returns simple boolean whether or not the passed userID is the creator of the file
|
|
public function isOwner($userID): bool
|
|
{
|
|
return $this->created_by = $userID;
|
|
}
|
|
|
|
// returns formatted size
|
|
public function formatSize($size) {
|
|
// maximum file size is in the GB range
|
|
$sizeUnits = ['B', 'KB', 'MB', 'GB'];
|
|
// floor() the size and get the amount of times 1024 fits into it
|
|
$power = $size > 0 ? floor(log($size, 1024)) : 0;
|
|
// calculate output by dividing total size by $power * 1024 then adding relevant $sizeUnit based on $power ($power can be no greater than 3 - no bigger than GB's)
|
|
$output = number_format(($size / pow(1024, $power)), 2, ".", ",") . " " . $sizeUnits[$power];
|
|
return $output;
|
|
}
|
|
|
|
// outputs correct sizes for folders
|
|
public function getFolderSize() {
|
|
$sum = [];
|
|
// call recursive function, then sum
|
|
$this->recurseChildren($this->children, $sum);
|
|
$sum = array_sum($sum);
|
|
// return $sum
|
|
return $sum;
|
|
}
|
|
|
|
// shred $this file
|
|
public function shred() {
|
|
// recursively shred all of $this
|
|
$this->recursiveShred([$this]);
|
|
// also call force delete
|
|
$this->forceDelete();
|
|
}
|
|
|
|
// additional bootstrapping on top of default Model model
|
|
protected static function boot()
|
|
{
|
|
// start with parent Model
|
|
parent::boot();
|
|
|
|
// define new bootstrapping
|
|
static::creating(function ($model) {
|
|
// check for parent - if one exists, exit function
|
|
if (!$model->parent) return;
|
|
|
|
// if file or folder is NOT a root-level folder
|
|
if (!$model->parent->isRoot()) {
|
|
// path is a node off the parent path
|
|
$model->path = $model->parent->path . '/';
|
|
}
|
|
// otherwise free-standing
|
|
else $model->path = '';
|
|
|
|
// append current file or folder name to path name
|
|
$model->path = $model->path . Str::slug($model->name);
|
|
});
|
|
|
|
// define delete function
|
|
static::deleted(function (File $file) {
|
|
// if file is a regular file (not a folder)
|
|
if (!$file->is_folder) {
|
|
// delete file from file system
|
|
Storage::delete($file->stored_at);
|
|
}
|
|
});
|
|
}
|
|
|
|
// moves $this file to recycle bin
|
|
private function recycle() {
|
|
// set this file's deleted_at to now
|
|
$this->deleted_at = Carbon::now();
|
|
// save record
|
|
return $this->save();
|
|
}
|
|
|
|
// recursively shred $queued files
|
|
private function recursiveShred($queued) {
|
|
// get children of parent and determine whether recursive function needs to be called
|
|
foreach ($queued as $file) {
|
|
// if there are no children, delete file
|
|
if ($file->children->isEmpty()) {
|
|
Storage::delete($file->stored_at);
|
|
// continue loop
|
|
continue;
|
|
}
|
|
// else recurse
|
|
$this->recursiveShred($file->children);
|
|
}
|
|
}
|
|
|
|
// get all children and subchildren
|
|
private function recurseChildren ($files, &$total) {
|
|
// go through each file in queue
|
|
foreach($files as $file) {
|
|
// push to array since it is a child
|
|
array_push($total, $file->size);
|
|
// iterate to next file in $queue if no more children
|
|
if (!$file->children) {
|
|
continue;
|
|
}
|
|
// else recurse on $current file children
|
|
$this->recurseChildren($file->children, $total);
|
|
}
|
|
}
|
|
}
|