diff --git a/composer.json b/composer.json index 728defa29a..37d67c88e1 100644 --- a/composer.json +++ b/composer.json @@ -33,6 +33,7 @@ "guzzlehttp/guzzle": "^7.5", "monolog/monolog": "^3.3", "myclabs/deep-copy": "~1.0", + "nelexa/zip": "^4.0", "phpseclib/phpseclib": "~3.0", "robthree/twofactorauth": "^2.0.0", "symfony/html-sanitizer": "^6.2", diff --git a/composer.lock b/composer.lock index 4ef68a5bea..3e62195c02 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "13666641f80659e4109aa3cee1819ddc", + "content-hash": "b6c9a123694ddd05b27a735986c04e45", "packages": [ { "name": "abraham/twitteroauth", @@ -1395,6 +1395,79 @@ ], "time": "2023-03-08T13:26:56+00:00" }, + { + "name": "nelexa/zip", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/Ne-Lexa/php-zip.git", + "reference": "88a1b6549be813278ff2dd3b6b2ac188827634a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ne-Lexa/php-zip/zipball/88a1b6549be813278ff2dd3b6b2ac188827634a7", + "reference": "88a1b6549be813278ff2dd3b6b2ac188827634a7", + "shasum": "" + }, + "require": { + "ext-zlib": "*", + "php": "^7.4 || ^8.0", + "psr/http-message": "*", + "symfony/finder": "*" + }, + "require-dev": { + "ext-bz2": "*", + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-iconv": "*", + "ext-openssl": "*", + "ext-xml": "*", + "friendsofphp/php-cs-fixer": "^3.4.0", + "guzzlehttp/psr7": "^1.6", + "phpunit/phpunit": "^9", + "symfony/http-foundation": "*", + "symfony/var-dumper": "*", + "vimeo/psalm": "^4.6" + }, + "suggest": { + "ext-bz2": "Needed to support BZIP2 compression", + "ext-fileinfo": "Needed to get mime-type file", + "ext-iconv": "Needed to support convert zip entry name to requested character encoding", + "ext-openssl": "Needed to support encrypt zip entries or use ext-mcrypt" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpZip\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ne-Lexa", + "email": "alexey@nelexa.ru", + "role": "Developer" + } + ], + "description": "PhpZip is a php-library for extended work with ZIP-archives. Open, create, update, delete, extract and get info tool. Supports appending to existing ZIP files, WinZip AES encryption, Traditional PKWARE Encryption, BZIP2 compression, external file attributes and ZIP64 extensions. Alternative ZipArchive. It does not require php-zip extension.", + "homepage": "https://github.com/Ne-Lexa/php-zip", + "keywords": [ + "archive", + "extract", + "unzip", + "winzip", + "zip", + "ziparchive" + ], + "support": { + "issues": "https://github.com/Ne-Lexa/php-zip/issues", + "source": "https://github.com/Ne-Lexa/php-zip/tree/4.0.2" + }, + "time": "2022-06-17T11:17:46+00:00" + }, { "name": "paragonie/constant_time_encoding", "version": "v2.6.3", @@ -2475,6 +2548,70 @@ ], "time": "2023-05-23T14:45:45+00:00" }, + { + "name": "symfony/finder", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/d9b01ba073c44cef617c7907ce2419f8d00d75e2", + "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-04-02T01:25:41+00:00" + }, { "name": "symfony/html-sanitizer", "version": "v6.3.0", diff --git a/phpmyfaq/src/phpMyFAQ/Setup/Upgrade.php b/phpmyfaq/src/phpMyFAQ/Setup/Upgrade.php index d793c6f9b5..e548e2b091 100644 --- a/phpmyfaq/src/phpMyFAQ/Setup/Upgrade.php +++ b/phpmyfaq/src/phpMyFAQ/Setup/Upgrade.php @@ -16,7 +16,6 @@ namespace phpMyFAQ\Setup; -use JsonException; use Monolog\Level; use phpMyFAQ\Configuration; use phpMyFAQ\Setup; @@ -26,7 +25,8 @@ use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; -use ZipArchive; +use PhpZip\ZipFile; +use PhpZip\Exception\ZipException; class Upgrade extends Setup { @@ -129,8 +129,8 @@ public function downloadPackage(string $version): string|bool * * @return bool * @throws TransportExceptionInterface|ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|JsonException - * @var string $path | Path to zip file - * @var string $version | Version to verify + * @param string $path | Path to zip file + * @param string $version | Version to verify */ public function verifyPackage(string $path, string $version): bool { @@ -163,34 +163,67 @@ public function verifyPackage(string $path, string $version): bool * Method to unpack the downloaded phpMyFAQ package * * @return bool - * @var string $path Path of the package + * @param string $path | Path of the package + * @throws ZipException */ public function unpackPackage(string $path): bool { - $zip = new ZipArchive(); - if (!$zip->open($path)) { - $this->configuration->getLogger()->log(Level::Error, $zip->getStatusString()); + $zip = new ZipFile(); + try { + if (!is_file($path)) { + return false; + } else { + $zip->openFile($path); + $zip->extractTo(PMF_CONTENT_DIR . '/upgrades/'); + $zip->close(); + return true; + } + } catch (ZipException $e) { + $this->configuration->getLogger()->log(Level::Error, $e->getMessage()); return false; - } else { - if (!$zip->extractTo(PMF_CONTENT_DIR . '/upgrades/')) { - $this->configuration->getLogger()->log(Level::Error, $zip->getStatusString()); + } + } + /** + * Method to create a temporary backup of the current files + * + * @param string $backupName | Name of the created backup + * @return bool + * @throws ZipException + */ + public function createTemporaryBackup(string $backupName): bool + { + try { + $zip = new ZipFile(); + if (!is_file(PMF_CONTENT_DIR . '/upgrades/' . $backupName)) { + $zip->addDirRecursive(PMF_ROOT_DIR); + $zip->saveAsFile(PMF_CONTENT_DIR . '/upgrades/' . $backupName); + $zip->close(); + return true; + } else { return false; } - $zip->close(); + } catch (ZipException $e) { + $this->configuration->getLogger()->log(Level::Error, $e->getMessage()); - return true; + return false; } } - /** - * Method to create a temporary backup of the current files + /** + * Method to delete the temporary created backup. * - * @return void + * @param string $backupName | Name of the created backup + * @return bool */ - public function createTemporaryBackup() + public function deleteTemporaryBackup(string $backupName): bool { + if (is_file(PMF_CONTENT_DIR . '/upgrades/' . $backupName)) { + return unlink(PMF_CONTENT_DIR . '/upgrades/' . $backupName); + } else { + return false; + } } /**