1<?php 2 3/* 4 * This file is part of the TYPO3 CMS project. 5 * 6 * It is free software; you can redistribute it and/or modify it under 7 * the terms of the GNU General Public License, either version 2 8 * of the License, or any later version. 9 * 10 * For the full copyright and license information, please read the 11 * LICENSE.txt file that was distributed with this source code. 12 * 13 * The TYPO3 project - inspiring people to share! 14 */ 15 16namespace TYPO3\CMS\Impexp\Controller; 17 18use Psr\Http\Message\ResponseInterface; 19use Psr\Http\Message\ServerRequestInterface; 20use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException; 21use TYPO3\CMS\Backend\Routing\UriBuilder; 22use TYPO3\CMS\Backend\Template\ModuleTemplate; 23use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; 24use TYPO3\CMS\Core\Http\RedirectResponse; 25use TYPO3\CMS\Core\Imaging\Icon; 26use TYPO3\CMS\Core\Imaging\IconFactory; 27use TYPO3\CMS\Core\Localization\LanguageService; 28use TYPO3\CMS\Core\Resource\Exception; 29use TYPO3\CMS\Core\Resource\Folder; 30use TYPO3\CMS\Core\Type\Bitmask\Permission; 31use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; 32use TYPO3\CMS\Core\Utility\GeneralUtility; 33use TYPO3\CMS\Fluid\View\StandaloneView; 34 35/** 36 * Main script class for the Import / Export facility. 37 * 38 * @todo: In TYPO3 v11 this class is about to become an abstract class 39 * @internal this is a TYPO3 Backend controller implementation and not part of TYPO3's Core API. 40 */ 41class ImportExportController 42{ 43 /** 44 * The integer value of the GET/POST var, 'id'. Used for submodules to the 'Web' module (page id) 45 * 46 * @var int 47 */ 48 protected $id; 49 50 /** 51 * Array containing the current page. 52 * 53 * @var array 54 */ 55 protected $pageinfo; 56 57 /** 58 * A WHERE clause for selection records from the pages table based on read-permissions of the current backend user. 59 * 60 * @var string 61 */ 62 protected $perms_clause; 63 64 /** 65 * @var LanguageService 66 */ 67 protected $lang; 68 69 /** 70 * @var IconFactory 71 */ 72 protected $iconFactory; 73 74 /** 75 * The name of the module 76 * 77 * @var string 78 */ 79 protected $moduleName = 'xMOD_tximpexp'; 80 81 /** 82 * ModuleTemplate Container 83 * 84 * @var ModuleTemplate 85 */ 86 protected $moduleTemplate; 87 88 /** 89 * The name of the shortcut for this page 90 * 91 * @var string 92 */ 93 protected $shortcutName; 94 95 /** 96 * @var StandaloneView 97 */ 98 protected $standaloneView; 99 100 /** 101 * Return URL 102 * 103 * @var string 104 */ 105 protected $returnUrl; 106 107 /** 108 * Constructor 109 */ 110 public function __construct() 111 { 112 $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class); 113 $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class); 114 115 $templatePath = ExtensionManagementUtility::extPath('impexp') . 'Resources/Private/'; 116 117 $this->standaloneView = GeneralUtility::makeInstance(StandaloneView::class); 118 $this->standaloneView->setTemplateRootPaths([$templatePath . 'Templates/ImportExport/']); 119 $this->standaloneView->setLayoutRootPaths([$templatePath . 'Layouts/']); 120 $this->standaloneView->setPartialRootPaths([$templatePath . 'Partials/']); 121 $this->standaloneView->getRequest()->setControllerExtensionName('impexp'); 122 123 $this->id = (int)GeneralUtility::_GP('id'); 124 $this->perms_clause = $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW); 125 $this->returnUrl = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl')); 126 $this->lang = $this->getLanguageService(); 127 } 128 129 /** 130 * Injects the request object for the current request and gathers all data 131 * 132 * IMPORTING DATA: 133 * 134 * Incoming array has syntax: 135 * GETvar 'id' = import page id (must be readable) 136 * 137 * file = pointing to filename relative to public web path 138 * 139 * [all relation fields are clear, but not files] 140 * - page-tree is written first 141 * - then remaining pages (to the root of import) 142 * - then all other records are written either to related included pages or if not found to import-root (should be a sysFolder in most cases) 143 * - then all internal relations are set and non-existing relations removed, relations to static tables preserved. 144 * 145 * EXPORTING DATA: 146 * 147 * Incoming array has syntax: 148 * 149 * file[] = file 150 * dir[] = dir 151 * list[] = table:pid 152 * record[] = table:uid 153 * 154 * pagetree[id] = (single id) 155 * pagetree[levels]=1,2,3, -1 = currently unpacked tree, -2 = only tables on page 156 * pagetree[tables][]=table/_ALL 157 * 158 * external_ref[tables][]=table/_ALL 159 * 160 * @param ServerRequestInterface $request 161 * @return ResponseInterface 162 * @throws RouteNotFoundException 163 */ 164 public function mainAction(ServerRequestInterface $request): ResponseInterface 165 { 166 // @todo: This method will become abstract in TYPO3 v11. 167 trigger_error('Route identifier xMOD_tximpexp is deprecated and will be removed in TYPO3 v11. Consider using tx_impexp_export or tx_impexp_import instead.', E_USER_DEPRECATED); 168 169 $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class); 170 $inData = GeneralUtility::_GP('tx_impexp'); 171 $routeName = 'tx_impexp_export'; 172 if ($inData === null || $inData['action'] === 'import') { 173 $routeName = 'tx_impexp_import'; 174 } 175 unset($inData['action']); 176 $target = (string)$uriBuilder->buildUriFromRoute($routeName, ['tx_impexp' => $inData]); 177 return new RedirectResponse($target, 308); 178 } 179 180 /** 181 * Create the panel of buttons for submitting the form or otherwise perform operations. 182 */ 183 protected function getButtons(): void 184 { 185 $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar(); 186 if ($this->getBackendUser()->mayMakeShortcut()) { 187 $shortcutButton = $buttonBar->makeShortcutButton() 188 ->setGetVariables(['tx_impexp']) 189 ->setDisplayName($this->shortcutName) 190 ->setModuleName($this->moduleName); 191 $buttonBar->addButton($shortcutButton); 192 } 193 // back button 194 if ($this->returnUrl) { 195 $backButton = $buttonBar->makeLinkButton() 196 ->setHref($this->returnUrl) 197 ->setTitle($this->lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack')) 198 ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-go-back', Icon::SIZE_SMALL)); 199 $buttonBar->addButton($backButton); 200 } 201 } 202 203 /** 204 * Returns a \TYPO3\CMS\Core\Resource\Folder object for saving export files 205 * to the server and is also used for uploading import files. 206 * 207 * @throws \InvalidArgumentException 208 * @return Folder|null 209 */ 210 protected function getDefaultImportExportFolder(): ?Folder 211 { 212 $defaultImportExportFolder = null; 213 214 $defaultTemporaryFolder = $this->getBackendUser()->getDefaultUploadTemporaryFolder(); 215 if ($defaultTemporaryFolder !== null) { 216 $importExportFolderName = 'importexport'; 217 $createFolder = !$defaultTemporaryFolder->hasFolder($importExportFolderName); 218 if ($createFolder === true) { 219 try { 220 $defaultImportExportFolder = $defaultTemporaryFolder->createFolder($importExportFolderName); 221 } catch (Exception $folderAccessException) { 222 } 223 } else { 224 $defaultImportExportFolder = $defaultTemporaryFolder->getSubfolder($importExportFolderName); 225 } 226 } 227 228 return $defaultImportExportFolder; 229 } 230 231 /** 232 * @return BackendUserAuthentication 233 */ 234 protected function getBackendUser(): BackendUserAuthentication 235 { 236 return $GLOBALS['BE_USER']; 237 } 238 239 /** 240 * @return LanguageService 241 */ 242 protected function getLanguageService(): LanguageService 243 { 244 return $GLOBALS['LANG']; 245 } 246} 247