161 lines
4.4 KiB
PHP
161 lines
4.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support\Rbac\Actions;
|
|
|
|
use App\Models\ManagedEnvironment;
|
|
use App\Models\Workspace;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use RuntimeException;
|
|
|
|
final readonly class UiActionContext
|
|
{
|
|
public const string CONTEXT_MISSING = 'context_missing';
|
|
|
|
public const string WORKSPACE_MISSING = 'workspace_missing';
|
|
|
|
public const string ENVIRONMENT_MISSING = 'environment_missing';
|
|
|
|
private function __construct(
|
|
public UiActionScope $scope,
|
|
public UiActionContextSource $source,
|
|
private ?Workspace $workspace = null,
|
|
private ?ManagedEnvironment $environment = null,
|
|
private ?Model $record = null,
|
|
private ?string $missingReason = null,
|
|
) {}
|
|
|
|
public static function forWorkspace(?Workspace $workspace, UiActionContextSource $source = UiActionContextSource::Explicit): self
|
|
{
|
|
if (! $workspace instanceof Workspace) {
|
|
return self::missing(self::WORKSPACE_MISSING, $source);
|
|
}
|
|
|
|
return new self(
|
|
scope: UiActionScope::Workspace,
|
|
source: $source,
|
|
workspace: $workspace,
|
|
);
|
|
}
|
|
|
|
public static function forEnvironment(?ManagedEnvironment $environment, UiActionContextSource $source = UiActionContextSource::Explicit): self
|
|
{
|
|
if (! $environment instanceof ManagedEnvironment) {
|
|
return self::missing(self::ENVIRONMENT_MISSING, $source);
|
|
}
|
|
|
|
return new self(
|
|
scope: UiActionScope::Environment,
|
|
source: $source,
|
|
workspace: $environment->workspace,
|
|
environment: $environment,
|
|
);
|
|
}
|
|
|
|
public static function forRecord(Model $record, UiActionContextSource $source = UiActionContextSource::Record): self
|
|
{
|
|
$environment = self::environmentFromRecord($record);
|
|
|
|
return new self(
|
|
scope: UiActionScope::Record,
|
|
source: $source,
|
|
workspace: $environment?->workspace,
|
|
environment: $environment,
|
|
record: $record,
|
|
);
|
|
}
|
|
|
|
public static function forSystem(UiActionContextSource $source = UiActionContextSource::Explicit): self
|
|
{
|
|
return new self(
|
|
scope: UiActionScope::System,
|
|
source: $source,
|
|
);
|
|
}
|
|
|
|
public static function missing(
|
|
string $reason = self::CONTEXT_MISSING,
|
|
UiActionContextSource $source = UiActionContextSource::Missing,
|
|
): self {
|
|
return new self(
|
|
scope: UiActionScope::Missing,
|
|
source: $source,
|
|
missingReason: $reason === '' ? self::CONTEXT_MISSING : $reason,
|
|
);
|
|
}
|
|
|
|
public function isMissing(): bool
|
|
{
|
|
return $this->scope === UiActionScope::Missing || $this->missingReason !== null;
|
|
}
|
|
|
|
public function missingReason(): ?string
|
|
{
|
|
return $this->missingReason;
|
|
}
|
|
|
|
public function workspace(): ?Workspace
|
|
{
|
|
return $this->workspace;
|
|
}
|
|
|
|
public function environment(): ?ManagedEnvironment
|
|
{
|
|
return $this->environment;
|
|
}
|
|
|
|
public function tenant(): ?ManagedEnvironment
|
|
{
|
|
return $this->environment();
|
|
}
|
|
|
|
public function record(): ?Model
|
|
{
|
|
return $this->record;
|
|
}
|
|
|
|
public function requireWorkspace(): Workspace
|
|
{
|
|
if ($this->workspace instanceof Workspace) {
|
|
return $this->workspace;
|
|
}
|
|
|
|
throw new RuntimeException($this->missingReason ?? self::WORKSPACE_MISSING);
|
|
}
|
|
|
|
public function requireEnvironment(): ManagedEnvironment
|
|
{
|
|
if ($this->environment instanceof ManagedEnvironment) {
|
|
return $this->environment;
|
|
}
|
|
|
|
throw new RuntimeException($this->missingReason ?? self::ENVIRONMENT_MISSING);
|
|
}
|
|
|
|
private static function environmentFromRecord(Model $record): ?ManagedEnvironment
|
|
{
|
|
if ($record instanceof ManagedEnvironment) {
|
|
return $record;
|
|
}
|
|
|
|
if (method_exists($record, 'relationLoaded') && $record->relationLoaded('tenant')) {
|
|
$tenant = $record->getRelation('tenant');
|
|
|
|
if ($tenant instanceof ManagedEnvironment) {
|
|
return $tenant;
|
|
}
|
|
}
|
|
|
|
if (method_exists($record, 'tenant')) {
|
|
$tenant = $record->getAttribute('tenant');
|
|
|
|
if ($tenant instanceof ManagedEnvironment) {
|
|
return $tenant;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|