diff --git a/classes/Task/Update/Download.php b/classes/Task/Update/Download.php index 0ce41a9fd..15e677d3f 100644 --- a/classes/Task/Update/Download.php +++ b/classes/Task/Update/Download.php @@ -49,7 +49,7 @@ class Download extends AbstractTask public function run(): int { if (!\ConfigurationTest::test_fopen() && !\ConfigurationTest::test_curl()) { - $this->logger->error($this->translator->trans('You need allow_url_fopen or cURL enabled for automatic download to work. You can also manually upload it in filepath %s.', [$this->container->getFilePath()])); + $this->logger->error($this->translator->trans('You need allow_url_fopen or cURL enabled for automatic download to work. You can also manually upload it in filepath %s.', [$this->container->getArchiveFilePath()])); $this->next = TaskName::TASK_ERROR; return ExitCode::FAIL; @@ -60,25 +60,19 @@ public function run(): int ); $this->logger->debug($this->translator->trans('Downloading from %s', [$this->container->getUpgrader()->getOnlineDestinationRelease()->getZipDownloadUrl()])); - $this->logger->debug($this->translator->trans('File will be saved in %s', [$this->container->getFilePath()])); + $this->logger->debug($this->translator->trans('File will be saved in %s', [$this->container->getArchiveFilePath()])); - $downloadPath = $this->container->getProperty(UpgradeContainer::DOWNLOAD_PATH); - - if ($this->container->getFileSystem()->exists($downloadPath)) { - foreach (scandir($downloadPath) as $item) { - if ($item !== '.' && $item !== '..') { - $path = $downloadPath . DIRECTORY_SEPARATOR . $item; - $this->container->getFileSystem()->remove($path); - } - } + $releasesDir = $this->container->getProperty(UpgradeContainer::TMP_RELEASES_DIR); + if ($this->container->getFilesystemAdapter()->clearDirectory($releasesDir)) { $this->logger->debug($this->translator->trans('Download directory has been emptied')); } + $report = ''; - $relative_download_path = str_replace(_PS_ROOT_DIR_, '', $downloadPath); + $relative_download_path = str_replace(_PS_ROOT_DIR_, '', $releasesDir); if (\ConfigurationTest::test_dir($relative_download_path, false, $report)) { $this->downloadArchive(); } else { - $this->logger->error($this->translator->trans('Download directory %s is not writable.', [$this->container->getProperty(UpgradeContainer::DOWNLOAD_PATH)])); + $this->logger->error($this->translator->trans('Download directory %s is not writable.', [$this->container->getProperty(UpgradeContainer::TMP_RELEASES_DIR)])); $this->next = TaskName::TASK_ERROR; } @@ -92,7 +86,7 @@ public function run(): int */ public function downloadArchive(): void { - $destPath = realpath($this->container->getProperty(UpgradeContainer::DOWNLOAD_PATH)) . DIRECTORY_SEPARATOR . $this->container->getProperty(UpgradeContainer::ARCHIVE_FILENAME); + $destPath = realpath($this->container->getProperty(UpgradeContainer::TMP_RELEASES_DIR)) . DIRECTORY_SEPARATOR . $this->container->getProperty(UpgradeContainer::ARCHIVE_FILENAME); $archiveUrl = $this->container->getUpgrader()->getOnlineDestinationRelease()->getZipDownloadUrl(); try { diff --git a/classes/Task/Update/Unzip.php b/classes/Task/Update/Unzip.php index 646dd74d3..439e604f5 100644 --- a/classes/Task/Update/Unzip.php +++ b/classes/Task/Update/Unzip.php @@ -47,22 +47,15 @@ class Unzip extends AbstractTask */ public function run(): int { - $filepath = $this->container->getFilePath(); - $destExtract = $this->container->getProperty(UpgradeContainer::LATEST_PATH); + $filepath = $this->container->getArchiveFilePath(); + $destExtract = $this->container->getProperty(UpgradeContainer::TMP_FILES_PATH); $this->container->getUpdateState()->setProgressPercentage( $this->container->getCompletionCalculator()->getBasePercentageOfTask(self::class) ); - if ($this->container->getFileSystem()->exists($destExtract)) { - foreach (scandir($destExtract) as $item) { - if ($item !== '.' && $item !== '..') { - $path = $destExtract . DIRECTORY_SEPARATOR . $item; - $this->container->getFileSystem()->remove($path); - } - } - - $this->logger->debug($this->translator->trans('"/latest" directory has been emptied')); + if ($this->container->getFilesystemAdapter()->clearDirectory($destExtract)) { + $this->logger->debug($this->translator->trans('files directory has been emptied')); } $relative_extract_path = str_replace(_PS_ROOT_DIR_, '', $destExtract); $report = ''; diff --git a/classes/Task/Update/UpdateComplete.php b/classes/Task/Update/UpdateComplete.php index 62f9d6c32..990d4afb7 100644 --- a/classes/Task/Update/UpdateComplete.php +++ b/classes/Task/Update/UpdateComplete.php @@ -63,8 +63,8 @@ public function run(): int $this->next = TaskName::TASK_COMPLETE; $filesystem = $this->container->getFileSystem(); - $filePath = $this->container->getFilePath(); - $latestPath = $this->container->getProperty(UpgradeContainer::LATEST_PATH); + $filePath = $this->container->getArchiveFilePath(); + $latestPath = $this->container->getProperty(UpgradeContainer::TMP_FILES_PATH); if ($filesystem->exists($filePath)) { if ($this->container->getUpdateConfiguration()->isChannelOnline()) { @@ -79,6 +79,11 @@ public function run(): int } // removing temporary files + $tmpModulePath = $this->container->getProperty(UpgradeContainer::TMP_MODULES_PATH); + if ($this->container->getFilesystemAdapter()->clearDirectory($tmpModulePath)) { + $this->logger->debug($this->translator->trans('The temporary directory of modules has been emptied')); + } + $this->container->getFileStorage()->cleanAllUpdateFiles(); $this->container->getAnalytics()->track('Upgrade Succeeded', Analytics::WITH_UPDATE_PROPERTIES); diff --git a/classes/Task/Update/UpdateFiles.php b/classes/Task/Update/UpdateFiles.php index 27bf9089a..b40dbbb39 100644 --- a/classes/Task/Update/UpdateFiles.php +++ b/classes/Task/Update/UpdateFiles.php @@ -112,7 +112,7 @@ public function upgradeThisFile($orig): bool // later, we could handle customization with some kind of diff functions // for now, just copy $file in str_replace($this->latestRootDir,_PS_ROOT_DIR_) - $file = str_replace($this->container->getProperty(UpgradeContainer::LATEST_PATH), '', $orig); + $file = str_replace($this->container->getProperty(UpgradeContainer::TMP_FILES_PATH), '', $orig); // The path to the file in our prestashop directory $dest = $this->destUpgradePath . $file; @@ -203,7 +203,7 @@ protected function warmUp(): int ); // Get path to the folder with release we will use to upgrade and check if it's valid - $newReleasePath = $this->container->getProperty(UpgradeContainer::LATEST_PATH); + $newReleasePath = $this->container->getProperty(UpgradeContainer::TMP_FILES_PATH); if (!$this->container->getFilesystemAdapter()->isReleaseValid($newReleasePath)) { $this->logger->error($this->translator->trans('Could not assert the folder %s contains a valid PrestaShop release, exiting.', [$newReleasePath])); $this->logger->error($this->translator->trans('A file may be missing, or the release is stored in a subfolder by mistake.')); diff --git a/classes/Task/Update/UpdateModules.php b/classes/Task/Update/UpdateModules.php index 7eb34fc72..db95a1dee 100644 --- a/classes/Task/Update/UpdateModules.php +++ b/classes/Task/Update/UpdateModules.php @@ -66,9 +66,9 @@ public function run(): int $modulesPath = $this->container->getProperty(UpgradeContainer::PS_ROOT_PATH) . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR; $moduleSourceList = new ModuleSourceAggregate($this->container->getModuleSourceProviders()); - $moduleDownloader = new ModuleDownloader($this->container->getDownloadService(), $this->translator, $this->logger, $this->container->getProperty(UpgradeContainer::TMP_PATH)); + $moduleDownloader = new ModuleDownloader($this->container->getDownloadService(), $this->translator, $this->logger, $this->container->getProperty(UpgradeContainer::TMP_MODULES_DIR)); $moduleUnzipper = new ModuleUnzipper($this->translator, $this->container->getZipAction(), $modulesPath); - $moduleMigration = new ModuleMigration($this->container->getFileSystem(), $this->translator, $this->logger, $this->container->getProperty(UpgradeContainer::TMP_PATH)); + $moduleMigration = new ModuleMigration($this->container->getFileSystem(), $this->translator, $this->logger, $this->container->getProperty(UpgradeContainer::TMP_MODULES_DIR)); if ($listModules->getRemainingTotal()) { $moduleInfos = $listModules->getNext(); diff --git a/classes/UpgradeContainer.php b/classes/UpgradeContainer.php index 463f3b510..128708f98 100644 --- a/classes/UpgradeContainer.php +++ b/classes/UpgradeContainer.php @@ -84,16 +84,23 @@ */ class UpgradeContainer { - const WORKSPACE_PATH = 'workspace'; // AdminSelfUpgrade::$autoupgradePath + const WORKSPACE_PATH = 'workspace'; const BACKUP_PATH = 'backup'; const DOWNLOAD_PATH = 'download'; - const LATEST_PATH = 'latest'; // AdminSelfUpgrade::$latestRootDir - const LATEST_DIR = 'latest/'; const LOGS_PATH = 'logs'; + + // temporary folders const TMP_PATH = 'tmp'; + const TMP_FILES_PATH = 'files'; + const TMP_FILES_DIR = 'files/'; + const TMP_MODULES_PATH = 'modules'; + const TMP_MODULES_DIR = 'modules/'; + const TMP_RELEASES_PATH = 'releases'; + const TMP_RELEASES_DIR = 'releases/'; + const PS_ADMIN_PATH = 'ps_admin'; const PS_ADMIN_SUBDIR = 'ps_admin_subdir'; - const PS_ROOT_PATH = 'ps_root'; // AdminSelfUpgrade::$prodRootDir + const PS_ROOT_PATH = 'ps_root'; const ARCHIVE_FILENAME = 'destDownloadFilename'; const ARCHIVE_FILEPATH = 'destDownloadFilepath'; const PS_VERSION = 'version'; @@ -275,18 +282,26 @@ public function getProperty(string $property): ?string return $this->autoupgradeWorkDir . DIRECTORY_SEPARATOR . 'backup'; case self::DOWNLOAD_PATH: return $this->autoupgradeWorkDir . DIRECTORY_SEPARATOR . 'download'; - case self::LATEST_PATH: - return $this->autoupgradeWorkDir . DIRECTORY_SEPARATOR . 'latest'; - case self::LATEST_DIR: - return $this->autoupgradeWorkDir . DIRECTORY_SEPARATOR . 'latest' . DIRECTORY_SEPARATOR; case self::TMP_PATH: return $this->autoupgradeWorkDir . DIRECTORY_SEPARATOR . 'tmp'; + case self::TMP_MODULES_PATH: + return $this->getProperty(self::TMP_PATH) . DIRECTORY_SEPARATOR . 'modules'; + case self::TMP_MODULES_DIR: + return $this->getProperty(self::TMP_MODULES_PATH) . DIRECTORY_SEPARATOR; + case self::TMP_RELEASES_PATH: + return $this->getProperty(self::TMP_PATH) . DIRECTORY_SEPARATOR . 'releases'; + case self::TMP_RELEASES_DIR: + return $this->getProperty(self::TMP_RELEASES_PATH) . DIRECTORY_SEPARATOR; + case self::TMP_FILES_PATH: + return $this->getProperty(self::TMP_PATH) . DIRECTORY_SEPARATOR . 'files'; + case self::TMP_FILES_DIR: + return $this->getProperty(self::TMP_FILES_PATH) . DIRECTORY_SEPARATOR; case self::LOGS_PATH: return $this->autoupgradeWorkDir . DIRECTORY_SEPARATOR . 'logs'; case self::ARCHIVE_FILENAME: return $this->getUpdateConfiguration()->getChannelZip(); case self::ARCHIVE_FILEPATH: - return $this->getProperty(self::DOWNLOAD_PATH) . DIRECTORY_SEPARATOR . $this->getProperty(self::ARCHIVE_FILENAME); + return $this->getArchiveFilePath(); case self::PS_VERSION: return $this->getPrestaShopConfiguration()->getPrestaShopVersion(); default: @@ -294,6 +309,20 @@ public function getProperty(string $property): ?string } } + /** + * @throws Exception + */ + public function getArchiveFilePath(): ?string + { + $fileName = $this->getProperty(self::ARCHIVE_FILENAME); + + if ($this->getUpdateConfiguration()->isChannelLocal()) { + return $this->getProperty(self::DOWNLOAD_PATH) . DIRECTORY_SEPARATOR . $fileName; + } + + return $this->getProperty(self::TMP_RELEASES_DIR) . $fileName; + } + public function getAnalytics(): Analytics { if (null === $this->analytics) { @@ -395,16 +424,6 @@ public function getDb(): \Db return \Db::getInstance(); } - /** - * Return the path to the zipfile containing prestashop. - * - * @throws Exception - */ - public function getFilePath(): string - { - return $this->getProperty(self::ARCHIVE_FILEPATH); - } - public function getFileStorage(): FileStorage { if (null === $this->fileStorage) { @@ -461,6 +480,7 @@ public function getFilesystemAdapter(): FilesystemAdapter { if (null === $this->filesystemAdapter) { $this->filesystemAdapter = new FilesystemAdapter( + $this->getFileSystem(), $this->getFileFilter(), $this->getProperty(self::WORKSPACE_PATH), str_replace( @@ -545,7 +565,7 @@ public function getModuleSourceProviders(): array $this->moduleSourceProviders = [ new LocalSourceProvider($this->getProperty(self::WORKSPACE_PATH) . DIRECTORY_SEPARATOR . 'modules', $this->getFileStorage()), new MarketplaceSourceProvider($this->getUpdateState()->getDestinationVersion(), $this->getProperty(self::PS_ROOT_PATH), $this->getFileLoader(), $this->getFileStorage()), - new ComposerSourceProvider($this->getProperty(self::LATEST_PATH), $this->getComposerService(), $this->getFileStorage()), + new ComposerSourceProvider($this->getProperty(self::TMP_FILES_PATH), $this->getComposerService(), $this->getFileStorage()), // Other providers ]; } @@ -804,9 +824,11 @@ public function getWorkspace(): Workspace self::WORKSPACE_PATH, self::BACKUP_PATH, self::DOWNLOAD_PATH, - self::LATEST_PATH, + self::TMP_FILES_PATH, self::LOGS_PATH, self::TMP_PATH, + self::TMP_MODULES_DIR, + self::TMP_RELEASES_DIR, ]; foreach ($properties as $property) { diff --git a/classes/UpgradeTools/CoreUpgrader/CoreUpgrader.php b/classes/UpgradeTools/CoreUpgrader/CoreUpgrader.php index 61738fc48..41bb77fc3 100644 --- a/classes/UpgradeTools/CoreUpgrader/CoreUpgrader.php +++ b/classes/UpgradeTools/CoreUpgrader/CoreUpgrader.php @@ -98,7 +98,7 @@ public function __construct(UpgradeContainer $container, LoggerInterface $logger $this->fileSystem = $this->container->getFileSystem(); $this->logger = $logger; $this->destinationUpgradeVersion = $this->container->getUpdateState()->getDestinationVersion(); - $this->pathToInstallFolder = realpath($this->container->getProperty(UpgradeContainer::LATEST_PATH) . DIRECTORY_SEPARATOR . 'install'); + $this->pathToInstallFolder = realpath($this->container->getProperty(UpgradeContainer::TMP_FILES_PATH) . DIRECTORY_SEPARATOR . 'install'); $this->pathToUpgradeScripts = dirname(__DIR__, 3) . '/upgrade/'; if ($this->fileSystem->exists($this->pathToInstallFolder . DIRECTORY_SEPARATOR . 'autoload.php')) { require_once $this->pathToInstallFolder . DIRECTORY_SEPARATOR . 'autoload.php'; diff --git a/classes/UpgradeTools/FilesystemAdapter.php b/classes/UpgradeTools/FilesystemAdapter.php index f2512ee82..b5cd11f24 100644 --- a/classes/UpgradeTools/FilesystemAdapter.php +++ b/classes/UpgradeTools/FilesystemAdapter.php @@ -31,27 +31,23 @@ use RecursiveCallbackFilterIterator; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; +use Symfony\Component\Filesystem\Filesystem; class FilesystemAdapter { - /** - * @var FileFilter - */ + /** @var Filesystem */ + private $filesystem; + + /** @var FileFilter */ private $fileFilter; - /** - * @var string - */ + /** @var string */ private $autoupgradeDir; - /** - * @var string - */ + /** @var string */ private $adminSubDir; - /** - * @var string - */ + /** @var string */ private $prodRootDir; /** @@ -72,13 +68,14 @@ class FilesystemAdapter ]; public function __construct( + Filesystem $filesystem, FileFilter $fileFilter, string $autoupgradeDir, string $adminSubDir, string $prodRootDir ) { + $this->filesystem = $filesystem; $this->fileFilter = $fileFilter; - $this->autoupgradeDir = $autoupgradeDir; $this->adminSubDir = $adminSubDir; $this->prodRootDir = $prodRootDir; @@ -236,4 +233,20 @@ public function isReleaseValid(string $path): bool return true; } + + public function clearDirectory(string $folderToClear): bool + { + if ($this->filesystem->exists($folderToClear)) { + foreach (scandir($folderToClear) as $item) { + if ($item !== '.' && $item !== '..' && $item !== 'index.php') { + $path = $folderToClear . DIRECTORY_SEPARATOR . $item; + $this->filesystem->remove($path); + + return true; + } + } + } + + return false; + } } diff --git a/tests/unit/UpgradeContainer/FilesystemAdapterTest.php b/tests/unit/UpgradeContainer/FilesystemAdapterTest.php index 4134c57ed..ed1c0ad17 100644 --- a/tests/unit/UpgradeContainer/FilesystemAdapterTest.php +++ b/tests/unit/UpgradeContainer/FilesystemAdapterTest.php @@ -186,9 +186,9 @@ public function testFileFromReleaseIsIgnored($file, $fullpath, $process) $this->assertTrue( $this->filesystemAdapter->isFileSkipped( $file, - $this->container->getProperty(UpgradeContainer::LATEST_PATH) . $fullpath, + $this->container->getProperty(UpgradeContainer::TMP_FILES_PATH) . $fullpath, $process, - $this->container->getProperty(UpgradeContainer::LATEST_PATH) + $this->container->getProperty(UpgradeContainer::TMP_FILES_PATH) ) ); }