feat: delete orphaned future snapshots after xml sync
This commit is contained in:
@@ -7,6 +7,7 @@ namespace App\Command;
|
||||
use App\BusProNet\Model\XmlExportInfo;
|
||||
use App\BusProNet\XmlLoader\TravelLoader;
|
||||
use App\Service\TravelDataService;
|
||||
use App\Service\TravelSnapshotService;
|
||||
use League\Flysystem\FilesystemException;
|
||||
use League\Flysystem\FilesystemOperator;
|
||||
use League\Flysystem\StorageAttributes;
|
||||
@@ -41,6 +42,7 @@ class BpnXmlSyncCommand extends Command
|
||||
private readonly LoggerInterface $logger,
|
||||
private readonly TravelLoader $travelLoader,
|
||||
private readonly TravelDataService $travelDataService,
|
||||
private readonly TravelSnapshotService $snapshotService,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
@@ -124,6 +126,7 @@ class BpnXmlSyncCommand extends Command
|
||||
|
||||
$xmlFileMap = null;
|
||||
$snapshotResult = null;
|
||||
$orphanedDeleted = null;
|
||||
try {
|
||||
$xmlFileMap = $this->travelLoader->generateFilesMap();
|
||||
} catch (\Throwable $e) {
|
||||
@@ -142,18 +145,24 @@ class BpnXmlSyncCommand extends Command
|
||||
);
|
||||
|
||||
$io->progressFinish();
|
||||
|
||||
$orphanedDeleted = $this->snapshotService->purgeOrphanedFutureSnapshots(array_keys($xmlFileMap));
|
||||
}
|
||||
|
||||
$successMessage = sprintf('Sync complete: %d files updated, %d files deleted', $syncResult['updated'], $syncResult['deleted']);
|
||||
if (null !== $snapshotResult) {
|
||||
$successMessage .= sprintf(', snapshots: %d processed, %d failed', $snapshotResult['processed'], $snapshotResult['failed']);
|
||||
}
|
||||
if (null !== $orphanedDeleted) {
|
||||
$successMessage .= sprintf(', orphaned deleted: %d', $orphanedDeleted);
|
||||
}
|
||||
$io->success($successMessage);
|
||||
$this->logger->info('XML sync completed', [
|
||||
'files_updated' => $syncResult['updated'],
|
||||
'files_deleted' => $syncResult['deleted'],
|
||||
'snapshots_processed' => $snapshotResult['processed'] ?? null,
|
||||
'snapshots_failed' => $snapshotResult['failed'] ?? null,
|
||||
'orphaned_deleted' => $orphanedDeleted,
|
||||
'remote_timestamp' => $remoteInfo->lastTransfer->format('c'),
|
||||
]);
|
||||
|
||||
|
||||
@@ -126,4 +126,31 @@ class TravelSnapshotRepository extends ServiceEntityRepository
|
||||
->getQuery()
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes future snapshots whose dateId is no longer present in the XML export.
|
||||
*
|
||||
* Only snapshots with dateFrom > today are removed; in-progress and past travels
|
||||
* are intentionally left intact so the extended-availability fallback can still serve them.
|
||||
*
|
||||
* @param array<int> $activeXmlDateIds dateIds currently present in the XML file map
|
||||
*/
|
||||
public function deleteOrphanedFutureSnapshots(array $activeXmlDateIds, \DateTimeImmutable $today): int
|
||||
{
|
||||
// An empty list means the XML export is unavailable or empty — refuse to purge
|
||||
// anything rather than deleting all future snapshots due to NOT IN ([]) = 1=1.
|
||||
if ([] === $activeXmlDateIds) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int) $this->createQueryBuilder('s')
|
||||
->delete()
|
||||
->where('s.dateFrom IS NOT NULL')
|
||||
->andWhere('s.dateFrom > :today')
|
||||
->andWhere('s.dateId NOT IN (:activeXmlDateIds)')
|
||||
->setParameter('today', $today)
|
||||
->setParameter('activeXmlDateIds', $activeXmlDateIds)
|
||||
->getQuery()
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,6 +272,19 @@ class TravelSnapshotService
|
||||
return $this->snapshotRepository->deleteExpiredSnapshots($beforeDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges future snapshots whose dateId is no longer present in the XML export.
|
||||
*
|
||||
* @param array<int> $activeXmlDateIds dateIds currently present in the XML file map
|
||||
*/
|
||||
public function purgeOrphanedFutureSnapshots(array $activeXmlDateIds): int
|
||||
{
|
||||
return $this->snapshotRepository->deleteOrphanedFutureSnapshots(
|
||||
$activeXmlDateIds,
|
||||
new \DateTimeImmutable('today'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves snapshot by exact date/hotel or by date fallback.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user