Extract synchronization logic into separate pages

This commit is contained in:
Ralph J. Smit
2022-08-08 17:21:58 +02:00
parent b2e1ee9e24
commit bcadd716fe
22 changed files with 442 additions and 138 deletions

View File

@@ -0,0 +1,34 @@
<?php
namespace App\Actions\Server;
use App\Models\Server;
use App\Services\Ploi\Ploi;
use Filament\Notifications\Notification;
class SynchronizeServerAction
{
public function execute(int $ploiServerId): Server
{
$serverData = Ploi::make()->server()->get($ploiServerId)->getData();
$server = Server::query()
->updateOrCreate([
'ploi_id' => $serverData->id,
], [
'status' => $serverData->status,
'name' => $serverData->name,
'ip' => $serverData->ip_address,
'ssh_port' => $serverData->ssh_port,
'internal_ip' => $serverData->internal_ip,
'available_php_versions' => $serverData->installed_php_versions,
]);
Notification::make()
->body(__('Server :server synchronized successfully.', ['server' => $server->name]))
->success()
->send();
return $server;
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace App\Actions\Site;
use App\Models\Server;
use App\Models\Site;
use App\Services\Ploi\Ploi;
use Filament\Notifications\Notification;
class SynchronizeSiteAction
{
public function execute(int $ploiServerId, int $ploiSiteId): Site
{
$siteData = Ploi::make()->server($ploiServerId)->sites()->get($ploiSiteId)->getData();
$server = Server::query()
->where('ploi_id', $siteData->server_id)
->firstOrFail();
$site = Site::query()
->updateOrCreate([
'ploi_id' => $siteData->id,
], [
'domain' => $siteData->domain,
'php_version' => $siteData->php_version,
'project' => $siteData->project_type,
]);
$site->status = $siteData->status;
$site->server_id = $server->id;
$site->save();
$certificates = Ploi::make()->server($siteData->server_id)->sites($siteData->id)->certificates()->get()->getData();
if ( $certificates ) {
foreach ($certificates as $certificate) {
$site->certificates()->updateOrCreate([
'ploi_id' => $certificate->id,
], [
'status' => $certificate->status,
'ploi_id' => $certificate->id,
'domain' => $certificate->domain,
'type' => $certificate->type,
]);
}
}
Notification::make()
->body(__('Site :site synchronized successfully.', ['site' => $site->domain]))
->success()
->send();
return $site;
}
}

View File

@@ -7,6 +7,7 @@ use App\Filament\Resources\ProviderResource\Pages;
use App\Filament\Resources\ProviderResource\RelationManagers;
use App\Filament\Resources\ProviderResource\Widgets\AvailableProvidersOverview;
use App\Models\Provider;
use App\Models\ProviderPlan;
use Filament\Forms;
use Filament\Notifications\Notification;
use Filament\Resources\Form;
@@ -29,13 +30,18 @@ class ProviderResource extends Resource
{
return $form
->schema([
Forms\Components\TextInput::make('ploi_id'),
Forms\Components\TextInput::make('label')
->maxLength(255),
Forms\Components\TextInput::make('name')
->maxLength(255),
Forms\Components\TextInput::make('allowed_plans'),
Forms\Components\TextInput::make('allowed_regions'),
->label(__('Name'))
->required()
->columnSpan(2),
Forms\Components\CheckboxList::make('allowed_plans')
->options(function (Provider $record) {
return $record->plans->mapWithKeys(fn (ProviderPlan $plan) => [$plan->id => $plan->label ?? $plan->plan_id]);
})
->label(__('Allowed Plans')),
Forms\Components\CheckboxList::make('allowed_regions')
->options(fn (Provider $record) => $record->regions->pluck('label', 'id'))
->label(__('Allowed Regions')),
]);
}
@@ -55,8 +61,10 @@ class ProviderResource extends Resource
//
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\Action::make('synchronize_provider')
->label(__('Synchronize'))
->tooltip(__('This will synchronize the latest data from this provider to your Ploi Core installation'))
->icon('heroicon-o-refresh')
->action(function (Provider $record) {
$provider = app(SynchronizeProviderAction::class)->execute($record->ploi_id);
@@ -96,6 +104,8 @@ class ProviderResource extends Resource
{
return [
'index' => Pages\ListProviders::route('/'),
'synchronize' => Pages\SynchronizeProviders::route('/synchronize'),
'edit' => Pages\EditProvider::route('/{record}'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\ProviderResource\Pages;
use App\Filament\Resources\ProviderResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\EditRecord;
class EditProvider extends EditRecord
{
protected static string $resource = ProviderResource::class;
}

View File

@@ -3,6 +3,7 @@
namespace App\Filament\Resources\ProviderResource\Pages;
use App\Filament\Resources\ProviderResource;
use Filament\Pages\Actions\Action;
use Filament\Resources\Pages\ListRecords;
class ListProviders extends ListRecords
@@ -16,14 +17,10 @@ class ListProviders extends ListRecords
protected function getActions(): array
{
return [
//
];
}
protected function getHeaderWidgets(): array
{
return [
ProviderResource\Widgets\AvailableProvidersOverview::class,
Action::make('synchronize_providers')
->label(__('Synchronize providers'))
->icon('heroicon-o-refresh')
->url(route('filament.resources.providers.synchronize')),
];
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace App\Filament\Resources\ProviderResource\Pages;
use App\Filament\Resources\ProviderResource;
use Filament\Resources\Pages\Page;
class SynchronizeProviders extends Page
{
protected static string $resource = ProviderResource::class;
protected static string $view = 'filament.resources.provider-resource.pages.synchronize-providers';
protected static ?string $title = 'Synchronize providers';
public function mount()
{
//
}
protected function getHeaderWidgets(): array
{
return [
ProviderResource\Widgets\AvailableProvidersOverview::class,
];
}
protected function getActions(): array
{
return [
//
];
}
}

View File

@@ -14,7 +14,7 @@ use Illuminate\Database\Eloquent\Relations\Relation;
class AvailableProvidersOverview extends TableWidget
{
protected $listeners = [
'$refresh'
'$refresh',
];
protected int|string|array $columnSpan = 'full';
@@ -54,9 +54,4 @@ class AvailableProvidersOverview extends TableWidget
}),
];
}
public static function canView(): bool
{
return AvailableProvider::exists();
}
}

View File

@@ -2,13 +2,12 @@
namespace App\Filament\Resources;
use App\Actions\Server\SynchronizeServerAction;
use App\Filament\Resources\ServerResource\Pages;
use App\Filament\Resources\ServerResource\RelationManagers;
use App\Models\Server;
use App\Models\User;
use App\Services\Ploi\Ploi;
use Filament\Forms;
use Filament\Notifications\Notification;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Filament\Resources\Table;
@@ -88,27 +87,9 @@ class ServerResource extends Resource
Tables\Actions\EditAction::make(),
Tables\Actions\Action::make('synchronize_server')
->label(__('Synchronize'))
->tooltip(__('This will synchronize the latest data from this provider to your Ploi Core installation'))
->icon('heroicon-o-refresh')
->action(function (Server $record) {
$serverData = Ploi::make()->server()->get($record->ploi_id)->getData();
$server = Server::query()
->updateOrCreate([
'ploi_id' => $serverData->id,
], [
'status' => $serverData->status,
'name' => $serverData->name,
'ip' => $serverData->ip_address,
'ssh_port' => $serverData->ssh_port,
'internal_ip' => $serverData->internal_ip,
'available_php_versions' => $serverData->installed_php_versions,
]);
Notification::make()
->body(__('Server :server synchronized successfully.', ['server' => $server->name]))
->success()
->send();
}),
->action(fn (Server $record) => app(SynchronizeServerAction::class)->execute($record->ploi_id)),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
@@ -134,6 +115,7 @@ class ServerResource extends Resource
return [
'index' => Pages\ListServers::route('/'),
'edit' => Pages\EditServer::route('/{record}/edit'),
'synchronize' => Pages\SynchronizeServers::route('/synchronize'),
];
}

View File

@@ -3,9 +3,7 @@
namespace App\Filament\Resources\ServerResource\Pages;
use App\Filament\Resources\ServerResource;
use App\Models\Server;
use App\Traits\HasPloi;
use Filament\Notifications\Notification;
use Filament\Pages\Actions\Action;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Builder;
@@ -22,28 +20,7 @@ class ListServers extends ListRecords
Action::make('synchronize_servers')
->label(__('Synchronize servers'))
->icon('heroicon-o-refresh')
->action(function () {
$availableServers = $this->getPloi()->synchronize()->servers()->getData();
foreach ($availableServers as $availableServer) {
Server::query()
->updateOrCreate([
'ploi_id' => $availableServer->id,
], [
'status' => $availableServer->status,
'name' => $availableServer->name,
'ip' => $availableServer->ip_address,
'ssh_port' => $availableServer->ssh_port,
'internal_ip' => $availableServer->internal_ip,
'available_php_versions' => $availableServer->installed_php_versions,
]);
}
Notification::make()
->body(__('Servers synchronized successfully.'))
->success()
->send();
}),
->url(route('filament.resources.servers.synchronize')),
];
}

View File

@@ -0,0 +1,57 @@
<?php
namespace App\Filament\Resources\ServerResource\Pages;
use App\Filament\Resources\ServerResource;
use App\Models\Server;
use App\Services\Ploi\Ploi;
use Filament\Notifications\Notification;
use Filament\Pages\Actions\Action;
use Filament\Resources\Pages\Page;
class SynchronizeServers extends Page
{
protected static string $resource = ServerResource::class;
protected static string $view = 'filament.resources.server-resource.pages.synchronize-servers';
protected static ?string $title = 'Synchronize servers';
protected function getHeaderWidgets(): array
{
return [
ServerResource\Widgets\AvailableServersOverview::class,
];
}
protected function getActions(): array
{
return [
Action::make('synchronize_servers')
->label(__('Synchronize all servers'))
->icon('heroicon-o-refresh')
->action(function () {
$availableServers = Ploi::make()->synchronize()->servers()->getData();
foreach ($availableServers as $availableServer) {
Server::query()
->updateOrCreate([
'ploi_id' => $availableServer->id,
], [
'status' => $availableServer->status,
'name' => $availableServer->name,
'ip' => $availableServer->ip_address,
'ssh_port' => $availableServer->ssh_port,
'internal_ip' => $availableServer->internal_ip,
'available_php_versions' => $availableServer->installed_php_versions,
]);
}
Notification::make()
->body(__('Servers synchronized successfully.'))
->success()
->send();
}),
];
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace App\Filament\Resources\ServerResource\Widgets;
use App\Actions\Server\SynchronizeServerAction;
use App\Models\AvailableServer;
use Filament\Tables\Actions\Action;
use Filament\Tables\Columns\TextColumn;
use Filament\Widgets\TableWidget;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\Relation;
class AvailableServersOverview extends TableWidget
{
protected $listeners = [
'$refresh',
];
protected int|string|array $columnSpan = 'full';
protected static ?string $heading = 'Available servers';
protected function getTableQuery(): Builder|Relation
{
return AvailableServer::query();
}
protected function getTableColumns(): array
{
return [
TextColumn::make('name')
->label(__('Name')),
];
}
protected function getTableActions(): array
{
return [
Action::make('synchronize_server')
->label(__('Synchronize'))
->icon('heroicon-o-refresh')
->action(function (AvailableServer $record) {
app(SynchronizeServerAction::class)->execute($record->id);
}),
];
}
}

View File

@@ -2,14 +2,12 @@
namespace App\Filament\Resources;
use App\Actions\Site\SynchronizeSiteAction;
use App\Filament\Resources\SiteResource\Pages;
use App\Filament\Resources\SiteResource\RelationManagers;
use App\Models\Server;
use App\Models\Site;
use App\Models\User;
use App\Services\Ploi\Ploi;
use Filament\Forms;
use Filament\Notifications\Notification;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Filament\Resources\Table;
@@ -85,46 +83,10 @@ class SiteResource extends Resource
Tables\Actions\EditAction::make(),
Tables\Actions\Action::make('synchronize_site')
->label(__('Synchronize'))
->tooltip(__('This will synchronize the latest data from this provider to your Ploi Core installation'))
->icon('heroicon-o-refresh')
->action(function (Site $record) {
$siteData = Ploi::make()->server($record->server->ploi_id)->sites()->get($record->ploi_id)->getData();
$server = Server::query()
->where('ploi_id', $siteData->server_id)
->firstOrFail();
$site = Site::query()
->updateOrCreate([
'ploi_id' => $siteData->id,
], [
'domain' => $siteData->domain,
'php_version' => $siteData->php_version,
'project' => $siteData->project_type,
]);
$site->status = $siteData->status;
$site->server_id = $server->id;
$site->save();
$certificates = Ploi::make()->server($siteData->server_id)->sites($siteData->id)->certificates()->get()->getData();
if ( $certificates ) {
foreach ($certificates as $certificate) {
$site->certificates()->updateOrCreate([
'ploi_id' => $certificate->id,
], [
'status' => $certificate->status,
'ploi_id' => $certificate->id,
'domain' => $certificate->domain,
'type' => $certificate->type,
]);
}
}
Notification::make()
->body(__('Site :site synchronized successfully.', ['site' => $site->domain]))
->success()
->send();
app(SynchronizeSiteAction::class)->execute($record->ploi_id);
}),
])
->bulkActions([
@@ -155,6 +117,7 @@ class SiteResource extends Resource
return [
'index' => Pages\ListSites::route('/'),
'edit' => Pages\EditSite::route('/{record}/edit'),
'synchronize' => Pages\SynchronizeSites::route('/synchronize'),
];
}
}

View File

@@ -3,10 +3,7 @@
namespace App\Filament\Resources\SiteResource\Pages;
use App\Filament\Resources\SiteResource;
use App\Models\Server;
use App\Models\Site;
use App\Traits\HasPloi;
use Filament\Notifications\Notification;
use Filament\Pages\Actions\Action;
use Filament\Resources\Pages\ListRecords;
use Illuminate\Database\Eloquent\Builder;
@@ -23,30 +20,7 @@ class ListSites extends ListRecords
Action::make('synchronize_sites')
->label(__('Synchronize sites'))
->icon('heroicon-o-refresh')
->action(function () {
$availableSites = $this->getPloi()->synchronize()->sites()->getData();
foreach ($availableSites as $availableSite) {
$server = Server::query()->where('ploi_id', $availableSite->server_id)->firstOrFail();
$site = Site::query()
->updateOrCreate([
'ploi_id' => $availableSite->id,
], [
'domain' => $availableSite->domain,
'php_version' => $availableSite->php_version,
]);
$site->status = $availableSite->status;
$site->server_id = $server->id;
$site->save();
}
Notification::make()
->body(__('Sites synchronized successfully.'))
->success()
->send();
}),
->url(route('filament.resources.sites.synchronize')),
];
}

View File

@@ -0,0 +1,58 @@
<?php
namespace App\Filament\Resources\SiteResource\Pages;
use App\Filament\Resources\SiteResource;
use App\Models\Server;
use App\Models\Site;
use App\Services\Ploi\Ploi;
use Filament\Notifications\Notification;
use Filament\Pages\Actions\Action;
use Filament\Resources\Pages\Page;
class SynchronizeSites extends Page
{
protected static string $resource = SiteResource::class;
protected static string $view = 'filament.resources.site-resource.pages.synchronize-sites';
public function getHeaderWidgets(): array
{
return [
SiteResource\Widgets\AvailableSitesOverview::class,
];
}
protected function getActions(): array
{
return [
Action::make('synchronize_sites')
->label(__('Synchronize all sites'))
->icon('heroicon-o-refresh')
->action(function () {
$availableSites = Ploi::make()->synchronize()->sites()->getData();
foreach ($availableSites as $availableSite) {
$server = Server::query()->where('ploi_id', $availableSite->server_id)->firstOrFail();
$site = Site::query()
->updateOrCreate([
'ploi_id' => $availableSite->id,
], [
'domain' => $availableSite->domain,
'php_version' => $availableSite->php_version,
]);
$site->status = $availableSite->status;
$site->server_id = $server->id;
$site->save();
}
Notification::make()
->body(__('Sites synchronized successfully.'))
->success()
->send();
}),
];
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace App\Filament\Resources\SiteResource\Widgets;
use App\Actions\Site\SynchronizeSiteAction;
use App\Models\AvailableSite;
use Filament\Tables\Actions\Action;
use Filament\Tables\Columns\TextColumn;
use Filament\Widgets\TableWidget;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\Relation;
class AvailableSitesOverview extends TableWidget
{
protected $listeners = [
'$refresh',
];
protected int|string|array $columnSpan = 'full';
protected static ?string $heading = 'Available sites';
protected function getTableQuery(): Builder|Relation
{
return AvailableSite::query();
}
protected function getTableColumns(): array
{
return [
TextColumn::make('domain')
->label(__('Site')),
];
}
protected function getTableActions(): array
{
return [
Action::make('synchronize_site')
->label(__('Synchronize'))
->icon('heroicon-o-refresh')
->action(function (AvailableSite $record) {
app(SynchronizeSiteAction::class)->execute(ploiServerId: $record->server_id, ploiSiteId: $record->id);
}),
];
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Models;
use App\Services\Ploi\Ploi;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use stdClass;
use Sushi\Sushi;
class AvailableServer extends Model
{
use Sushi;
public function getRows(): array
{
$availableServers = Ploi::make()
->synchronize()
->servers()
->getData();
return collect($availableServers)
->map(fn (stdClass $provider): array => Arr::only((array) $provider, ['id', 'name']))
->all();
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Models;
use App\Services\Ploi\Ploi;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use stdClass;
use Sushi\Sushi;
class AvailableSite extends Model
{
use Sushi;
public function getRows(): array
{
$availableSites = Ploi::make()
->synchronize()
->sites()
->getData();
return collect($availableSites)
->map(fn (stdClass $provider): array => Arr::only((array) $provider, ['id', 'domain', 'server_id']))
->all();
}
}

View File

@@ -54,7 +54,7 @@ class ProviderPolicy
*/
public function update(User $user, Provider $provider)
{
return false;
return true;
}
/**