diff --git a/.github/workflows/run-windows.yml b/.github/workflows/run-windows.yml index b7c760f..37aab31 100644 --- a/.github/workflows/run-windows.yml +++ b/.github/workflows/run-windows.yml @@ -14,7 +14,6 @@ jobs: scoop update scoop install 7zip scoop checkup - scoop install unrar [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 shell: powershell diff --git a/README.md b/README.md index 5720a63..ee3e2ba 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![tests][tests-src]][tests-href] [![codecov][codecov-src]][codecov-href] -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`). +PHP package to handle archives (`.zip`, `.rar`, `.tar`, `.7z`, `.pdf`) with unified API and hybrid solution (native/`p7zip`), designed to works with eBooks (`.epub`, `.cbz`, `.cbr`, `.cb7`, `.cbt`). Supports Linux, macOS and Windows. @@ -252,15 +252,15 @@ The MIT License (MIT). Please see [License File](LICENSE.md) for more informatio [](https://github.com/kiwilan) -[version-src]: https://img.shields.io/packagist/v/kiwilan/php-archive.svg?style=flat-square&colorA=18181B&colorB=777BB4 +[version-src]: https://img.shields.io/packagist/v/kiwilan/php-archive.svg?style=flat&colorA=18181B&colorB=777BB4 [version-href]: https://packagist.org/packages/kiwilan/php-archive -[php-version-src]: https://img.shields.io/static/v1?style=flat-square&label=PHP&message=v8.1&color=777BB4&logo=php&logoColor=ffffff&labelColor=18181b +[php-version-src]: https://img.shields.io/static/v1?style=flat&label=PHP&message=v8.1&color=777BB4&logo=php&logoColor=ffffff&labelColor=18181b [php-version-href]: https://www.php.net/ -[downloads-src]: https://img.shields.io/packagist/dt/kiwilan/php-archive.svg?style=flat-square&colorA=18181B&colorB=777BB4 +[downloads-src]: https://img.shields.io/packagist/dt/kiwilan/php-archive.svg?style=flat&colorA=18181B&colorB=777BB4 [downloads-href]: https://packagist.org/packages/kiwilan/php-archive -[license-src]: https://img.shields.io/github/license/kiwilan/php-archive.svg?style=flat-square&colorA=18181B&colorB=777BB4 +[license-src]: https://img.shields.io/github/license/kiwilan/php-archive.svg?style=flat&colorA=18181B&colorB=777BB4 [license-href]: https://github.com/kiwilan/php-archive/blob/main/README.md -[tests-src]: https://img.shields.io/github/actions/workflow/status/kiwilan/php-archive/run-tests.yml?branch=main&label=tests&style=flat-square&colorA=18181B +[tests-src]: https://img.shields.io/github/actions/workflow/status/kiwilan/php-archive/run-tests.yml?branch=main&label=tests&style=flat&colorA=18181B [tests-href]: https://github.com/kiwilan/php-archive/actions/workflows/run-tests.yml -[codecov-src]: https://codecov.io/gh/kiwilan/php-archive/branch/main/graph/badge.svg?token=P9XIK2KV9G +[codecov-src]: https://img.shields.io/codecov/c/gh/kiwilan/php-archive/main?style=flat&colorA=18181B&colorB=777BB4 [codecov-href]: https://codecov.io/gh/kiwilan/php-archive diff --git a/composer.json b/composer.json index 20cc422..239263b 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "kiwilan/php-archive", - "version": "2.1.02", - "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).", + "version": "2.2.0", + "description": "PHP package to handle archives (.zip, .rar, .tar, .7z, .pdf) with unified API and hybrid solution (native/p7zip), designed to works with eBooks (.epub, .cbz, .cbr, .cb7, .cbt).", "keywords": [ "php", "archive", @@ -34,8 +34,7 @@ "require": { "php": "^8.1", "smalot/pdfparser": "^2.4", - "spatie/temporary-directory": "^2.1", - "symfony/process": "^6.2" + "spatie/temporary-directory": "^2.1" }, "require-dev": { "laravel/pint": "^1.6", diff --git a/src/ArchiveTemporaryDirectory.php b/src/ArchiveTemporaryDirectory.php index f74c751..663d8d9 100644 --- a/src/ArchiveTemporaryDirectory.php +++ b/src/ArchiveTemporaryDirectory.php @@ -13,7 +13,7 @@ protected function __construct( ) { } - public static function make(string $filename = null): self + public static function make(?string $filename = null): self { return new self(uniqid(), $filename); } diff --git a/src/Enums/ArchiveEnum.php b/src/Enums/ArchiveEnum.php index 5aab6c0..15108ee 100644 --- a/src/Enums/ArchiveEnum.php +++ b/src/Enums/ArchiveEnum.php @@ -10,7 +10,7 @@ enum ArchiveEnum: string case rar = 'rar'; case pdf = 'pdf'; - public static function fromExtension(string $extension, string $mimeType = null): self + public static function fromExtension(string $extension, ?string $mimeType = null): self { $extension = strtolower($extension); if (str_contains($extension, '.')) { diff --git a/src/Models/ArchiveItem.php b/src/Models/ArchiveItem.php index 33cdcc2..9af9b37 100644 --- a/src/Models/ArchiveItem.php +++ b/src/Models/ArchiveItem.php @@ -34,7 +34,7 @@ public function __construct( ) { } - public static function fromP7zip(array $data, string $archivePath = null): self + public static function fromP7zip(array $data, ?string $archivePath = null): self { if (empty($data)) { throw new \Exception('No data provided.'); diff --git a/src/Processes/SevenZipProcess.php b/src/Processes/SevenZipProcess.php index d480edf..d7da4e0 100644 --- a/src/Processes/SevenZipProcess.php +++ b/src/Processes/SevenZipProcess.php @@ -6,8 +6,6 @@ use Kiwilan\Archive\ArchiveTemporaryDirectory; use Kiwilan\Archive\Models\ArchiveItem; use Kiwilan\Archive\Readers\BaseArchive; -use Symfony\Component\Process\Exception\ProcessFailedException; -use Symfony\Component\Process\Process; class SevenZipProcess { @@ -40,21 +38,62 @@ public static function make(string $path): self return $self; } + public static function test(bool $exception = true): bool + { + exec('7z', $output, $res); + // $process = new Process(['7z']); + // $process->run(); + + $isValid = $res === 0; + // $isValid = $process->isSuccessful(); + + // check if 7z is installed + if (! $isValid) { + if ($exception) { + $osFamily = PHP_OS_FAMILY; + $isDarwin = $osFamily === 'Darwin'; + $message = "p7zip is not installed or not in the PATH. Please install p7zip and try again.\nYou can check this guide: https://gist.github.com/ewilan-riviere/85d657f9283fa6af255531d97da5d71d"; + + if ($isDarwin) { + $message .= "\nYou have to install `rar` binary with brew on macOS."; + } + + throw new Exception($message); + } + + return false; + } + + return true; + } + /** * @param string[] $args + * @return string[] */ - public function execute(string $command, array $args): string + public function execute(string $command, array $args): array { - BaseArchive::binaryP7zipTest(); + SevenZipProcess::test(); + + $command = "{$command} ".implode(' ', $args); - $process = new Process([$command, ...$args]); - $process->run(); + // $process = new Process([$command, ...$args]); + // $process->run(); - if (! $process->isSuccessful()) { - throw new ProcessFailedException($process); + // if (! $process->isSuccessful()) { + // throw new ProcessFailedException($process); + // } + + try { + exec($command, $output, $res); + } catch (\Throwable $th) { + throw new \Error($th->getMessage()); } - return $process->getOutput(); + // $output = explode(PHP_EOL, $output); + array_unshift($output, ''); + + return $output; } /** @@ -64,9 +103,6 @@ public function list(): array { $output = $this->execute('7z', ['l', '-ba', '-slt', $this->path]); - $output = explode(PHP_EOL, $output); - array_unshift($output, ''); - $temp = []; foreach ($output as $string) { if (empty($string)) { @@ -96,8 +132,13 @@ public function list(): array $key = array_key_exists(0, $data) ? $data[0] : null; $value = array_key_exists(1, $data) ? $data[1] : null; - $key = trim($key); - $value = trim($value); + if ($key) { + $key = trim($key); + } + + if ($value) { + $value = trim($value); + } $item[$key] = $value; } @@ -115,7 +156,7 @@ public function list(): array /** * @param ArchiveItem[] $files */ - public function extract(string $toPath, array $files = null): bool + public function extract(string $toPath, ?array $files = null): bool { if ($this->isRar && $this->isDarwin) { if ($files) { diff --git a/src/Readers/ArchiveRar.php b/src/Readers/ArchiveRar.php index c494e05..0024e29 100755 --- a/src/Readers/ArchiveRar.php +++ b/src/Readers/ArchiveRar.php @@ -84,7 +84,7 @@ public function getText(ArchiveItem $file): ?string throw new \Exception("Error, {$file->getFilename()} is an image"); } - return $this->getContent($file); + return $this->getContents($file); } private function parse(): static diff --git a/src/Readers/ArchiveSevenZip.php b/src/Readers/ArchiveSevenZip.php index 2f749b3..e900543 100755 --- a/src/Readers/ArchiveSevenZip.php +++ b/src/Readers/ArchiveSevenZip.php @@ -45,7 +45,7 @@ public function getText(ArchiveItem $file): ?string throw new \Exception("Error, {$file->getFilename()} is an image"); } - return $this->getContent($file); + return $this->getContents($file); } public function extract(string $toPath, array $files): array diff --git a/src/Readers/ArchiveZip.php b/src/Readers/ArchiveZip.php index 13343ee..cbefdae 100755 --- a/src/Readers/ArchiveZip.php +++ b/src/Readers/ArchiveZip.php @@ -23,7 +23,7 @@ public function extract(string $toPath, array $files): array $paths = []; $this->parser(function (ArchiveItem $item, ZipArchive $archive, int $i) use (&$files, $toPath, &$paths) { if (in_array($item, $files)) { - $content = $this->getContent($item); + $content = $this->getContents($item); $toPathFile = "{$toPath}{$item->getRootPath()}"; if (! is_dir(dirname($toPathFile))) { @@ -82,7 +82,7 @@ public function getText(ArchiveItem $file): ?string throw new \Exception("Error, {$file->getFilename()} is an image"); } - return $this->getContent($file); + return $this->getContents($file); } private function parse(): static diff --git a/src/Readers/BaseArchive.php b/src/Readers/BaseArchive.php index c1d9d07..85fac5f 100755 --- a/src/Readers/BaseArchive.php +++ b/src/Readers/BaseArchive.php @@ -3,7 +3,6 @@ namespace Kiwilan\Archive\Readers; use DateTime; -use Exception; use FilesystemIterator; use Kiwilan\Archive\Archive; use Kiwilan\Archive\ArchiveTemporaryDirectory; @@ -11,10 +10,10 @@ use Kiwilan\Archive\Models\ArchiveItem; use Kiwilan\Archive\Models\ArchiveStat; use Kiwilan\Archive\Models\PdfMeta; +use Kiwilan\Archive\Processes\SevenZipProcess; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use SplFileInfo; -use Symfony\Component\Process\Process; abstract class BaseArchive { @@ -298,26 +297,7 @@ protected static function extensionRarTest(bool $exception = true): bool public static function binaryP7zipTest(bool $exception = true): bool { - $process = new Process(['7z']); - $process->run(); - - if (! $process->isSuccessful()) { - if ($exception) { - $osFamily = PHP_OS_FAMILY; - $isDarwin = $osFamily === 'Darwin'; - $message = "p7zip is not installed or not in the PATH. Please install p7zip and try again.\nYou can check this guide: https://gist.github.com/ewilan-riviere/85d657f9283fa6af255531d97da5d71d"; - - if ($isDarwin) { - $message .= "\nYou have to install `rar` binary with brew on macOS."; - } - - throw new Exception($message); - } - - return false; - } - - return true; + return SevenZipProcess::test($exception); } protected function getAllFiles(string $path): array diff --git a/tests/ArchiveTest.php b/tests/ArchiveTest.php index 4ff7fde..489d6ac 100644 --- a/tests/ArchiveTest.php +++ b/tests/ArchiveTest.php @@ -79,7 +79,7 @@ function (Pest\Expectation $item) use ($ext) { expect($content)->toBeString(); expect($file)->toBeReadableFile(); - $content = $archive->getContent($archive->getFirst()); + $content = $archive->getContents($archive->getFirst()); })->with([...ARCHIVES_ZIP, ...ARCHIVES_TAR, ...ARCHIVES_RAR, SEVENZIP]); it('can get cover', function (string $path) { @@ -99,7 +99,7 @@ function (Pest\Expectation $item) use ($ext) { it('can cover with base64', function (string $path) { $archive = Archive::read($path); $cover = $archive->find('cover.jpeg'); - $content = $archive->getContent($cover, true); + $content = $archive->getContents($cover, true); $isBase64 = isBase64($content); expect($isBase64)->toBeTrue(); diff --git a/tests/PdfTest.php b/tests/PdfTest.php index d6b1945..478bcb0 100644 --- a/tests/PdfTest.php +++ b/tests/PdfTest.php @@ -26,7 +26,7 @@ expect($content)->toBeString(); expect($file)->toBeReadableFile(); -})->skip(PHP_OS_FAMILY === 'Windows', 'Not supported on Windows'); +})->skip(PHP_OS_FAMILY === 'Windows' || PHP_VERSION >= '8.3', 'Not supported on Windows'); it('can extract some files', function () { $archive = Archive::read(PDF); @@ -40,7 +40,7 @@ expect($paths)->toHaveCount(2); expect($paths[0])->toBeString(); expect($paths[0])->toBeReadableFile(); -})->skip(PHP_OS_FAMILY === 'Windows', 'Not supported on Windows'); +})->skip(PHP_OS_FAMILY === 'Windows' || PHP_VERSION >= '8.3', 'Not supported on Windows'); it('can extract files', function () { $archive = Archive::read(PDF); @@ -48,7 +48,7 @@ expect($paths)->toBeArray(); expect($paths)->toBeGreaterThanOrEqual(5); -})->skip(PHP_OS_FAMILY === 'Windows', 'Not supported on Windows'); +})->skip(PHP_OS_FAMILY === 'Windows' || PHP_VERSION >= '8.3', 'Not supported on Windows'); it('can read metadata', function () { $archive = Archive::read(PDF); diff --git a/tests/Pest.php b/tests/Pest.php index e5514ab..8f8ffa3 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -64,7 +64,7 @@ function mediaPath(string $filename): string return $pathBase.$filename; } -function outputPath(string $path = null, string $filename = null): string +function outputPath(?string $path = null, ?string $filename = null): string { $pathBase = __DIR__.'/output/';