vito/app/Models/File.php

148 lines
3.8 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* @property int $user_id
* @property int $server_id
* @property string $path
* @property string $type
* @property string $server_user
* @property string $name
* @property int $size
* @property int $links
* @property string $owner
* @property string $group
* @property string $date
* @property string $permissions
* @property User $user
* @property Server $server
*/
class File extends AbstractModel
{
use HasFactory;
protected $fillable = [
'user_id',
'server_id',
'server_user',
'path',
'type',
'name',
'size',
'links',
'owner',
'group',
'date',
'permissions',
];
protected $casts = [
'user_id' => 'integer',
'server_id' => 'integer',
'size' => 'integer',
'links' => 'integer',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
protected static function boot(): void
{
parent::boot();
static::deleting(function (File $file) {
if ($file->name === '.' || $file->name === '..') {
return false;
}
$file->server->os()->deleteFile($file->getFilePath(), $file->server_user);
return true;
});
}
public function server(): BelongsTo
{
return $this->belongsTo(Server::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public static function path(User $user, Server $server, string $serverUser): string
{
$file = self::query()
->where('user_id', $user->id)
->where('server_id', $server->id)
->where('server_user', $serverUser)
->first();
if ($file) {
return $file->path;
}
return home_path($serverUser);
}
public static function parse(User $user, Server $server, string $path, string $serverUser, string $listOutput): void
{
self::query()
->where('user_id', $user->id)
->where('server_id', $server->id)
->delete();
// Split output by line
$lines = explode("\n", trim($listOutput));
// Skip the first two lines (total count and . & .. directories)
array_shift($lines);
foreach ($lines as $line) {
if (preg_match('/^([drwx\-]+)\s+(\d+)\s+([\w\-]+)\s+([\w\-]+)\s+(\d+)\s+([\w\s:\-]+)\s+(.+)$/', $line, $matches)) {
$type = match ($matches[1][0]) {
'-' => 'file',
'd' => 'directory',
default => 'unknown',
};
if ($type === 'unknown') {
continue;
}
if ($matches[7] === '.') {
continue;
}
self::create([
'user_id' => $user->id,
'server_id' => $server->id,
'server_user' => $serverUser,
'path' => $path,
'type' => $type,
'name' => $matches[7],
'size' => (int) $matches[5],
'links' => (int) $matches[2],
'owner' => $matches[3],
'group' => $matches[4],
'date' => $matches[6],
'permissions' => $matches[1],
]);
}
}
}
public function getFilePath(): string
{
return $this->path.'/'.$this->name;
}
public function isExtractable(): bool
{
$extension = pathinfo($this->name, PATHINFO_EXTENSION);
return in_array($extension, ['zip', 'tar', 'tar.gz', 'bz2', 'tar.bz2']);
}
}