158 lines
4.7 KiB
PHP
158 lines
4.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Filament\Jabali\Pages;
|
|
|
|
use App\Filament\Concerns\HasPageTour;
|
|
use App\Models\Domain;
|
|
use App\Services\Agent\AgentClient;
|
|
use BackedEnum;
|
|
use Exception;
|
|
use Filament\Actions\Concerns\InteractsWithActions;
|
|
use Filament\Actions\Contracts\HasActions;
|
|
use Filament\Forms\Components\Select;
|
|
use Filament\Forms\Components\TextInput;
|
|
use Filament\Forms\Components\Toggle;
|
|
use Filament\Forms\Concerns\InteractsWithForms;
|
|
use Filament\Forms\Contracts\HasForms;
|
|
use Filament\Notifications\Notification;
|
|
use Filament\Pages\Page;
|
|
use Filament\Schemas\Components\Section;
|
|
use Filament\Schemas\Schema;
|
|
use Illuminate\Contracts\Support\Htmlable;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
class ImageOptimization extends Page implements HasActions, HasForms
|
|
{
|
|
use HasPageTour;
|
|
use InteractsWithActions;
|
|
use InteractsWithForms;
|
|
|
|
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-photo';
|
|
|
|
protected static ?int $navigationSort = 21;
|
|
|
|
protected static ?string $slug = 'image-optimization';
|
|
|
|
protected string $view = 'filament.jabali.pages.image-optimization';
|
|
|
|
protected ?AgentClient $agent = null;
|
|
|
|
public array $imageFormData = [];
|
|
|
|
public function getTitle(): string|Htmlable
|
|
{
|
|
return __('Image Optimization');
|
|
}
|
|
|
|
public static function getNavigationLabel(): string
|
|
{
|
|
return __('Image Optimization');
|
|
}
|
|
|
|
protected function getAgent(): AgentClient
|
|
{
|
|
if ($this->agent === null) {
|
|
$this->agent = new AgentClient;
|
|
}
|
|
|
|
return $this->agent;
|
|
}
|
|
|
|
protected function getUsername(): string
|
|
{
|
|
return Auth::user()->username;
|
|
}
|
|
|
|
protected function getDomainOptions(): array
|
|
{
|
|
return Domain::query()
|
|
->where('user_id', Auth::id())
|
|
->orderBy('domain')
|
|
->pluck('domain', 'id')
|
|
->toArray();
|
|
}
|
|
|
|
protected function getForms(): array
|
|
{
|
|
return ['imageForm'];
|
|
}
|
|
|
|
public function imageForm(Schema $schema): Schema
|
|
{
|
|
return $schema
|
|
->statePath('imageFormData')
|
|
->schema([
|
|
Section::make(__('Optimization Settings'))
|
|
->schema([
|
|
Select::make('domain_id')
|
|
->label(__('Domain'))
|
|
->options($this->getDomainOptions())
|
|
->searchable()
|
|
->required(),
|
|
TextInput::make('path')
|
|
->label(__('Custom Path (optional)'))
|
|
->helperText(__('Leave empty to optimize the selected domain root')),
|
|
Toggle::make('convert_webp')
|
|
->label(__('Generate WebP copies'))
|
|
->default(false),
|
|
TextInput::make('quality')
|
|
->label(__('Quality (40-95)'))
|
|
->numeric()
|
|
->default(82),
|
|
])
|
|
->columns(2),
|
|
]);
|
|
}
|
|
|
|
public function runOptimization(): void
|
|
{
|
|
$data = $this->imageForm->getState();
|
|
$domainId = $data['domain_id'] ?? null;
|
|
|
|
if (! $domainId) {
|
|
Notification::make()->title(__('Select a domain'))->danger()->send();
|
|
|
|
return;
|
|
}
|
|
|
|
$domain = Domain::where('id', $domainId)->where('user_id', Auth::id())->first();
|
|
if (! $domain) {
|
|
Notification::make()->title(__('Domain not found'))->danger()->send();
|
|
|
|
return;
|
|
}
|
|
|
|
$path = trim((string) ($data['path'] ?? ''));
|
|
if ($path === '') {
|
|
$path = $domain->document_root;
|
|
}
|
|
|
|
try {
|
|
$result = $this->getAgent()->imageOptimize(
|
|
$this->getUsername(),
|
|
$path,
|
|
(bool) ($data['convert_webp'] ?? false),
|
|
(int) ($data['quality'] ?? 82)
|
|
);
|
|
|
|
if ($result['success'] ?? false) {
|
|
$optimized = $result['optimized'] ?? [];
|
|
$message = __('Optimization complete');
|
|
if (! empty($optimized)) {
|
|
$message .= ' · JPG: '.($optimized['jpg'] ?? 0).', PNG: '.($optimized['png'] ?? 0).', WebP: '.($optimized['webp'] ?? 0);
|
|
}
|
|
|
|
Notification::make()->title($message)->success()->send();
|
|
|
|
return;
|
|
}
|
|
|
|
Notification::make()->title(__('Optimization failed'))->body($result['error'] ?? '')->danger()->send();
|
|
} catch (Exception $e) {
|
|
Notification::make()->title(__('Optimization failed'))->body($e->getMessage())->danger()->send();
|
|
}
|
|
}
|
|
}
|