vito/app/Models/User.php
2025-03-12 13:31:10 +01:00

213 lines
5.3 KiB
PHP
Executable File

<?php
namespace App\Models;
use App\Enums\UserRole;
use App\Traits\HasTimezoneTimestamps;
use Carbon\Carbon;
use Filament\Models\Contracts\FilamentUser;
use Filament\Panel;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Collection;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Sanctum\HasApiTokens;
/**
* @property int $id
* @property string $name
* @property string $email
* @property string $password
* @property string $profile_photo_path
* @property string $two_factor_recovery_codes
* @property string $two_factor_secret
* @property Collection<int, SshKey> $sshKeys
* @property Collection<int, SourceControl> $sourceControls
* @property Collection<int, ServerProvider> $serverProviders
* @property Collection<int, Server> $servers
* @property Collection<int, Script> $scripts
* @property Collection<int, StorageProvider> $storageProviders
* @property Collection<int, StorageProvider> $connectedStorageProviders
* @property Collection<int, PersonalAccessToken> $tokens
* @property string $profile_photo_url
* @property string $timezone
* @property ?int $current_project_id
* @property ?Project $currentProject
* @property Collection<int, Project> $projects
* @property string $role
* @property Carbon $created_at
* @property Carbon $updated_at
*/
class User extends Authenticatable implements FilamentUser
{
use HasApiTokens;
/** @use HasFactory<\Database\Factories\UserFactory> */
use HasFactory;
use HasTimezoneTimestamps;
use Notifiable;
use TwoFactorAuthenticatable;
protected $fillable = [
'name',
'email',
'password',
'timezone',
'current_project_id',
'role',
];
protected $hidden = [
'password',
'remember_token',
'two_factor_recovery_codes',
'two_factor_secret',
];
protected $appends = [
];
/**
* @return HasMany<Server, covariant $this>
*/
public function servers(): HasMany
{
return $this->hasMany(Server::class);
}
/**
* @return HasMany<SshKey, covariant $this>
*/
public function sshKeys(): HasMany
{
return $this->hasMany(SshKey::class);
}
/**
* @return HasMany<SourceControl, covariant $this>
*/
public function sourceControls(): HasMany
{
return $this->hasMany(SourceControl::class);
}
/**
* @return HasMany<ServerProvider, covariant $this>
*/
public function serverProviders(): HasMany
{
return $this->hasMany(ServerProvider::class);
}
/**
* @return HasOne<SourceControl, covariant $this>
*/
public function sourceControl(string $provider): HasOne
{
return $this->hasOne(SourceControl::class)->where('provider', $provider);
}
/**
* @return HasMany<StorageProvider, covariant $this>
*/
public function storageProviders(): HasMany
{
return $this->hasMany(StorageProvider::class);
}
/**
* @return HasOne<StorageProvider, covariant $this>
*/
public function storageProvider(string $provider): HasOne
{
return $this->hasOne(StorageProvider::class)->where('provider', $provider);
}
/**
* @return Builder<Project>|BelongsToMany<Project, covariant $this>
*/
public function allProjects(): Builder|BelongsToMany
{
if ($this->isAdmin()) {
return Project::query();
}
return $this->projects();
}
/**
* @return BelongsToMany<Project, covariant $this>
*/
public function projects(): BelongsToMany
{
return $this->belongsToMany(Project::class, 'user_project')
->withTimestamps();
}
/**
* @return HasOne<Project, covariant $this>
*/
public function currentProject(): HasOne
{
return $this->HasOne(Project::class, 'id', 'current_project_id');
}
public function createDefaultProject(): Project
{
/** @var ?Project $project */
$project = $this->projects()->first();
if (! $project) {
$project = new Project;
$project->name = 'default';
$project->save();
$project->users()->attach($this->id);
}
$this->current_project_id = $project->id;
$this->save();
return $project;
}
public function isAdmin(): bool
{
return $this->role === UserRole::ADMIN;
}
/**
* @return HasMany<Script, covariant $this>
*/
public function scripts(): HasMany
{
return $this->hasMany(Script::class);
}
/**
* @return Builder<Server>
*/
public function allServers(): Builder
{
/** @var Builder<Server> $query */
$query = Server::query();
return $query->whereHas('project', function (Builder $query): void {
$query->whereHas('users', function ($query): void {
$query->where('user_id', $this->id);
});
});
}
public function canAccessPanel(Panel $panel): bool
{
return true;
}
}