From 69193e402fadaba9b2391cda5453582b09ca0afe Mon Sep 17 00:00:00 2001 From: Adam Daley Date: Sat, 22 Apr 2023 06:21:34 +0100 Subject: [PATCH] Remove Box/Zip in favour of library (#1123) Remove custom Box/Zip class in favour of nelexa/zip library. --- src/library/Box/Update.php | 13 +++- src/library/Box/Zip.php | 48 ------------ src/modules/Extension/Service.php | 30 +++++--- tests/modules/Extension/ServiceTest.php | 97 +------------------------ 4 files changed, 32 insertions(+), 156 deletions(-) delete mode 100644 src/library/Box/Zip.php diff --git a/src/library/Box/Update.php b/src/library/Box/Update.php index df39ba5cf..eb72d0a73 100644 --- a/src/library/Box/Update.php +++ b/src/library/Box/Update.php @@ -13,6 +13,8 @@ * with this source code in the file LICENSE */ +use PhpZip\ZipFile; + class Box_Update { /** @@ -175,8 +177,15 @@ class Box_Update //@todo validate downloaded file hash // Extract latest archive on top of current version - $ff = new Box_Zip($latest_version_archive); - $ff->decompress(PATH_ROOT); + $zip = new ZipFile(); + try { + $zip->openFile($latest_version_archive); + $zip->extractTo(PATH_ROOT); + $zip->close(); + } catch (\PhpZip\Exception\ZipException $e) { + error_log($e->getMessage()); + throw new \Box_Exception('Failed to extract file, please check file and folder permissions. Further details are available in the error log.'); + } if(file_exists(PATH_ROOT.'/foss-update.php')) { error_log('Calling foss-update.php script from auto-updater'); diff --git a/src/library/Box/Zip.php b/src/library/Box/Zip.php deleted file mode 100644 index 547fb471d..000000000 --- a/src/library/Box/Zip.php +++ /dev/null @@ -1,48 +0,0 @@ -zip = $zip; - } - - function decompress($to, $runFromTest = false) - { - if ($runFromTest) { - return true; - } else { - if(!file_exists($this->zip)) { - throw new \Box_Exception('File :file does not exist', array(':file'=>$this->zip)); - } - - $zip = new \PhpZip\ZipFile(); - try{ - $zip->openFile($this->zip); - $zip->extractTo($to); - $zip->close(); - - return true; - } - catch(\PhpZip\Exception\ZipException $e){ - $zip->close(); - error_log($e->getMessage()); - throw new \Box_Exception('Failed to extract file, please check file and folder permissions. Further details are available in the error log.'); - } - } - } -} diff --git a/src/modules/Extension/Service.php b/src/modules/Extension/Service.php index 76775c838..ddb3f680a 100644 --- a/src/modules/Extension/Service.php +++ b/src/modules/Extension/Service.php @@ -17,6 +17,7 @@ namespace Box\Mod\Extension; use Box\InjectionAwareInterface; +use PhpZip\ZipFile; class Service implements InjectionAwareInterface { @@ -435,7 +436,7 @@ class Service implements InjectionAwareInterface return true; } - public function downloadAndExtract($type, $id, $runFromTest = false) + public function downloadAndExtract($type, $id) { $ext = $this->di['extension']; $manifest = $ext->getExtension($id, $type); @@ -444,14 +445,14 @@ class Service implements InjectionAwareInterface throw new \Exception('Invalid download URL for the extension'); } - $extracted = PATH_CACHE . '/' . md5(uniqid()); - $zip = PATH_CACHE . '/' . md5(uniqid()) . '.zip'; + $extractedPath = PATH_CACHE . '/' . md5(uniqid()); + $zipPath = PATH_CACHE . '/' . md5(uniqid()) . '.zip'; // Create a temporary directory to extract the extension - mkdir($extracted, 0755, true); + mkdir($extractedPath, 0755, true); // Download the extension archive and save it to the cache folder - $fileHandler = fopen($zip, 'w'); + $fileHandler = fopen($zipPath, 'w'); $client = $this->di['http_client']; $response = $client->request('GET', $manifest['download_url']); @@ -465,8 +466,15 @@ class Service implements InjectionAwareInterface } // Extract the archive - $ff = new \Box_Zip($zip); - $ff->decompress($extracted, $runFromTest); + $zip = new ZipFile(); + try { + $zip->openFile($zipPath); + $zip->extractTo($extractedPath); + $zip->close(); + } catch (\PhpZip\Exception\ZipException $e) { + error_log($e->getMessage()); + throw new \Box_Exception('Failed to extract file, please check file and folder permissions. Further details are available in the error log.'); + } switch ($type) { case \Box_Extension::TYPE_MOD: @@ -487,18 +495,18 @@ class Service implements InjectionAwareInterface if (file_exists($destination)) { throw new \Box_Exception('Extension :id seems to be already installed.', [':id' => $id], 436); } - if (!rename($extracted, $destination)) { + if (!rename($extractedPath, $destination)) { throw new \Box_Exception('Failed to move extension to it\'s final destination. Please check permissions for the destination folder. (:destination)', [':destination' => $destination], 437); } } else { throw new \Box_Exception('Extension type (:type) cannot be automatically installed.', [':type' => $type]); } - if (file_exists($zip)) { - unlink($zip); + if (file_exists($zipPath)) { + unlink($zipPath); } - $this->di['tools']->emptyFolder($extracted); + $this->di['tools']->emptyFolder($extractedPath); return true; } diff --git a/tests/modules/Extension/ServiceTest.php b/tests/modules/Extension/ServiceTest.php index 2614dbabb..a602e6018 100644 --- a/tests/modules/Extension/ServiceTest.php +++ b/tests/modules/Extension/ServiceTest.php @@ -26,7 +26,6 @@ class ServiceTest extends \BBTestCase { $this->service = new \Box\Mod\Extension\Service(); } - public function testgetDi() { $di = new \Box_Di(); @@ -588,99 +587,7 @@ class ServiceTest extends \BBTestCase { $this->assertTrue($result); } - public function testdownloadAndExtract() - { - $extensionMock = $this->getMockBuilder(\Box_Extension::class)->getMock(); - - $extensionMock->expects($this->atLeastOnce()) - ->method('getExtension') - ->will($this->returnValue(array('download_url' => 'www.fossbilling.com'))); - - $httpClientMock = new MockHttpClient(); - - $toolsMock = $this->getMockBuilder(\Box_tools::class)->getMock(); - $toolsMock->expects($this->atLeastOnce()) - ->method('emptyFolder'); - - $di = new \Box_Di(); - $di['extension'] = $extensionMock; - $di['http_client'] = $httpClientMock; - $di['tools'] = $toolsMock; - - $this->service->setDi($di); - $result = $this->service->downloadAndExtract('mod', 'extensionId', true); - $this->assertTrue($result); - } - - public function testdownloadAndExtractTypeExceptionNotDefinedTypeException() - { - $extensionMock = $this->getMockBuilder(\Box_Extension::class)->getMock(); - - $extensionMock->expects($this->atLeastOnce()) - ->method('getExtension') - ->will($this->returnValue(array('download_url' => 'www.fossbilling.com'))); - - $httpClientMock = new MockHttpClient(); - - $di = new \Box_Di(); - $di['extension'] = $extensionMock; - $di['http_client'] = $httpClientMock; - - $this->service->setDi($di); - $this->expectException(\Box_Exception::class); - $this->expectExceptionMessage('Extension type (notDefinedType) cannot be automatically installed.'); - $this->service->downloadAndExtract('notDefinedType', 'extensionId', true); - } - - public function testdownloadAndExtractTranslationException() - { - $extensionMock = $this->getMockBuilder(\Box_Extension::class)->getMock(); - - $extensionMock->expects($this->atLeastOnce()) - ->method('getExtension') - ->will($this->returnValue(array('download_url' => 'www.fossbilling.com'))); - - $httpClientMock = new MockHttpClient(); - - $toolsMock = $this->getMockBuilder(\Box_tools::class)->getMock(); - - $di = new \Box_Di(); - $di['extension'] = $extensionMock; - $di['http_client'] = $httpClientMock; - $di['tools'] = $toolsMock; - - $this->service->setDi($di); - $this->expectException(\Box_Exception::class); - $this->expectExceptionCode(437); - $this->expectExceptionMessage("Failed to move extension to it's final destination. Please check permissions for the destination folder. (/home/runner/work/FOSSBilling/FOSSBilling/src/locale/extensionId/LC_MESSAGES)"); - $this->service->downloadAndExtract('translation', 'extensionId', true); - } - - public function testdownloadAndExtractFileExistsException() - { - $extensionMock = $this->getMockBuilder(\Box_Extension::class)->getMock(); - - $extensionMock->expects($this->atLeastOnce()) - ->method('getExtension') - ->will($this->returnValue(array('download_url' => 'www.fossbilling.com'))); - - $httpClientMock = new MockHttpClient(); - - $toolsMock = $this->getMockBuilder(\Box_tools::class)->getMock(); - - $di = new \Box_Di(); - $di['extension'] = $extensionMock; - $di['http_client'] = $httpClientMock; - $di['tools'] = $toolsMock; - - $this->service->setDi($di); - $this->expectException(\Box_Exception::class); - $this->expectExceptionCode(436); - $this->expectExceptionMessage('Extension extensionId seems to be already installed.'); - $this->service->downloadAndExtract('mod', 'extensionId', true); - } - - public function testdownloadAndExtractDownloadUrlMisssing() + public function testdownloadAndExtractDownloadUrlMissing() { $extensionMock = $this->getMockBuilder(\Box_Extension::class)->getMock(); @@ -694,7 +601,7 @@ class ServiceTest extends \BBTestCase { $this->service->setDi($di); $this->expectException(\Exception::class); $this->expectExceptionMessage('Invalid download URL for the extension'); - $this->service->downloadAndExtract('mod', 'extensionId', true); + $this->service->downloadAndExtract('mod', 'extensionId'); } public function testgetInstalledMods()