<?php
namespace App\Enums\Acl;
use App\Exceptions\KoelPlusRequiredException;
use App\Facades\License;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Collection;
enum Role: string implements Arrayable
{
case ADMIN = 'admin';
case MANAGER = 'manager';
case USER = 'user';
public function label(): string
{
return match ($this) {
self::ADMIN => 'Admin',
self::MANAGER => 'Manager',
self::USER => 'User',
};
}
public static function default(): self
{
return self::USER;
}
public function level(): int
{
return match ($this) {
self::ADMIN => 3,
self::MANAGER => 2,
self::USER => 1,
};
}
public function greaterThan(self $other): bool
{
return $this->level() > $other->level();
}
public function lessThan(self $other): bool
{
return $this->level() < $other->level();
}
public function canManage(self $other): bool
{
return $this->level() >= $other->level();
}
public function available(): bool
{
return match ($this) {
self::ADMIN, self::USER => true,
self::MANAGER => once(static fn () => License::isPlus()),
};
}
public function assertAvailable(): void
{
throw_unless($this->available(), KoelPlusRequiredException::class);
}
public static function allAvailable(): Collection
{
return collect(self::cases())->filter(static fn (Role $role) => $role->available());
}
public function description(): string
{
$isCommunity = once(static fn () => License::isCommunity());
return match ($this) {
self::ADMIN => 'Admins can manage everything.',
self::MANAGER => $isCommunity
? 'Managers can manage users, upload musics, and perform other management tasks.'
: 'Managers can manage users and perform other management tasks.',
self::USER => $isCommunity
? 'Users can play music and manage their own playlists.'
: 'Users can upload and manage their own music.',
};
}
public function toArray(): array
{
return [
'id' => $this->value,
'label' => $this->label(),
'level' => $this->level(),
'is_default' => $this === self::default(),
'description' => $this->description(),
];
}
}