Captures the current working tree after theme slots, ArticleAccess, and the payment / paid-content plugins so subsequent work has a reviewable git history.
126 lines
4.0 KiB
PHP
126 lines
4.0 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace App\Filament\Pages;
|
||
|
||
use App\Domain\Plugin\PluginManager;
|
||
use App\Models\Plugin;
|
||
use BackedEnum;
|
||
use Filament\Actions\Action;
|
||
use Filament\Notifications\Notification;
|
||
use Filament\Pages\Page;
|
||
use Filament\Support\Icons\Heroicon;
|
||
use UnitEnum;
|
||
|
||
class ManagePlugins extends Page
|
||
{
|
||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedPuzzlePiece;
|
||
|
||
protected static ?int $navigationSort = 81;
|
||
|
||
protected string $view = 'filament.pages.manage-plugins';
|
||
|
||
/** @var array<int, array<string, mixed>> */
|
||
public array $plugins = [];
|
||
|
||
public static function getNavigationGroup(): ?string
|
||
{
|
||
return __('admin.groups.system');
|
||
}
|
||
|
||
public static function getNavigationLabel(): string
|
||
{
|
||
return __('admin.nav.plugins');
|
||
}
|
||
|
||
public function getTitle(): string
|
||
{
|
||
return __('admin.pages.plugins_title');
|
||
}
|
||
|
||
public function mount(PluginManager $manager): void
|
||
{
|
||
$manager->syncDiscoveredPlugins();
|
||
$this->reload($manager);
|
||
}
|
||
|
||
public function enable(string $name, PluginManager $manager): void
|
||
{
|
||
try {
|
||
$manager->enable($name);
|
||
$this->reload($manager);
|
||
Notification::make()->title(__('admin.pages.enable').':'.$name)->success()->send();
|
||
} catch (\Throwable $e) {
|
||
Notification::make()->title($e->getMessage())->danger()->send();
|
||
}
|
||
}
|
||
|
||
public function disable(string $name, PluginManager $manager): void
|
||
{
|
||
try {
|
||
$manager->disable($name);
|
||
$this->reload($manager);
|
||
Notification::make()->title(__('admin.pages.disable').':'.$name)->success()->send();
|
||
} catch (\Throwable $e) {
|
||
Notification::make()->title($e->getMessage())->danger()->send();
|
||
}
|
||
}
|
||
|
||
public function showDocs(string $name, PluginManager $manager): void
|
||
{
|
||
$docs = $manager->readDocs($name);
|
||
if ($docs === null || trim($docs) === '') {
|
||
Notification::make()->title(__('admin.messages.plugin_docs_missing'))->warning()->send();
|
||
|
||
return;
|
||
}
|
||
|
||
Notification::make()
|
||
->title(__('admin.pages.plugin_docs'))
|
||
->body(str($docs)->limit(1800)->toString())
|
||
->persistent()
|
||
->info()
|
||
->send();
|
||
}
|
||
|
||
protected function reload(PluginManager $manager): void
|
||
{
|
||
$discovered = $manager->discover();
|
||
$records = Plugin::query()->get()->keyBy('name');
|
||
$accents = ['#0f8a7a', '#c45c26', '#2563eb', '#7c3aed', '#db2777', '#0891b2'];
|
||
|
||
$this->plugins = $discovered->values()->map(function (array $manifest, int $index) use ($records, $accents, $manager) {
|
||
$name = (string) $manifest['name'];
|
||
$titleKey = 'admin.plugins.'.$name.'.title';
|
||
$descKey = 'admin.plugins.'.$name.'.description';
|
||
$record = $records->get($name);
|
||
$requires = (array) ($manifest['requires'] ?? []);
|
||
|
||
return [
|
||
'name' => $name,
|
||
'title' => __($titleKey) !== $titleKey ? __($titleKey) : ($manifest['title'] ?? $name),
|
||
'version' => $manifest['version'] ?? '1.0.0',
|
||
'description' => __($descKey) !== $descKey ? __($descKey) : ($manifest['description'] ?? ''),
|
||
'enabled' => (bool) ($record?->enabled),
|
||
'requires' => $requires,
|
||
'has_docs' => $manager->docsPath($name) !== null,
|
||
'accent' => $accents[$index % count($accents)],
|
||
];
|
||
})->all();
|
||
}
|
||
|
||
protected function getHeaderActions(): array
|
||
{
|
||
return [
|
||
Action::make('sync')
|
||
->label(__('admin.pages.plugins_sync'))
|
||
->action(function (PluginManager $manager): void {
|
||
$manager->syncDiscoveredPlugins();
|
||
$this->reload($manager);
|
||
Notification::make()->title(__('admin.pages.plugins_sync'))->success()->send();
|
||
}),
|
||
];
|
||
}
|
||
}
|