![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/framework/Setup/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Framework\Setup; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Backup\Exception\NotEnoughPermissions; use Magento\Framework\Backup\Factory; use Magento\Framework\Backup\Filesystem\Helper; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Filesystem\Driver\File; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Phrase; /** * Class to deal with backup and rollback functionality for database and Code base * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class BackupRollback { /** * Default backup directory */ public const DEFAULT_BACKUP_DIRECTORY = 'backups'; /** * Path to backup folder * * @var string */ private $backupsDir; /** * @var ObjectManagerInterface */ private $objectManager; /** * Logger * * @var LoggerInterface */ private $log; /** * Filesystem Directory List * * @var DirectoryList */ private $directoryList; /** * @var File */ private $file; /** * Filesystem Helper * * @var Helper */ private $fsHelper; /** * Constructor * * @param ObjectManagerInterface $objectManager * @param LoggerInterface $log * @param DirectoryList $directoryList * @param File $file * @param Helper $fsHelper */ public function __construct( ObjectManagerInterface $objectManager, LoggerInterface $log, DirectoryList $directoryList, File $file, Helper $fsHelper ) { $this->objectManager = $objectManager; $this->log = $log; $this->directoryList = $directoryList; $this->file = $file; $this->fsHelper = $fsHelper; $this->backupsDir = $this->directoryList->getPath(DirectoryList::VAR_DIR) . '/' . self::DEFAULT_BACKUP_DIRECTORY; } /** * Take backup for code base * * @param int $time * @param string $type * @return string * @throws LocalizedException */ public function codeBackup($time, $type = Factory::TYPE_FILESYSTEM) { /** @var \Magento\Framework\Backup\Filesystem $fsBackup */ $fsBackup = $this->objectManager->create(\Magento\Framework\Backup\Filesystem::class); $fsBackup->setRootDir($this->directoryList->getRoot()); if ($type === Factory::TYPE_FILESYSTEM) { $fsBackup->addIgnorePaths($this->getCodeBackupIgnorePaths()); $granularType = 'Code'; $fsBackup->setName('code'); } elseif ($type === Factory::TYPE_MEDIA) { $fsBackup->addIgnorePaths($this->getMediaBackupIgnorePaths()); $granularType = 'Media'; $fsBackup->setName('media'); } else { throw new LocalizedException(new Phrase("This backup type \'$type\' is not supported.")); } if (!$this->file->isExists($this->backupsDir)) { $this->file->createDirectory($this->backupsDir); } $fsBackup->setBackupsDir($this->backupsDir); $fsBackup->setBackupExtension('tgz'); $fsBackup->setTime($time); $this->log->log($granularType . ' backup is starting...'); $fsBackup->create(); $this->log->log( $granularType . ' backup filename: ' . $fsBackup->getBackupFilename() . ' (The archive can be uncompressed with 7-Zip on Windows systems)' ); $this->log->log($granularType . ' backup path: ' . $fsBackup->getBackupPath()); $this->log->logSuccess($granularType . ' backup completed successfully.'); return $fsBackup->getBackupPath(); } /** * Roll back code base * * @param string $rollbackFile * @param string $type * @param boolean $keepSourceFile * @return void * @throws LocalizedException */ public function codeRollback($rollbackFile, $type = Factory::TYPE_FILESYSTEM, $keepSourceFile = false) { if (!$rollbackFile || preg_match('/[0-9]_(filesystem)_(code|media)\.(tgz)$/', $rollbackFile) !== 1) { throw new LocalizedException(new Phrase('The rollback file is invalid. Verify the file and try again.')); } if (!$this->file->isExists($this->backupsDir . '/' . $rollbackFile)) { throw new LocalizedException(new Phrase("The rollback file doesn't exist. Verify the file and try again.")); } /** @var \Magento\Framework\Backup\Filesystem $fsRollback */ $fsRollback = $this->objectManager->create(\Magento\Framework\Backup\Filesystem::class); if ($type === Factory::TYPE_FILESYSTEM) { $ignorePaths = $this->getCodeBackupIgnorePaths(); $granularType = 'Code'; $fsRollback->setName('code'); } elseif ($type === Factory::TYPE_MEDIA) { $ignorePaths = $this->getMediaBackupIgnorePaths(); $granularType = 'Media'; $fsRollback->setName('media'); } else { throw new LocalizedException(new Phrase("This backup type '$type' is not supported.")); } $filesInfo = $this->fsHelper->getInfo( $this->directoryList->getRoot(), Helper::INFO_WRITABLE, $ignorePaths ); if (!$filesInfo['writable']) { throw new NotEnoughPermissions( new Phrase("The rollback can't be executed because not all files are writable.") ); } $fsRollback->setRootDir($this->directoryList->getRoot()); $fsRollback->addIgnorePaths($ignorePaths); $fsRollback->setBackupsDir($this->backupsDir); $fsRollback->setBackupExtension('tgz'); $time = explode('_', $rollbackFile); $fsRollback->setKeepSourceFile($keepSourceFile); $fsRollback->setTime($time[0]); $this->log->log($granularType . ' rollback is starting ...'); $fsRollback->rollback(); $this->log->log($granularType . ' rollback filename: ' . $fsRollback->getBackupFilename()); $this->log->log($granularType . ' rollback file path: ' . $fsRollback->getBackupPath()); $this->log->logSuccess($granularType . ' rollback completed successfully.'); } /** * Take backup for database * * @param int $time * @return string */ public function dbBackup($time) { /** @var \Magento\Framework\Backup\Db $dbBackup */ $dbBackup = $this->objectManager->create(\Magento\Framework\Backup\Db::class); $dbBackup->setRootDir($this->directoryList->getRoot()); if (!$this->file->isExists($this->backupsDir)) { $this->file->createDirectory($this->backupsDir); } $dbBackup->setBackupsDir($this->backupsDir); $dbBackup->setBackupExtension('sql'); $dbBackup->setTime($time); $this->log->log('DB backup is starting...'); $dbBackup->create(); $this->log->log('DB backup filename: ' . $dbBackup->getBackupFilename()); $this->log->log('DB backup path: ' . $dbBackup->getBackupPath()); $this->log->logSuccess('DB backup completed successfully.'); return $dbBackup->getBackupPath(); } /** * Roll back database * * @param string $rollbackFile * @param boolean $keepSourceFile * @return void * @throws LocalizedException */ public function dbRollback($rollbackFile, $keepSourceFile = false) { if (!$rollbackFile || preg_match('/[0-9]_(db)(.*?).(sql)$/', $rollbackFile) !== 1) { throw new LocalizedException(new Phrase('The rollback file is invalid. Verify the file and try again.')); } if (!$this->file->isExists($this->backupsDir . '/' . $rollbackFile)) { throw new LocalizedException(new Phrase("The rollback file doesn't exist. Verify the file and try again.")); } /** @var \Magento\Framework\Backup\Db $dbRollback */ $dbRollback = $this->objectManager->create(\Magento\Framework\Backup\Db::class); $dbRollback->setRootDir($this->directoryList->getRoot()); $dbRollback->setBackupsDir($this->backupsDir); $dbRollback->setBackupExtension('sql'); $time = explode('_', $rollbackFile); if (count($time) === 3) { $thirdPart = explode('.', $time[2] ?? ''); $dbRollback->setName($thirdPart[0]); } $dbRollback->setTime($time[0]); $this->log->log('DB rollback is starting...'); $dbRollback->setKeepSourceFile($keepSourceFile); $dbRollback->setResourceModel($this->objectManager->create(\Magento\Backup\Model\ResourceModel\Db::class)); if ($dbRollback->getBackupFilename() !== $rollbackFile) { $correctName = $this->getCorrectFileNameWithoutPrefix($dbRollback, $rollbackFile); $dbRollback->setName($correctName); } $dbRollback->rollback(); $this->log->log('DB rollback filename: ' . $dbRollback->getBackupFilename()); $this->log->log('DB rollback path: ' . $dbRollback->getBackupPath()); $this->log->logSuccess('DB rollback completed successfully.'); } /** * Get paths that should be excluded during iterative searches for locations for code backup only * * @return array */ private function getCodeBackupIgnorePaths() { return [ $this->directoryList->getPath(DirectoryList::MEDIA), $this->directoryList->getPath(DirectoryList::STATIC_VIEW), $this->directoryList->getPath(DirectoryList::VAR_DIR), $this->directoryList->getRoot() . '/update', $this->directoryList->getRoot() . '/node_modules', $this->directoryList->getRoot() . '/.grunt', $this->directoryList->getRoot() . '/.idea', $this->directoryList->getRoot() . '/.svn', $this->directoryList->getRoot() . '/.git' ]; } /** * Get paths that should be excluded during iterative searches for locations for media backup only * * @return array */ private function getMediaBackupIgnorePaths() { $ignorePaths = []; foreach (new \DirectoryIterator($this->directoryList->getRoot()) as $item) { if (!$item->isDot() && ($this->directoryList->getPath(DirectoryList::PUB) !== $item->getPathname())) { $ignorePaths[] = $item->getPathname() !== null ? str_replace('\\', '/', $item->getPathname()) : ''; } } foreach (new \DirectoryIterator($this->directoryList->getPath(DirectoryList::PUB)) as $item) { if (!$item->isDot() && ($this->directoryList->getPath(DirectoryList::MEDIA) !== $item->getPathname())) { $ignorePaths[] = $item->getPathname() !== null ? str_replace('\\', '/', $item->getPathname()) : ''; } } return $ignorePaths; } /** * Get disk availability for filesystem backup * * @param string $type * @return int * @throws LocalizedException */ public function getFSDiskSpace($type = Factory::TYPE_FILESYSTEM) { $filesystemSize = 0; if ($type === Factory::TYPE_FILESYSTEM) { $ignorePaths = $this->getCodeBackupIgnorePaths(); } elseif ($type === Factory::TYPE_MEDIA) { $ignorePaths = $this->getMediaBackupIgnorePaths(); } else { throw new LocalizedException(new Phrase("This backup type '$type' is not supported.")); } $filesInfo = $this->fsHelper->getInfo( $this->directoryList->getRoot(), Helper::INFO_SIZE, $ignorePaths ); if ($filesInfo['size']) { $filesystemSize = $filesInfo['size']; } return $filesystemSize; } /** * Get disk availability for database backup * * @return int * @throws LocalizedException */ public function getDBDiskSpace() { /** @var \Magento\Framework\Backup\Db $dbBackup */ $dbBackup = $this->objectManager->create(\Magento\Framework\Backup\Db::class); return $dbBackup->getDBSize(); } /** * Get correct file name without prefix. * * @param \Magento\Framework\Backup\Db $dbRollback * @param string $rollbackFile * * @return string */ private function getCorrectFileNameWithoutPrefix(\Magento\Framework\Backup\Db $dbRollback, $rollbackFile) { $namePrefix = $dbRollback->getTime() . '_' . $dbRollback->getType(); //delete prefix. $fileNameWithoutPrefix = $rollbackFile !== null ? str_replace($namePrefix, '', $rollbackFile) : ''; //change '_' to ' '. $fileNameWithoutPrefix = str_replace('_', ' ', $fileNameWithoutPrefix); //delete file extension. $fileNameWithoutPrefix = pathinfo($fileNameWithoutPrefix, PATHINFO_FILENAME); return $fileNameWithoutPrefix; } }