diff --git a/app/Extensions/Features/FeatureProvider.php b/app/Extensions/Features/FeatureProvider.php index 2558bd1ed..0e734ba95 100644 --- a/app/Extensions/Features/FeatureProvider.php +++ b/app/Extensions/Features/FeatureProvider.php @@ -2,50 +2,32 @@ namespace App\Extensions\Features; -use Filament\Actions\Action; -use Illuminate\Foundation\Application; +use App\Models\Egg; +use Illuminate\Database\Eloquent\Model; -abstract class FeatureProvider +class FeatureProvider { - /** - * @var array - */ - protected static array $providers = []; + /** @var FeatureSchemaInterface[] */ + private array $providers = []; - /** - * @param string[] $id - * @return self|static[] - */ - public static function getProviders(string|array|null $id = null): array|self + /** @return FeatureSchemaInterface[] | FeatureSchemaInterface */ + public function get(?string $id = null): array|FeatureSchemaInterface { - if (is_array($id)) { - return array_intersect_key(static::$providers, array_flip($id)); - } - - return $id ? static::$providers[$id] : static::$providers; + return $id ? $this->providers[$id] : $this->providers; } - protected function __construct(protected Application $app) + /** @return FeatureSchemaInterface[] */ + public function getAvailableFeatures(Egg $egg): array { - if (array_key_exists($this->getId(), static::$providers)) { - if (!$this->app->runningUnitTests()) { - logger()->warning("Tried to create duplicate Feature provider with id '{$this->getId()}'"); - } + return collect($this->providers)->intersect($egg->features)->all(); + } + public function register(FeatureSchemaInterface $provider): void + { + if (array_key_exists($provider->getId(), $this->providers)) { return; } - static::$providers[$this->getId()] = $this; + $this->providers[$provider->getId()] = $provider; } - - abstract public function getId(): string; - - /** - * A matching subset string (case-insensitive) from the console output - * - * @return array - */ - abstract public function getListeners(): array; - - abstract public function getAction(): Action; } diff --git a/app/Extensions/Features/FeatureSchemaInterface.php b/app/Extensions/Features/FeatureSchemaInterface.php new file mode 100644 index 000000000..98bfae15a --- /dev/null +++ b/app/Extensions/Features/FeatureSchemaInterface.php @@ -0,0 +1,14 @@ + */ public function getListeners(): array { @@ -114,9 +109,4 @@ class GSLToken extends FeatureProvider } }); } - - public static function register(Application $app): self - { - return new self($app); - } } diff --git a/app/Extensions/Features/JavaVersion.php b/app/Extensions/Features/Schemas/JavaVersionSchema.php similarity index 90% rename from app/Extensions/Features/JavaVersion.php rename to app/Extensions/Features/Schemas/JavaVersionSchema.php index d7f5b80d1..18ec306ba 100644 --- a/app/Extensions/Features/JavaVersion.php +++ b/app/Extensions/Features/Schemas/JavaVersionSchema.php @@ -1,7 +1,8 @@ */ public function getListeners(): array { @@ -89,9 +84,4 @@ class JavaVersion extends FeatureProvider } }); } - - public static function register(Application $app): self - { - return new self($app); - } } diff --git a/app/Extensions/Features/MinecraftEula.php b/app/Extensions/Features/Schemas/MinecraftEulaSchema.php similarity index 86% rename from app/Extensions/Features/MinecraftEula.php rename to app/Extensions/Features/Schemas/MinecraftEulaSchema.php index 7627f9fc3..980df0544 100644 --- a/app/Extensions/Features/MinecraftEula.php +++ b/app/Extensions/Features/Schemas/MinecraftEulaSchema.php @@ -1,7 +1,8 @@ */ public function getListeners(): array { @@ -64,9 +59,4 @@ class MinecraftEula extends FeatureProvider } ); } - - public static function register(Application $app): self - { - return new self($app); - } } diff --git a/app/Extensions/Features/PIDLimit.php b/app/Extensions/Features/Schemas/PIDLimitSchema.php similarity index 87% rename from app/Extensions/Features/PIDLimit.php rename to app/Extensions/Features/Schemas/PIDLimitSchema.php index dfae1d8c4..29b4abb6f 100644 --- a/app/Extensions/Features/PIDLimit.php +++ b/app/Extensions/Features/Schemas/PIDLimitSchema.php @@ -1,19 +1,14 @@ */ public function getListeners(): array { @@ -68,9 +63,4 @@ class PIDLimit extends FeatureProvider ->modalCancelActionLabel('Close') ->action(fn () => null); } - - public static function register(Application $app): self - { - return new self($app); - } } diff --git a/app/Extensions/Features/SteamDiskSpace.php b/app/Extensions/Features/Schemas/SteamDiskSpaceSchema.php similarity index 83% rename from app/Extensions/Features/SteamDiskSpace.php rename to app/Extensions/Features/Schemas/SteamDiskSpaceSchema.php index c4479a987..b6ad64a12 100644 --- a/app/Extensions/Features/SteamDiskSpace.php +++ b/app/Extensions/Features/Schemas/SteamDiskSpaceSchema.php @@ -1,19 +1,14 @@ */ public function getListeners(): array { @@ -56,9 +51,4 @@ class SteamDiskSpace extends FeatureProvider ->modalCancelActionLabel('Close') ->action(fn () => null); } - - public static function register(Application $app): self - { - return new self($app); - } } diff --git a/app/Filament/Server/Pages/Console.php b/app/Filament/Server/Pages/Console.php index 065482bfb..ff6627e92 100644 --- a/app/Filament/Server/Pages/Console.php +++ b/app/Filament/Server/Pages/Console.php @@ -6,23 +6,25 @@ use App\Enums\ConsoleWidgetPosition; use App\Enums\ContainerStatus; use App\Exceptions\Http\Server\ServerStateConflictException; use App\Extensions\Features\FeatureProvider; +use App\Extensions\Features\FeatureSchemaInterface; use App\Filament\Server\Widgets\ServerConsole; use App\Filament\Server\Widgets\ServerCpuChart; use App\Filament\Server\Widgets\ServerMemoryChart; -// use App\Filament\Server\Widgets\ServerNetworkChart; use App\Filament\Server\Widgets\ServerOverview; use App\Livewire\AlertBanner; use App\Models\Permission; use App\Models\Server; +use Filament\Actions\Action; use Filament\Actions\Concerns\InteractsWithActions; use Filament\Facades\Filament; -use Filament\Actions\Action; use Filament\Pages\Page; use Filament\Support\Enums\ActionSize; use Filament\Widgets\Widget; use Filament\Widgets\WidgetConfiguration; use Livewire\Attributes\On; +// use App\Filament\Server\Widgets\ServerNetworkChart; + class Console extends Page { use InteractsWithActions; @@ -35,6 +37,8 @@ class Console extends Page public ContainerStatus $status = ContainerStatus::Offline; + protected FeatureProvider $featureProvider; + public function mount(): void { /** @var Server $server */ @@ -51,12 +55,12 @@ class Console extends Page } } - public function boot(): void + public function boot(FeatureProvider $featureProvider): void { + $this->featureProvider = $featureProvider; /** @var Server $server */ $server = Filament::getTenant(); - /** @var FeatureProvider $feature */ - foreach ($server->egg->features() as $feature) { + foreach ($featureProvider->getAvailableFeatures($server->egg) as $feature) { $this->cacheAction($feature->getAction()); } } @@ -67,7 +71,7 @@ class Console extends Page $data = json_decode($data); $feature = data_get($data, 'key'); - $feature = FeatureProvider::getProviders($feature); + $feature = $this->featureProvider->get($feature); if ($this->getMountedAction()) { return; } diff --git a/app/Models/Egg.php b/app/Models/Egg.php index f3091016b..4d1f6139a 100644 --- a/app/Models/Egg.php +++ b/app/Models/Egg.php @@ -5,12 +5,11 @@ namespace App\Models; use App\Contracts\Validatable; use App\Exceptions\Service\Egg\HasChildrenException; use App\Exceptions\Service\HasActiveServersException; -use App\Extensions\Features\FeatureProvider; use App\Traits\HasValidation; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Support\Str; /** @@ -160,12 +159,6 @@ class Egg extends Model implements Validatable }); } - /** @return array */ - public function features(): array - { - return FeatureProvider::getProviders($this->features); - } - /** * Returns the install script for the egg; if egg is copying from another * it will return the copied script. diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 5c49ab9d3..05d927b47 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -13,11 +13,6 @@ use App\Checks\UsedDiskSpaceCheck; use App\Extensions\Avatar\Providers\GravatarProvider; use App\Extensions\Avatar\Providers\UiAvatarsProvider; use App\Extensions\Captcha\Providers\TurnstileProvider; -use App\Extensions\Features\GSLToken; -use App\Extensions\Features\JavaVersion; -use App\Extensions\Features\MinecraftEula; -use App\Extensions\Features\PIDLimit; -use App\Extensions\Features\SteamDiskSpace; use App\Models; use App\Services\Helpers\SoftwareVersionService; use Dedoc\Scramble\Scramble; @@ -105,13 +100,6 @@ class AppServiceProvider extends ServiceProvider GravatarProvider::register(); UiAvatarsProvider::register(); - // Default Feature providers - GSLToken::register($app); - JavaVersion::register($app); - MinecraftEula::register($app); - PIDLimit::register($app); - SteamDiskSpace::register($app); - FilamentColor::register([ 'danger' => Color::Red, 'gray' => Color::Zinc, diff --git a/app/Providers/Extensions/FeatureServiceProvider.php b/app/Providers/Extensions/FeatureServiceProvider.php new file mode 100644 index 000000000..1a562fc62 --- /dev/null +++ b/app/Providers/Extensions/FeatureServiceProvider.php @@ -0,0 +1,29 @@ +app->singleton(FeatureProvider::class, function ($app) { + $provider = new FeatureProvider(); + + $provider->register(new GSLTokenSchema()); + $provider->register(new JavaVersionSchema()); + $provider->register(new MinecraftEulaSchema()); + $provider->register(new PIDLimitSchema()); + $provider->register(new SteamDiskSpaceSchema()); + + return $provider; + }); + } +} diff --git a/bootstrap/providers.php b/bootstrap/providers.php index d36b7fa6c..caf780b48 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -8,6 +8,7 @@ return [ App\Providers\Filament\AdminPanelProvider::class, App\Providers\Filament\AppPanelProvider::class, App\Providers\Filament\ServerPanelProvider::class, + App\Providers\Extensions\FeatureServiceProvider::class, App\Providers\Extensions\OAuthServiceProvider::class, App\Providers\RouteServiceProvider::class, SocialiteProviders\Manager\ServiceProvider::class,