From 15f72b4de11d1234c648805e6d72d00c5d4f2ff2 Mon Sep 17 00:00:00 2001 From: F4ilji Date: Sun, 5 Jul 2026 02:47:40 +0500 Subject: [PATCH] feat(vikon): add restoreAfterFail for crash recovery in FilesystemTask --- .../VikonIntegration/Tasks/FilesystemTask.php | 38 +++++++++++++++++++ .../Tests/Unit/FilesystemTaskTest.php | 19 ++++++++++ 2 files changed, 57 insertions(+) diff --git a/app/Containers/VikonIntegration/Tasks/FilesystemTask.php b/app/Containers/VikonIntegration/Tasks/FilesystemTask.php index 312c2fc..4584212 100644 --- a/app/Containers/VikonIntegration/Tasks/FilesystemTask.php +++ b/app/Containers/VikonIntegration/Tasks/FilesystemTask.php @@ -111,6 +111,44 @@ class FilesystemTask return $this->moveEntry($newEntryPath, $currentEntryPath, $isFile); } + public function restoreAfterFail(string $modulePath, array $allowedEntries, int $moduleId): bool + { + $entries = File::directories($modulePath); + $entries = array_merge($entries, File::files($modulePath)); + + foreach ($entries as $entryPath) { + $name = basename($entryPath); + + if (str_ends_with($name, '_new')) { + $baseName = substr($name, 0, -4); + if (in_array($baseName, $allowedEntries, true)) { + if (is_dir($entryPath)) { + File::deleteDirectory($entryPath); + } else { + File::delete($entryPath); + } + } + } + + if (str_ends_with($name, '_old')) { + $baseName = substr($name, 0, -4); + if (in_array($baseName, $allowedEntries, true)) { + $originalPath = $modulePath . '/' . $baseName; + if (File::exists($originalPath)) { + if (is_dir($originalPath)) { + File::deleteDirectory($originalPath); + } else { + File::delete($originalPath); + } + } + rename($entryPath, $originalPath); + } + } + } + + return true; + } + private function moveEntry(string $source, string $dest, bool $isFile): bool { if ($isFile) { diff --git a/app/Containers/VikonIntegration/Tests/Unit/FilesystemTaskTest.php b/app/Containers/VikonIntegration/Tests/Unit/FilesystemTaskTest.php index 5ee407d..ac62351 100644 --- a/app/Containers/VikonIntegration/Tests/Unit/FilesystemTaskTest.php +++ b/app/Containers/VikonIntegration/Tests/Unit/FilesystemTaskTest.php @@ -82,4 +82,23 @@ class FilesystemTaskTest extends TestCase $this->assertFalse($result); } + + public function test_restore_after_fail_removes_new_and_restores_old(): void + { + $base = $this->tempDir . '/module'; + File::makeDirectory($base, 0755, true, true); + + // Simulate partial swap state: _old has backup + File::makeDirectory($base . '/common', 0755, true, true); + file_put_contents($base . '/common/index.php', 'fs->restoreAfterFail($base, ['common'], 1); + + $this->assertTrue($result); + $this->assertFileExists($base . '/common/index.php'); + $this->assertStringContainsString('original', file_get_contents($base . '/common/index.php')); + $this->assertDirectoryDoesNotExist($base . '/common_old'); + } }