_directory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $this->_fileFactory = $fileFactory; $this->_link = $link; $this->_updateFactory = $updateFactory; $this->_eventManager = $eventManager; $this->_customizationPath = $customization; } /** * Copy customizations from one theme to another * * @param ThemeInterface $source * @param ThemeInterface $target * @return void */ public function copy(ThemeInterface $source, ThemeInterface $target) { $this->_copyDatabaseCustomization($source, $target); $this->_copyLayoutCustomization($source, $target); $this->_copyFilesystemCustomization($source, $target); } /** * Copy customizations stored in a database from one theme to another, overriding existing data * * @param ThemeInterface $source * @param ThemeInterface $target * @return void */ protected function _copyDatabaseCustomization(ThemeInterface $source, ThemeInterface $target) { /** @var $themeFile \Magento\Theme\Model\Theme\File */ foreach ($target->getCustomization()->getFiles() as $themeFile) { $themeFile->delete(); } /** @var $newFile \Magento\Theme\Model\Theme\File */ foreach ($source->getCustomization()->getFiles() as $themeFile) { /** @var $newThemeFile \Magento\Theme\Model\Theme\File */ $newThemeFile = $this->_fileFactory->create(); $newThemeFile->setData( [ 'theme_id' => $target->getId(), 'file_path' => $themeFile->getFilePath(), 'file_type' => $themeFile->getFileType(), 'content' => $themeFile->getContent(), 'sort_order' => $themeFile->getData('sort_order'), ] ); $newThemeFile->save(); } } /** * Add layout links to general layout updates for themes * * @param ThemeInterface $source * @param ThemeInterface $target * @return void */ protected function _copyLayoutCustomization(ThemeInterface $source, ThemeInterface $target) { $update = $this->_updateFactory->create(); /** @var $targetUpdates \Magento\Widget\Model\ResourceModel\Layout\Update\Collection */ $targetUpdates = $update->getCollection(); $targetUpdates->addThemeFilter($target->getId()); $targetUpdates->delete(); /** @var $sourceCollection \Magento\Widget\Model\ResourceModel\Layout\Link\Collection */ $sourceCollection = $this->_link->getCollection(); $sourceCollection->addThemeFilter($source->getId()); /** @var $layoutLink \Magento\Widget\Model\Layout\Link */ foreach ($sourceCollection as $layoutLink) { /** @var $update \Magento\Widget\Model\Layout\Update */ $update = $this->_updateFactory->create(); $update->load($layoutLink->getLayoutUpdateId()); if ($update->getId()) { $update->setId(null); $update->save(); $layoutLink->setThemeId($target->getId()); $layoutLink->setLayoutUpdateId($update->getId()); $layoutLink->setId(null); $layoutLink->save(); } } } /** * Copy customizations stored in a file system from one theme to another, overriding existing data * * @param ThemeInterface $source * @param ThemeInterface $target * @return void */ protected function _copyFilesystemCustomization(ThemeInterface $source, ThemeInterface $target) { $sourcePath = $this->_customizationPath->getCustomizationPath($source); $targetPath = $this->_customizationPath->getCustomizationPath($target); if (!$sourcePath || !$targetPath) { return; } $this->_deleteFilesRecursively($targetPath); if ($this->_directory->isDirectory($sourcePath)) { $this->_copyFilesRecursively($sourcePath, $sourcePath, $targetPath); } } /** * Copies all files in a directory recursively * * @param string $baseDir * @param string $sourceDir * @param string $targetDir * @return void */ protected function _copyFilesRecursively($baseDir, $sourceDir, $targetDir) { foreach ($this->_directory->read($sourceDir) as $path) { if ($this->_directory->isDirectory($path)) { $this->_copyFilesRecursively($baseDir, $path, $targetDir); } else { $filePath = substr($path, strlen($baseDir) + 1); $this->_directory->copyFile($path, $targetDir . '/' . $filePath); } } } /** * Delete all files in a directory recursively * * @param string $targetDir * @return void */ protected function _deleteFilesRecursively($targetDir) { if ($this->_directory->isExist($targetDir)) { foreach ($this->_directory->read($targetDir) as $path) { $this->_directory->delete($path); } } } }