Files
Virtnet.bond/extensions/Servers/ManualServers/Admin/Pages/ManualServersManage.php
2026-03-12 22:47:38 +01:00

253 lines
11 KiB
PHP

<?php
namespace Paymenter\Extensions\Servers\ManualServers\Admin\Pages;
use App\Models\Service;
use Filament\Actions\Action;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Paymenter\Extensions\Servers\ManualServers\ManualServers;
class ManualServersManage extends Page implements HasForms
{
use InteractsWithForms;
protected static string|\BackedEnum|null $navigationIcon = 'ri-hard-drive-3-line';
protected string $view = 'manual-servers::admin.pages.manual-servers-manage';
protected static bool $shouldRegisterNavigation = false;
protected static ?string $slug = 'manual-servers-manage/{service}';
public ?Service $service = null;
public array $processData = [];
public array $credentialData = [];
public array $credentialFields = [];
public string $deployStatus = 'pending';
public string $feedback = '';
public function mount(Service $service): void
{
$this->service = $service->load(['user', 'product', 'product.server', 'product.server.settings', 'product.settings', 'properties']);
$this->loadServiceData();
}
protected function loadServiceData(): void
{
$server = $this->service->product->server;
if (!$server || $server->extension !== 'ManualServers') {
Notification::make()
->title('Invalid Server')
->body('This service does not use the ManualServers extension.')
->danger()
->send();
$this->redirect(ManualServersQueue::getUrl());
return;
}
$config = $server->settings->pluck('value', 'key')->toArray();
$extension = new ManualServers($config);
$data = $extension->getServiceData($this->service);
$this->deployStatus = $data['status'];
$this->processData = $data['processes'];
$this->credentialData = $data['credentials'];
$this->credentialFields = $data['credential_fields'];
$this->feedback = $data['feedback'];
}
public function getTitle(): string
{
return 'Manual Server #' . $this->service?->id;
}
public static function canAccess(): bool
{
return auth()->check() && auth()->user()->can('viewAny', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class);
}
protected function getHeaderActions(): array
{
return [];
}
public function toggleProcess(int $index): void
{
abort_unless(auth()->user()?->can('manage', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class), 403);
$server = $this->service->product->server;
$config = $server->settings->pluck('value', 'key')->toArray();
$extension = new ManualServers($config);
$currentStatus = $this->processData[$index]['completed'] ?? false;
$extension->updateProcessStatus($this->service, $index, !$currentStatus);
$this->service->refresh();
$this->loadServiceData();
Notification::make()
->title(!$currentStatus ? 'Setup Step Completed' : 'Setup Step Reverted')
->success()
->send();
}
public function deployAction(): Action
{
$fields = [];
foreach ($this->credentialFields as $field) {
$type = $field['type'] ?? 'text';
if ($type === 'textarea') {
$fields[] = Textarea::make($field['name'])
->label($field['label'])
->required();
} elseif ($type === 'password') {
$fields[] = TextInput::make($field['name'])
->label($field['label'])
->password()
->required();
} else {
$fields[] = TextInput::make($field['name'])
->label($field['label'])
->required();
}
}
return Action::make('deploy')
->label('Deploy Server')
->color('success')
->requiresConfirmation()
->modalHeading('Deploy Manual Server')
->modalDescription('Enter the server credentials to provide to the client.')
->form($fields)
->action(function (array $data): void {
abort_unless(auth()->user()?->can('deploy', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class), 403);
$server = $this->service->product->server;
$config = $server->settings->pluck('value', 'key')->toArray();
$extension = new ManualServers($config);
$extension->deployService($this->service, $data);
$this->service->refresh();
$this->loadServiceData();
Notification::make()
->title('Server Deployed')
->body('Server credentials have been saved and the server is now marked as deployed.')
->success()
->send();
})
->visible(fn () => auth()->user()?->can('deploy', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class) && $this->areAllProcessesCompleted() && $this->deployStatus !== 'deployed');
}
public function editCredentialsAction(): Action
{
$fields = [];
foreach ($this->credentialFields as $field) {
$type = $field['type'] ?? 'text';
$defaultValue = $this->credentialData[$field['name']] ?? '';
if ($type === 'textarea') {
$fields[] = Textarea::make($field['name'])
->label($field['label'])
->default($defaultValue)
->required();
} elseif ($type === 'password') {
$fields[] = TextInput::make($field['name'])
->label($field['label'])
->default($defaultValue)
->password()
->required();
} else {
$fields[] = TextInput::make($field['name'])
->label($field['label'])
->default($defaultValue)
->required();
}
}
return Action::make('editCredentials')
->label('Edit Server Credentials')
->color('warning')
->modalHeading('Edit Server Credentials')
->modalDescription('Update the server credentials that were provided to the client.')
->form($fields)
->action(function (array $data): void {
abort_unless(auth()->user()?->can('credentials', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class), 403);
$this->service->properties()->updateOrCreate(
['key' => 'credentials_data'],
['value' => json_encode($data)]
);
$this->service->refresh();
$this->loadServiceData();
Notification::make()
->title('Server Credentials Updated')
->body('The server credentials have been updated successfully.')
->success()
->send();
})
->visible(fn () => auth()->user()?->can('credentials', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class) && $this->deployStatus === 'deployed' && !empty($this->credentialData));
}
public function reverseDeploymentAction(): Action
{
return Action::make('reverseDeployment')
->label('Reverse Deployment')
->color('danger')
->requiresConfirmation()
->modalHeading('Reverse Deployment')
->modalDescription('This will set the server back to pending, clear credentials, and reset all setup steps.')
->action(function (): void {
abort_unless(auth()->user()?->can('manage', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class), 403);
$server = $this->service->product->server;
$config = $server->settings->pluck('value', 'key')->toArray();
$extension = new ManualServers($config);
$extension->reverseDeployment($this->service, true);
$this->service->refresh();
$this->loadServiceData();
Notification::make()
->title('Deployment Reversed')
->body('Server is set back to pending and setup steps are reset.')
->success()
->send();
})
->visible(fn () => auth()->user()?->can('manage', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class) && $this->deployStatus === 'deployed');
}
public function feedbackAction(): Action
{
return Action::make('feedback')
->label('Send Message to Client')
->color('info')
->modalHeading('Send Message to Client')
->modalDescription('Send a message or instructions to the client regarding their manual server.')
->form([
Textarea::make('feedback')
->label('Message')
->placeholder('e.g. Please point your domain to 1.2.3.4')
->default($this->feedback)
->rows(5),
])
->action(function (array $data): void {
abort_unless(auth()->user()?->can('message', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class), 403);
$this->service->properties()->updateOrCreate(
['key' => 'feedback'],
['value' => $data['feedback'] ?? '']
);
$this->service->refresh();
$this->loadServiceData();
Notification::make()
->title('Message Sent')
->body('The message has been sent to the client and will be visible on their server page.')
->success()
->send();
})
->visible(fn () => auth()->user()?->can('message', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class));
}
public function initializeProcesses(): void
{
abort_unless(auth()->user()?->can('manage', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class), 403);
$server = $this->service->product->server;
$config = $server->settings->pluck('value', 'key')->toArray();
$extension = new ManualServers($config);
$extension->createServer($this->service);
$this->service->refresh();
$this->loadServiceData();
Notification::make()
->title('Setup Steps Initialized')
->body('The manual server setup steps have been configured and are ready to track.')
->success()
->send();
}
public function areAllProcessesCompleted(): bool
{
if (empty($this->processData)) return false;
foreach ($this->processData as $process) {
if (!($process['completed'] ?? false)) {
return false;
}
}
return true;
}
}