diff --git a/README.md b/README.md index 263ec4b..b4c55e7 100644 --- a/README.md +++ b/README.md @@ -79,12 +79,51 @@ $sevenZip->source('/path/to/archive.7z') ->extract(); ``` +### Encryption + +You can encrypt the compressed archive using a password: + +```php +$sevenZip = new SevenZip(); +$sevenZip->source('/path/to/source/file/or/directory') + ->target('/path/to/encrypted_archive.7z') + ->encrypt('your_password') + ->compress(); +``` + +By default, the file names are also encrypted (not possible in zip format). If you want to disable file name encryption, you can use +the `notEncryptNames()` method: + +```php +$sevenZip->notEncryptNames(); +``` + +For ZIP archives, you can specify the encryption method using the `setZipEncryptionMethod()` method. Available options are 'ZipCrypto' (not secure), ' +AES128', 'AES192', or 'AES256'. The default is 'AES128'. + +```php +$sevenZip->setZipEncryptionMethod('AES256'); +``` + +### Decryption + +To decrypt an encrypted archive during extraction: + +```php +$sevenZip = new SevenZip(); +$sevenZip->source('/path/to/encrypted_archive.7z') + ->target('/path/to/extract/directory') + ->decrypt('your_password') + ->extract(); +``` + ## TODO / WIP +- [x] Full support for add flags (7z switches) - [ ] Add custom support for gz, xz, etc. by using tar flags - [ ] Use tar to keep original file permissions and other attributes -- [ ] Encrypt and decrypt -- [ ] Test files +- [x] Encrypt and decrypt +- [ ] Test files using 7z test command - [ ] Detect supported formats by the OS ## Contributing @@ -192,6 +231,42 @@ Compresses a file or directory. $sevenZip->compress('7z', '/path/to/source', '/path/to/archive.7z'); ``` +### `encrypt(string $password): self` + +Encrypts the data using the provided password. + +**Parameters** + +- `$password`: The password to encrypt the data. + +**Returns**: The current instance of the SevenZip class. + +### `decrypt(string $password): self` + +Decrypts the data using the provided password. + +**Parameters** + +- `$password`: The password to decrypt the data. + +**Returns**: The current instance of the SevenZip class. + +### `notEncryptNames(): self` + +Disables encryption of file names. + +**Returns**: The current instance of the SevenZip class. + +### `setZipEncryptionMethod(string $method): self` + +Sets the encryption method for ZIP archives. + +**Parameters** + +- `$method`: The encryption method to be used. Can be 'ZipCrypto' (not secure), 'AES128', 'AES192', or 'AES256'. + +**Returns**: The current instance of the SevenZip class. + ### `getTargetPath(): string` Gets the target path for compression/extraction. @@ -421,7 +496,91 @@ Resets the property values to their original state. **Returns**: The current instance of the SevenZip class. -This method resets the `customFlags`, `progressCallback`, `lastProgress`, `format`, `targetPath`, and `sourcePath` properties to their default values. +### `setPassword(?string $password): self` + +Sets the password for encryption or decryption. + +**Parameters** + +- `$password`: The password to be used for encryption or decryption. + +**Returns**: The current instance of the SevenZip class. + +### `getPassword(): ?string` + +Gets the password used for encryption or decryption. + +**Returns**: The password used for encryption or decryption, or null if not set. + +### `setEncryptNames(bool $encryptNames): self` + +Sets whether or not to encrypt file names. + +**Parameters** + +- `$encryptNames`: Whether or not to encrypt file names. + +**Returns**: The current instance of the SevenZip class. + +### `getEncryptNames(): ?bool` + +Gets whether or not file names are encrypted. + +**Returns**: Whether or not file names are encrypted, or null if not set. + +### `setZipEncryptionMethod(string $method): self` + +Sets the encryption method for ZIP archives. + +**Parameters** + +- `$method`: The encryption method to be used. Can be 'ZipCrypto' (not secure), 'AES128', 'AES192', or 'AES256'. + +**Returns**: The current instance of the SevenZip class. + +### `getZipEncryptionMethod(): string` + +Gets the encryption method used for ZIP archives. + +**Returns**: The encryption method used for ZIP archives. + +### `extract(?string $format = null, ?string $archivePath = null, ?string $extractPath = null): bool` + +Extracts an archive. + +**Parameters** + +- `$format` (optional): Archive format. +- `$archivePath` (optional): Path to the archive to extract. +- `$extractPath` (optional): Path to the directory where the archive will be extracted. + +**Returns**: `true` on success. + +**Throws** + +- `InvalidArgumentException`: If format, archive path, or extract path is not set. + +**Example** + +```php +$sevenZip->extract('7z', '/path/to/archive.7z', '/path/to/extract/directory'); +``` + +### `target(string $path): static` + +Sets the target path for compression or extraction using a fluent interface. + +**Parameters** + +- `$path`: The path to the target file or directory for compression or extraction. + +**Returns**: The current instance of the SevenZip class. + +**Example** + +```php +$sevenZip->target('/path/to/archive.7z'); +``` ## License diff --git a/src/SevenZip.php b/src/SevenZip.php index f754902..07b1971 100644 --- a/src/SevenZip.php +++ b/src/SevenZip.php @@ -77,6 +77,27 @@ class SevenZip */ protected string $sourcePath; + /** + * The password to be used for encryption or decryption. + * + * @var ?string + */ + protected ?string $password = null; + + /** + * Whether or not to encrypt file names. + * + * @var bool|null + */ + protected ?bool $encryptNames = true; + + /** + * The encryption method to be used for ZIP archives. + * + * @var string Can be 'ZipCrypto' (not secure) or 'AES128' or 'AES192' or 'AES256' + */ + protected string $zipEncryptionMethod = 'AES128'; + /** * Constructs a new SevenZip instance. * If $sevenZipPath is not provided, it will attempt to automatically detect the 7-Zip executable. @@ -100,6 +121,11 @@ public function __construct(?string $sevenZipPath = null) if ($this->getSevenZipPath() === null) { throw new ExecutableNotFoundException(); } + + // Here some options not set in $alwaysFlags to let the user override it + + // Multi-Threaded Mode ON by default + $this->mmt(); } /** @@ -125,14 +151,94 @@ public function setSevenZipPath(string $sevenZipPath): SevenZip } /** - * Sets the source path for the compression or extraction operation. + * Set the number of CPU threads to use for compression. * - * @param string $path The source path. - * @return static The current instance of the SevenZip class. + * @param int|bool|string $threads The number of CPU threads to use, or 'on' or 'off'. + * @return $this The current instance of the SevenZip class. */ - public function source(string $path): static + public function mmt(int|bool|string $threads = 'on'): self { - return $this->setSourcePath($path); + if ($threads === true) { + $threads = 'on'; + } + if ($threads === false || $threads === 0 || $threads === '0') { + $threads = 'off'; + } + + return $this->addFlag('mmt', $threads); + } + + /** + * Add a compression flag. + * + * @param string $flag The compression flag to be added. + * @param mixed $value The value for the flag (optional). + * @return $this The current instance of the SevenZip class. + */ + public function addFlag(string $flag, $value = null): self + { + $customFlags = $this->getCustomFlags(); + $customFlags[$flag] = $value; + return $this->setCustomFlags($customFlags); + } + + /** + * Get the custom compression flags. + * + * @return array The custom compression flags that have been added. + */ + public function getCustomFlags(): array + { + return $this->customFlags; + } + + /** + * Set the custom compression flags. + * + * @param array $customFlags The custom compression flags to be used. + * @return SevenZip The current instance of the SevenZip class. + */ + public function setCustomFlags(array $customFlags): SevenZip + { + $this->customFlags = $customFlags; + return $this; + } + + /** + * Encrypts the data using the provided password. + * + * @param string $password The password to encrypt the data. + * @return self Returns the current instance of this class. + */ + public function encrypt(string $password): self + { + return $this->setPassword($password); + } + + /** + * Do not encrypt file names. + * + * @return $this + */ + public function notEncryptNames(): self + { + if ($this->getFormat() === 'zip') { + $this->removeFlag('em'); + } else { + $this->removeFlag('mhe'); + } + + return $this->setEncryptNames(false); + } + + /** + * Get the archive format. + * + * @return string The compression format to be used. + */ + public function getFormat(): string + { + return $this->format ?? '7z'; } /** @@ -141,9 +247,37 @@ public function source(string $path): static * @param string $format The compression format to be used. * @return $this The current instance of the SevenZip class. */ - public function format(string $format): static + public function setFormat(string $format): self { - return $this->setFormat($format); + $this->format = $format; + return $this; + } + + /** + * Remove a compression flag. + * + * @param string $flag The compression flag to be removed. + * + * @return $this The current instance of the SevenZip class. + */ + public function removeFlag(string $flag): self + { + $customFlags = $this->getCustomFlags(); + + unset($customFlags[$flag]); + + return $this->setCustomFlags($customFlags); + } + + /** + * Decrypts the data using the provided password. + * + * @param string $password The password to decrypt the data. + * @return self Returns the current instance of this class. + */ + public function decrypt(string $password): self + { + return $this->setPassword($password); } /** @@ -158,17 +292,9 @@ public function format(string $format): static */ public function compress(?string $format = null, ?string $sourcePath = null, ?string $targetPath = null): bool { - if ($format !== null) { - $this->setFormat($format); - } - - if ($sourcePath !== null) { - $this->setSourcePath($sourcePath); - } - - if ($targetPath !== null) { - $this->setTargetPath($targetPath); - } + if ($format) $this->setFormat($format); + if ($sourcePath) $this->setSourcePath($sourcePath); + if ($targetPath) $this->setTargetPath($targetPath); if (!$this->getTargetPath()) { throw new \InvalidArgumentException('Archive file path (target) must be set or passed as argument'); @@ -178,6 +304,20 @@ public function compress(?string $format = null, ?string $sourcePath = null, ?st throw new \InvalidArgumentException('File or directory path (source) must be set or passed as argument'); } + if ($this->getFormat() === 'zip') { + if (!$this->getFlag('mm')) { + $this->mm('Deflate64'); + } + + if ($this->getPassword()) { + $this->addFlag('mem', $this->getZipEncryptionMethod()); + } + } + + if ($this->getPassword() && $this->getEncryptNames() && $this->getFormat() !== 'zip') { + $this->addFlag('mhe'); + } + $command = [ $this->sevenZipPath, 'a', @@ -188,6 +328,10 @@ public function compress(?string $format = null, ?string $sourcePath = null, ?st $this->getSourcePath(), ]; + if ($this->getPassword()) { + $command[] = '-p' . $this->getPassword(); + } + return $this->runCommand($command); } @@ -207,7 +351,7 @@ public function getTargetPath(): string * @param string $path The path to the target file or directory for compression or extraction. * @return $this The current instance of the SevenZip class. */ - public function setTargetPath(string $path): static + public function setTargetPath(string $path): self { $this->targetPath = $path; return $this; @@ -229,12 +373,72 @@ public function getSourcePath(): string * @param string $path The path to the source file or directory for compression or extraction. * @return $this The current instance of the SevenZip class. */ - public function setSourcePath(string $path): static + public function setSourcePath(string $path): self { $this->sourcePath = $path; return $this; } + public function getFlag(string $flag): mixed + { + return $this->customFlags[$flag] ?? null; + } + + /** + * Set the compression method for ZIP format + * + * @param string $method Sets a method: Copy, Deflate, Deflate64, BZip2, LZMA, PPMd. + * @return $this + */ + public function mm(string $method): self + { + return $this->addFlag('mm', $method); + } + + /** + * Get the password to be used for encryption or decryption. + * + * @return ?string The password or null if not set. + */ + public function getPassword(): ?string + { + return $this->password; + } + + /** + * Set the password to be used for encryption or decryption. + * + * @param string $password The password to be used. + * @return $this The current instance of the SevenZip class. + */ + public function setPassword(string $password): self + { + $this->password = $password; + return $this; + } + + public function getZipEncryptionMethod(): string + { + return $this->zipEncryptionMethod; + } + + public function setZipEncryptionMethod(string $zipEncryptionMethod): SevenZip + { + $this->zipEncryptionMethod = $zipEncryptionMethod; + return $this; + } + + public function getEncryptNames(): ?bool + { + return $this->encryptNames; + } + + public function setEncryptNames(?bool $encryptNames): SevenZip + { + $this->encryptNames = $encryptNames; + return $this; + } + /** * Format flags and values into an array of strings suitable for passing to 7-Zip commands. * @@ -301,50 +505,6 @@ protected function getDefaultCompressFlags(?string $format = null): array return $this->defaultCompressFlags[$this->getFormat()] ?? ['t' . $this->getFormat()]; } - /** - * Get the archive format. - * - * @return string The compression format to be used. - */ - public function getFormat(): string - { - return $this->format ?? '7z'; - } - - /** - * Set the archive format. - * - * @param string $format The compression format to be used. - * @return $this The current instance of the SevenZip class. - */ - public function setFormat(string $format): static - { - $this->format = $format; - return $this; - } - - /** - * Get the custom compression flags. - * - * @return array The custom compression flags that have been added. - */ - public function getCustomFlags(): array - { - return $this->customFlags; - } - - /** - * Set the custom compression flags. - * - * @param array $customFlags The custom compression flags to be used. - * @return SevenZip The current instance of the SevenZip class. - */ - public function setCustomFlags(array $customFlags): SevenZip - { - $this->customFlags = $customFlags; - return $this; - } - /** * Run a 7z command and parse its output. * @@ -354,6 +514,8 @@ public function setCustomFlags(array $customFlags): SevenZip */ protected function runCommand(array $command): bool { + echo 'Running command: ' . implode(' ', $command) . "\n"; + $process = new Process($command); $process->run(function ($type, $buffer) { if ($type === Process::OUT) { @@ -408,7 +570,7 @@ public function getProgressCallback(): ?callable * @param callable $callback The callback function to be called during the compression progress. * @return $this The current instance of the SevenZip class. */ - public function setProgressCallback(callable $callback): static + public function setProgressCallback(callable $callback): self { $this->progressCallback = $callback; return $this; @@ -438,7 +600,7 @@ public function getLastProgress(): int * @param int $lastProgress The last reported progress percentage. * @return SevenZip The current instance of the SevenZip class. */ - protected function setLastProgress(int $lastProgress): SevenZip + protected function setLastProgress(int $lastProgress): self { $this->lastProgress = $lastProgress; return $this; @@ -449,7 +611,7 @@ protected function setLastProgress(int $lastProgress): SevenZip * * @return SevenZip The current instance of the SevenZip class. */ - public function reset(): SevenZip + public function reset(): self { $this->customFlags = []; $this->progressCallback = null; @@ -457,17 +619,78 @@ public function reset(): SevenZip $this->format = null; $this->targetPath = ''; $this->sourcePath = ''; + $this->password = null; return $this; } + /** + * Extract an archive. + * + * @param ?string $sourcePath Path to the archive (optional). + * @param ?string $targetPath Path to extract the archive (optional). + * @return bool True on success. + * @throws \InvalidArgumentException If source path or target path is not set. + * + */ + public function extract(?string $sourcePath = null, ?string $targetPath = null): bool + { + if ($sourcePath) $this->setSourcePath($sourcePath); + if ($targetPath) $this->setTargetPath($targetPath); + + if (!$this->getSourcePath()) { + throw new \InvalidArgumentException('Archive path (source) must be set or passed as argument'); + } + + if (!$this->getTargetPath()) { + throw new \InvalidArgumentException('Extract path (target) must be set or passed as argument'); + } + + $command = [ + $this->getSevenZipPath(), + 'x', + ...$this->flagrize($this->getAlwaysFlags()), + ...$this->flagrize($this->getCustomFlags()), + $this->getSourcePath(), + '-o' . $this->getTargetPath(), + ]; + + if ($this->getPassword()) { + $command[] = '-p' . $this->getPassword(); + } + + return $this->runCommand($command); + } + + /** + * Sets the source path for the compression or extraction operation. + * + * @param string $path The source path. + * @return static The current instance of the SevenZip class. + */ + public function source(string $path): self + { + return $this->setSourcePath($path); + } + + /** + * Set the archive format. + * + * @param string $format The compression format to be used. + * @return $this The current instance of the SevenZip class. + */ + public function format(string $format): self + { + return $this->setFormat($format); + } + /** * Set the progress callback using a fluent interface. * * @param callable $callback The callback function to be called during the compression progress. * @return $this The current instance of the SevenZip class. */ - public function progress(callable $callback): static + public function progress(callable $callback): self { return $this->setProgressCallback($callback); } @@ -477,7 +700,7 @@ public function progress(callable $callback): static * * @return $this The current instance of the SevenZip class. */ - public function faster(): static + public function faster(): self { if ($this->getFormat() === 'zstd' || $this->getFormat() === 'zst') { return $this->mx(0); @@ -492,31 +715,17 @@ public function faster(): static * @param int $level The compression level to be used. * @return $this The current instance of the SevenZip class. */ - public function mx(int $level): static + public function mx(int $level): self { return $this->addFlag('mx', $level); } - /** - * Add a compression flag. - * - * @param string $flag The compression flag to be added. - * @param mixed $value The value for the flag (optional). - * @return $this The current instance of the SevenZip class. - */ - public function addFlag(string $flag, $value = null): static - { - $customFlags = $this->getCustomFlags(); - $customFlags[$flag] = $value; - return $this->setCustomFlags($customFlags); - } - /** * Set the compression level to slower. * * @return $this The current instance of the SevenZip class. */ - public function slower(): static + public function slower(): self { if ($this->getFormat() === 'zstd' || $this->getFormat() === 'zst') { return $this->mx(22); @@ -530,7 +739,7 @@ public function slower(): static * * @return static The current instance for method chaining. */ - public function ultra(): static + public function ultra(): self { $this->mmt(true)->mx(9); @@ -544,23 +753,12 @@ public function ultra(): static }; } - /** - * Set the number of CPU threads to use for compression. + /* + * Sets level of file analysis. * - * @param int|bool|string $threads The number of CPU threads to use, or 'on' or 'off'. - * @return $this The current instance of the SevenZip class. + * @param int $level + * @return $this */ - public function mmt(int|bool|string $threads = 'on'): static - { - if ($threads === true) { - $threads = 'on'; - } - if ($threads === false || $threads === 0 || $threads === '0') { - $threads = 'off'; - } - - return $this->addFlag('mmt', $threads); - } public function mmem(int|string $size = 24) { @@ -573,7 +771,7 @@ public function mmem(int|string $size = 24) * @param int $number The number of passes for compression. * @return $this The current instance of the SevenZip class. */ - public function mpass(int $number = 7): static + public function mpass(int $number = 7): self { return $this->addFlag('mpass', $number); } @@ -584,28 +782,17 @@ public function mpass(int $number = 7): static * @param int $bytes The size of the Fast Bytes. The default value (when set) is 64. * @return $this The current instance of the SevenZip class. */ - public function mfb(int $bytes = 64): static + public function mfb(int $bytes = 64): self { return $this->addFlag('mfb', $bytes); } - /** - * Set the compression method for ZIP format - * - * @param string $method Sets a method: Copy, Deflate, Deflate64, BZip2, LZMA, PPMd. - * @return $this - */ - public function mm(string $method = 'Deflate'): static - { - return $this->addFlag('mm', $method); - } - - public function md(string $size = '32m'): static + public function md(string $size = '32m'): self { return $this->addFlag('md', $size); } - public function ms(bool|string|int $on = true): static + public function ms(bool|string|int $on = true): self { return $this->addFlag('ms', $on ? 'on' : 'off'); } @@ -615,24 +802,17 @@ public function ms(bool|string|int $on = true): static * @param $method string The compression method to be used. * @return $this */ - public function m0($method): static + public function m0($method): self { return $this->addFlag('m0', $method); } - /* - * Sets level of file analysis. - * - * @param int $level - * @return $this - */ - /** * Configures no compression (copy only) settings based on the specified format. * * @return static The current instance for method chaining. */ - public function copy(): static + public function copy(): self { return $this->mmt(true)->mx(0)->m0('Copy')->mm('Copy')->myx(0); } @@ -643,74 +823,19 @@ public function copy(): static * @param int $level * @return $this */ - public function myx(int $level = 5): static + public function myx(int $level = 5): self { return $this->addFlag('myx', $level); } - /** - * Extract an archive. - * - * @param ?string $sourcePath Path to the archive (optional). - * @param ?string $targetPath Path to extract the archive (optional). - * @return bool True on success. - * @throws \InvalidArgumentException If source path or target path is not set. - * - */ - public function extract(?string $sourcePath = null, ?string $targetPath = null): bool - { - if ($sourcePath !== null) { - $this->setSourcePath($sourcePath); - } - - if ($targetPath !== null) { - $this->setTargetPath($targetPath); - } - - if (!$this->getSourcePath()) { - throw new \InvalidArgumentException('Archive path (source) must be set or passed as argument'); - } - - if (!$this->getTargetPath()) { - throw new \InvalidArgumentException('Extract path (target) must be set or passed as argument'); - } - - $command = [ - $this->getSevenZipPath(), - 'x', - ...$this->flagrize($this->getAlwaysFlags()), - ...$this->flagrize($this->getCustomFlags()), - $this->getSourcePath(), - '-o' . $this->getTargetPath(), - ]; - - return $this->runCommand($command); - } - /** * Set the target path for compression/extraction using a fluent interface. * * @param string|null $path The path to the target file or directory for compression or extraction. * @return $this The current instance of the SevenZip class. */ - public function target(?string $path): static + public function target(?string $path): self { return $this->setTargetPath($path); } - - /** - * Remove a compression flag. - * - * @param string $flag The compression flag to be removed. - * - * @return $this The current instance of the SevenZip class. - */ - public function removeFlag(string $flag): static - { - $customFlags = $this->getCustomFlags(); - - unset($customFlags[$flag]); - - return $this->setCustomFlags($customFlags); - } } diff --git a/tests/SevenZipTest.php b/tests/SevenZipTest.php index 155591c..2712891 100644 --- a/tests/SevenZipTest.php +++ b/tests/SevenZipTest.php @@ -288,4 +288,57 @@ public function testGetDefaultCompressFlags(): void $this->assertEquals(['t7z', 'm0' => 'bzip2'], $defaultFlags->invoke($this->sevenZip, 'bzip2')); $this->assertEquals(['tmy_format'], $defaultFlags->invoke($this->sevenZip, 'my_format')); } + + /** + * Test encrypting and decrypting a file. + * + * @return void + */ + public function testEncryptAndDecrypt(): void + { + $password = 'my_secret_password'; + $sourceFile = $this->testDir . '/source/Avatart.svg'; + $encryptedFile = $this->testDir . '/target/test.encrypted.7z'; + $decryptedFile = $this->testDir . '/target/'; + + // Compress and encrypt the file + $this->sevenZip->encrypt($password) + ->source($sourceFile) + ->target($encryptedFile) + ->compress(); + + $this->assertFileExists($encryptedFile); + + // Decrypt and extract the file + $this->sevenZip->decrypt($password) + ->source($encryptedFile) + ->target($decryptedFile) + ->extract(); + + $this->assertFileExists($decryptedFile); + $this->assertFileEquals($sourceFile, $decryptedFile . 'Avatart.svg'); + } + + /** + * Test encrypting a ZIP file with a specific encryption method. + * + * @return void + */ + public function testEncryptZipWithEncryptionMethod(): void + { + $password = 'my_secret_password'; + $format = 'zip'; + $directory = $this->testDir . '/source'; + $archive = $this->testDir . '/target/archive.' . $format; + + // Compress and encrypt the ZIP file with AES256 encryption + $this->sevenZip->encrypt($password) + ->setZipEncryptionMethod('AES256') + ->source($directory) + ->target($archive) + ->compress($format); + + $this->assertFileExists($archive); + + } } diff --git a/try.php b/try.php index 607fbf6..496d214 100644 --- a/try.php +++ b/try.php @@ -5,9 +5,10 @@ use Verseles\SevenZip\SevenZip; -$archivePath = '/Users/helio/zip-tiny.7z'; +$archivePath = '/Users/helio/zip-big.7z'; $extractPath = '/Users/helio/tmp'; -$fileToCompress = '/Users/helio/zip-tiny'; +$fileToCompress = '/Users/helio/zip-big'; +$password = 'test2'; @unlink($archivePath); @unlink($extractPath . '/' . $fileToCompress); @@ -21,29 +22,31 @@ ->setProgressCallback(function ($progress) { echo "\n" . $progress . "%\n"; }) - ->format('7z') + ->format('zstd') + ->encrypt($password) ->source($fileToCompress) ->target($archivePath) ->compress(); echo "✅\n"; - -echo 'Extracting archive... '; -$sevenZip - ->setProgressCallback(function ($progress) { - echo "\n" . $progress . "%\n"; - }) - ->source($archivePath) - ->target($extractPath) - ->extract(); -echo "✅\n"; - -echo "Deleting archive... "; -unlink($archivePath); -echo "✅\n"; - -echo "Clearing directory... "; -clearDirectory($extractPath); -echo "✅\n"; +// +//echo 'Extracting archive... '; +//$sevenZip +// ->setProgressCallback(function ($progress) { +// echo "\n" . $progress . "%\n"; +// }) +// ->source($archivePath) +// ->target($extractPath) +// ->decrypt($password) +// ->extract(); +//echo "✅\n"; +// +//echo "Deleting archive... "; +//unlink($archivePath); +//echo "✅\n"; +// +//echo "Clearing directory... "; +//clearDirectory($extractPath); +//echo "✅\n"; /** * Clears a directory by removing all files and subdirectories within it,