174 lines
4.8 KiB
PHP
174 lines
4.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Filament\Pages;
|
|
|
|
use App\Models\OsurgInitial;
|
|
use App\Models\SyncLog;
|
|
use App\Services\OsurgImportService;
|
|
use App\Services\SyncService;
|
|
use Filament\Actions\Action;
|
|
use Filament\Notifications\Notification;
|
|
use Filament\Pages\Page;
|
|
use Livewire\WithFileUploads;
|
|
use Morilog\Jalali\Jalalian;
|
|
|
|
class SyncPage extends Page
|
|
{
|
|
use WithFileUploads;
|
|
protected string $view = 'filament.pages.sync-page';
|
|
|
|
protected static ?int $navigationSort = 99;
|
|
|
|
public static function canAccess(): bool
|
|
{
|
|
return auth()->user()->can('View:SyncPage');
|
|
}
|
|
|
|
public static function shouldRegisterNavigation(): bool
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public static function getNavigationIcon(): \BackedEnum|string|null
|
|
{
|
|
return 'heroicon-o-arrows-right-left';
|
|
}
|
|
|
|
public static function getNavigationGroup(): ?string
|
|
{
|
|
return __('navigation.groups.system');
|
|
}
|
|
|
|
public string $report = '';
|
|
public string $importReport = '';
|
|
public bool $importing = false;
|
|
|
|
public $sqlFile = null;
|
|
|
|
public static function getNavigationLabel(): string
|
|
{
|
|
return __('navigation.sync.label');
|
|
}
|
|
|
|
public function getTitle(): string
|
|
{
|
|
return __('navigation.sync.title');
|
|
}
|
|
|
|
public function getPendingCount(): int
|
|
{
|
|
return SyncLog::changesSince((int) OsurgInitial::val('our_sync_cursor', 0))->count();
|
|
}
|
|
|
|
public function getLastSyncTime(): string
|
|
{
|
|
$last = SyncLog::where('action', 'synced')->latest('id')->first();
|
|
if (! $last) {
|
|
return __('navigation.sync.never');
|
|
}
|
|
|
|
return Jalalian::fromCarbon($last->datetime->timezone('Asia/Tehran'))->format('Y/m/d H:i:s');
|
|
}
|
|
|
|
protected function rules(): array
|
|
{
|
|
return [
|
|
'sqlFile' => ['required', 'file', 'max:307200'],
|
|
];
|
|
}
|
|
|
|
|
|
protected function getHeaderActions(): array
|
|
{
|
|
return [
|
|
Action::make('sync')
|
|
->label(__('navigation.sync.sync_with_peer'))
|
|
->icon('heroicon-o-arrows-right-left')
|
|
->color('primary')
|
|
->requiresConfirmation()
|
|
->modalHeading(__('navigation.sync.confirm_heading'))
|
|
->modalDescription(__('navigation.sync.confirm_description'))
|
|
->modalSubmitActionLabel(__('navigation.sync.confirm_button'))
|
|
->action('runSync'),
|
|
|
|
Action::make('backup')
|
|
->label(__('navigation.backup.label'))
|
|
->icon('heroicon-o-arrow-down-tray')
|
|
->color('success')
|
|
->action('downloadBackup'),
|
|
];
|
|
}
|
|
|
|
public function runSync(): void
|
|
{
|
|
$service = SyncService::fromConfig();
|
|
|
|
if (! $service->isConfigured()) {
|
|
Notification::make()
|
|
->title(__('navigation.sync.error_title'))
|
|
->body(__('navigation.sync.error_not_configured'))
|
|
->danger()
|
|
->send();
|
|
return;
|
|
}
|
|
|
|
$result = $service->sync();
|
|
|
|
$this->report = implode("\n", $result['report']);
|
|
|
|
Notification::make()
|
|
->title($result['success'] ? __('navigation.sync.success') : __('navigation.sync.failed'))
|
|
->body(__('navigation.sync.see_report'))
|
|
->color($result['success'] ? 'success' : 'warning')
|
|
->send();
|
|
}
|
|
|
|
|
|
public function startImport(): void
|
|
{
|
|
$this->validate();
|
|
|
|
$this->importing = true;
|
|
|
|
try {
|
|
@set_time_limit(600);
|
|
|
|
$tmpPath = $this->sqlFile->getRealPath();
|
|
|
|
$service = new OsurgImportService();
|
|
$result = $service->import($tmpPath);
|
|
|
|
$this->importReport = implode("\n", $result['report']);
|
|
|
|
Notification::make()
|
|
->title($result['success']
|
|
? __('navigation.import.success')
|
|
: __('navigation.import.failed'))
|
|
->body(__('navigation.sync.see_report'))
|
|
->color($result['success'] ? 'success' : 'danger')
|
|
->send();
|
|
} finally {
|
|
$this->sqlFile = null;
|
|
$this->importing = false;
|
|
}
|
|
}
|
|
|
|
|
|
public function downloadBackup(): \Symfony\Component\HttpFoundation\StreamedResponse
|
|
{
|
|
$data = [
|
|
'exported_at' => now()->toDateTimeString(),
|
|
'last_sync_id' => SyncLog::lastSyncId(),
|
|
'changes' => SyncLog::all()->toArray(),
|
|
];
|
|
|
|
$filename = 'matab-backup-' . now()->format('Y-m-d_H-i-s') . '.json';
|
|
|
|
return response()->streamDownload(function () use ($data) {
|
|
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
|
}, $filename, ['Content-Type' => 'application/json']);
|
|
}
|
|
}
|