markRunning($this->operationId); $stato->fase($this->operationId, 'Lettura dei dati gestionali'); $destinazione = self::percorso($this->operationId); try { $this->rimuoviArchiviVecchi($archivio); $xml = $exchange->currentXmlBackup(); $stato->fase($this->operationId, 'Compressione dei file'); $archivio->create( $xml, $destinazione, fn (int $fatti, int $totale) => $stato->avanza($this->operationId, $fatti, $totale) ); } catch (\Throwable $e) { Log::error('Creazione del backup non riuscita.', ['exception' => $e]); $stato->markFailed($this->operationId, $e->getMessage()); return; } $risultato = [ 'file' => basename($destinazione), 'nome_download' => 'termanager2-backup-' . now()->format('Ymd-His') . '.zip', 'dimensione' => filesize($destinazione) ?: 0, ]; if ($this->perAzzeramento) { $stato->log($this->operationId, 'Archivio pronto. In attesa che il download sia completato.'); $stato->markAttesaDownload($this->operationId, $risultato); return; } $stato->log($this->operationId, 'Backup pronto per il download.'); $stato->markCompleted($this->operationId, $risultato); } public static function percorso(string $operationId): string { return storage_path('app/backups/' . $operationId . '.zip'); } /** * Gli archivi restano su disco finche' il browser non li scarica, quindi un * download mai completato lascerebbe un file per sempre. Si ripulisce * all'inizio di ogni nuovo backup invece di aggiungere un task pianificato: * il momento in cui serve spazio e' esattamente questo. */ private function rimuoviArchiviVecchi(BackupArchive $archivio): void { $cartella = storage_path('app/backups'); if (! is_dir($cartella)) { return; } $limite = now()->subDay()->getTimestamp(); foreach (glob($cartella . '/*.zip') ?: [] as $file) { if (filemtime($file) < $limite) { @unlink($file); } } } }