diff --git a/src/Backuper.php b/src/Backuper.php index 573ad10..44da46e 100644 --- a/src/Backuper.php +++ b/src/Backuper.php @@ -41,6 +41,10 @@ public function backup(): BackupDto $zipper->encrypt($password); } + $zipper->addMeta('created_at', now()->toIso8601String()); + + $zipMeta = $this->resolveMetaFromZip($zipper); + $zipper->close(); $backup = $this->repository->add($temp_zip_path); @@ -51,10 +55,8 @@ public function backup(): BackupDto $metadata->setCreatedBy($user); } - $zipper->getMeta()->each(function ($meta, $key) use ($metadata) { - if (isset($meta['skipped'])) { - $metadata->addSkippedPipe($key, $meta['skipped']); - } + $zipMeta->each(fn ($meta, $key) => match ($key) { + 'skipped' => $meta->each(fn (string $reason, string $pipe) => $metadata->addSkippedPipe($pipe, $reason)), }); event(new BackupCreated($backup)); @@ -75,6 +77,21 @@ public function backup(): BackupDto } } + private function resolveMetaFromZip(Zipper $zip) + { + $metadata = collect([ + 'skipped' => collect(), + ]); + + $zip->getMeta()->each(function ($meta, $key) use ($metadata) { + if (isset($meta['skipped'])) { + $metadata->get('skipped')->put($key, $meta['skipped']); + } + }); + + return $metadata; + } + /** * Remove oldest backups when max backups is exceeded if it's present. */ diff --git a/src/Contracts/Repositories/BackupRepository.php b/src/Contracts/Repositories/BackupRepository.php index 3a707f6..b3aea29 100644 --- a/src/Contracts/Repositories/BackupRepository.php +++ b/src/Contracts/Repositories/BackupRepository.php @@ -11,6 +11,8 @@ interface BackupRepository { /** * Get all backups. + * + * @return Collection */ public function all(): Collection; diff --git a/src/Http/Resources/MetadataResource.php b/src/Http/Resources/MetadataResource.php index ebfce37..a7de5d8 100644 --- a/src/Http/Resources/MetadataResource.php +++ b/src/Http/Resources/MetadataResource.php @@ -5,6 +5,7 @@ namespace Itiden\Backup\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; +use Itiden\Backup\DataTransferObjects\SkippedPipeDto; /** * @mixin \Itiden\Backup\Models\Metadata @@ -17,7 +18,10 @@ public function toArray($request) 'created_by' => $this->getCreatedBy(), 'downloads' => $this->getDownloads(), 'restores' => $this->getRestores(), - 'skipped_pipes' => $this->getSkippedPipes(), + 'skipped_pipes' => $this->getSkippedPipes()->map(fn (SkippedPipeDto $pipe) => [ + 'pipe' => $pipe->pipe::getKey(), + 'reason' => $pipe->reason, + ]), ]; } } diff --git a/src/Support/Zipper.php b/src/Support/Zipper.php index a7ea281..e1ac854 100644 --- a/src/Support/Zipper.php +++ b/src/Support/Zipper.php @@ -110,10 +110,16 @@ public function getArchive(): ZipArchive /** * Add some data so that it can be extracted later. */ - public function addMeta(string $key, array $meta): self + public function addMeta(string $key, array|string $meta): self { - $current = $this->meta[$key] ?? []; - $this->meta[$key] = array_merge($current, $meta); + if (is_array($meta)) { + $current = $this->meta[$key] ?? []; + $this->meta[$key] = array_merge($current, $meta); + } else { + $this->meta[$key] = $meta; + } + + $this->zip->setArchiveComment(comment: json_encode($this->meta)); return $this; } @@ -125,6 +131,10 @@ public function addMeta(string $key, array $meta): self */ public function getMeta(): Collection { + if ($comment = $this->zip->getArchiveComment()) { + $this->meta = json_decode($comment, true); + } + return collect($this->meta); } } diff --git a/tests/Unit/PipeTest.php b/tests/Unit/PipeTest.php index bdbc49a..791ba98 100644 --- a/tests/Unit/PipeTest.php +++ b/tests/Unit/PipeTest.php @@ -57,8 +57,9 @@ $pipe->backup(zip: $zipper, next: $callable); - $zipper->close(); expect($zipper->getMeta())->toHaveKey(Users::class); expect($zipper->getMeta()[Users::class])->toHaveKey('skipped', 'No users found.'); + + $zipper->close(); }); diff --git a/tests/Unit/ZipperTest.php b/tests/Unit/ZipperTest.php index 0832d82..b6c8e19 100644 --- a/tests/Unit/ZipperTest.php +++ b/tests/Unit/ZipperTest.php @@ -121,3 +121,19 @@ expect(File::allFiles($unzip)[0]->getRelativePathname())->toBe("test.txt"); expect(File::get($unzip . '/test.txt'))->toBe('test'); }); + +it('can write meta to zip', function () { + $target = storage_path('test.zip'); + + Zipper::open($target) + ->addFromString('test.txt', 'test') + ->addMeta('test', 'test') + ->close(); + + $zip = Zipper::open($target, true); + + expect($zip->getMeta())->toHaveKey('test'); + expect($zip->getMeta())->get('test')->toBe('test'); + + $zip->close(); +});