From 38ba79335798198e1d319c8fbb94c19cd94ac238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ewilan=20Rivi=C3=A8re?= Date: Mon, 28 Aug 2023 18:22:41 +0200 Subject: [PATCH] 2.1.0 Rework `Archive::make()` - `addFile()` takes two parameters now: the `outputPath` inside archive and `pathToFile` on disk - ~~`addFiles()`~~ is removed - `addDirectory()` takes two parameters now: `relativeTo` path inside archive and the `path` of directory on the disk - If the `path` is `/path/to/dir` and `relativeTo` is `./dir`, the directory will be added to archive as `dir/` - ~~`addDirectories()`~~ is removed --- README.md | 16 +++--- composer.json | 2 +- src/ArchiveZipCreate.php | 101 ++++++++++++++++++++---------------- tests/ArchiveCreateTest.php | 41 +++++++++------ 4 files changed, 91 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 4a5dba1..05de6ce 100644 --- a/README.md +++ b/README.md @@ -148,13 +148,17 @@ Works only with `.zip` archives. ```php $archive = Archive::make('path/to/archive.zip'); -$archive->addFiles([ - 'path/to/file1.txt', - 'path/to/file2.txt', - 'path/to/file3.txt', -]); +$files = [ + 'path/to/file/in/archive-file1.txt' => 'path/to/real-file1.txt', + 'path/to/file/in/archive-file2.txt' => 'path/to/real-file2.txt', + 'path/to/file/in/archive-file3.txt' => 'path/to/real-file3.txt', +]; + +foreach ($files as $pathInArchive => $pathToRealFile) { + $archive->addFile($pathInArchive, $pathToRealFile); +} $archive->addFromString('test.txt', 'Hello World!'); -$archive->addDirectory('path/to/directory'); +$archive->addDirectory('./directory', 'path/to/directory'); $archive->save(); ``` diff --git a/composer.json b/composer.json index 4279cd5..b2d8691 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "kiwilan/php-archive", - "version": "2.0.02", + "version": "2.1.0", "description": "PHP package to handle archives (.zip, .rar, .tar, .7z) or .pdf with hybrid solution (native/p7zip), designed to works with eBooks (.epub, .cbz, .cbr, .cb7, .cbt).", "keywords": [ "php", diff --git a/src/ArchiveZipCreate.php b/src/ArchiveZipCreate.php index 607d842..683b5db 100755 --- a/src/ArchiveZipCreate.php +++ b/src/ArchiveZipCreate.php @@ -10,14 +10,12 @@ class ArchiveZipCreate { /** - * @param SplFileInfo[] $files - * @param array $strings + * @param ArchiveFile[] $files */ protected function __construct( protected string $path, protected string $name, protected array $files = [], - protected array $strings = [], protected int $count = 0, ) { } @@ -64,7 +62,7 @@ public function getCount(): int } /** - * @return SplFileInfo[] + * @return ArchiveFile[] */ public function getFiles(): array { @@ -72,77 +70,74 @@ public function getFiles(): array } /** - * @return array + * Add a new file to the archive from existing file. + * + * @param string $outputPath Path to the file inside the archive + * @param string $pathToFile Path to the file to add */ - public function getStrings(): array - { - return $this->strings; - } - - public function addFile(string $path): self + public function addFile(string $outputPath, string $pathToFile): self { - $this->files[] = new SplFileInfo($path); + $this->files[] = new ArchiveFile($outputPath, new SplFileInfo($pathToFile)); $this->count++; return $this; } - public function addFromString(string $filename, string $content): self + /** + * Add a new file to the archive from string. + * + * @param string $outputPath Path to the file inside the archive + * @param string $content Content of the file to add + */ + public function addFromString(string $outputPath, string $content): self { - $this->strings[$filename] = $content; + $this->files[] = new ArchiveFile($outputPath, null, $content); $this->count++; return $this; } - public function addFiles(array $paths): self - { - foreach ($paths as $path) { - $this->addFile($path); - } - - return $this; - } - - public function addDirectory(string $path): self + /** + * Add a full directory to the archive, including subdirectories. + * + * @param string $relativeTo Relative path to the directory inside the archive + * @param string $path Path to the directory to add + * + * ```php + * $archive->addDirectory('./to/directory', '/path/to/directory'); + * ``` + */ + public function addDirectory(string $relativeTo, string $path): self { - $files = $this->pathsToSplFiles($this->directoryToPaths($path)); + $files = $this->pathsToSplFiles($this->directoryToPaths($path, $relativeTo)); $this->files = [...$this->files, ...$files]; $this->count = count($this->files); return $this; } - public function addDirectories(array $paths): self - { - foreach ($paths as $path) { - $this->addDirectory($path); - } - - return $this; - } - - public function save(): self + /** + * Save the archive. + */ + public function save(): bool { $zip = new ZipArchive(); $zip->open($this->path, ZipArchive::CREATE); foreach ($this->files as $file) { - $zip->addFile($file->getRealPath(), $file->getFilename()); - } - - foreach ($this->strings as $filename => $content) { - $zip->addFromString($filename, $content); + $content = $file->content; + if (! $file->isString) { + $content = file_get_contents($file->file->getPathname()); + } + $zip->addFromString($file->outputPath, $content); } $this->count = $zip->numFiles; - $zip->close(); - - return $this; + return $zip->close(); } - protected function directoryToPaths(string $path): array + protected function directoryToPaths(string $path, string $relativeTo): array { $files = []; $directory = new RecursiveDirectoryIterator($path); @@ -152,7 +147,9 @@ protected function directoryToPaths(string $path): array if ($file->isDir()) { continue; } - $files[] = $file->getPathname(); + + $outputPath = str_replace($path, $relativeTo, $file->getPathname()); + $files[] = $this->addFile($outputPath, $file->getPathname()); } return $files; @@ -176,3 +173,17 @@ protected function pathsToSplFiles(array $paths): array return $files; } } + +class ArchiveFile +{ + public function __construct( + public string $outputPath, + public ?SplFileInfo $file = null, + public ?string $content = null, + public bool $isString = false, + ) { + if (! $this->file) { + $this->isString = true; + } + } +} diff --git a/tests/ArchiveCreateTest.php b/tests/ArchiveCreateTest.php index 11b0a84..bbb72a7 100644 --- a/tests/ArchiveCreateTest.php +++ b/tests/ArchiveCreateTest.php @@ -1,6 +1,7 @@ mediaPath('archive/cover.jpeg'), + 'archive/file-1.md' => mediaPath('archive/file-1.md'), + 'archive/file-2.md' => mediaPath('archive/file-2.md'), + 'archive/file-3.md' => mediaPath('archive/file-3.md'), + 'archive/metadata.xml' => mediaPath('archive/metadata.xml'), ]; $archive = Archive::make($path); - $archive->addFiles($medias); + foreach ($medias as $output => $media) { + $archive->addFile($output, $media); + } $archive->save(); expect($archive->getPath())->toBe($path); @@ -24,20 +27,23 @@ expect($archive->getPath())->toBeReadableFile($path); expect($archive->getCount())->toBe(5); expect($archive->getFiles())->toBeArray() - ->each(fn ($file) => expect($file->value)->toBeInstanceOf(SplFileInfo::class)); + ->each(fn ($file) => expect($file->value)->toBeInstanceOf(ArchiveFile::class)); }); it('can create with files', function () { $path = outputPath(filename: 'test.zip'); + $files = [ + 'archive/cover.jpeg' => mediaPath('archive/cover.jpeg'), + 'archive/file-1.md' => mediaPath('archive/file-1.md'), + 'archive/file-2.md' => mediaPath('archive/file-2.md'), + 'archive/file-3.md' => mediaPath('archive/file-3.md'), + 'archive/metadata.xml' => mediaPath('archive/metadata.xml'), + ]; $archive = Archive::make($path); - $archive->addFiles([ - mediaPath('archive/cover.jpeg'), - mediaPath('archive/file-1.md'), - mediaPath('archive/file-2.md'), - mediaPath('archive/file-3.md'), - mediaPath('archive/metadata.xml'), - ]); + foreach ($files as $path => $file) { + $archive->addFile($path, $file); + } $archive->addFromString('test.txt', 'Hello World!'); $archive->save(); @@ -61,18 +67,19 @@ $path = outputPath(filename: 'test.zip'); $archive = Archive::make($path); - $archive->addDirectory(mediaPath('archive')); + $archive->addDirectory('./archive', mediaPath('archive')); + $archive->addFromString('test.txt', 'Hello World!'); $archive->save(); expect($archive->getPath())->toBeReadableFile($path); - expect($archive->getCount())->toBe(5); + expect($archive->getCount())->toBe(6); }); it('can edit', function () { $path = outputPath(filename: 'test.zip'); $archive = Archive::make($path); - $archive->addDirectory(mediaPath('archive')); + $archive->addDirectory('./archive', mediaPath('archive')); $archive->save(); $archive = Archive::make($path);