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); } } }