‪TYPO3CMS  ‪main
ImportController.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ResponseInterface;
21 use Psr\Http\Message\ServerRequestInterface;
26 use TYPO3\CMS\Backend\Utility\BackendUtility;
29 use TYPO3\CMS\Core\Imaging\IconSize;
31 use TYPO3\CMS\Core\Package\PackageManager;
43 
49 #[Controller]
51 {
52  protected const ‪NO_UPLOAD = 0;
53  protected const ‪UPLOAD_DONE = 1;
54  protected const ‪UPLOAD_FAILED = 2;
55 
56  public function ‪__construct(
57  protected readonly ‪IconFactory $iconFactory,
58  protected readonly ‪ModuleTemplateFactory $moduleTemplateFactory,
59  protected readonly ‪ExtendedFileUtility $fileProcessor,
60  protected readonly ‪ResourceFactory $resourceFactory
61  ) {
62  }
63 
64  public function ‪handleRequest(ServerRequestInterface $request): ResponseInterface
65  {
66  if (!$this->‪getBackendUser()->isImportEnabled()) {
67  throw new \RuntimeException(
68  'Import module is disabled for non admin users and user TSconfig options.impexp.enableImportForNonAdminUser is not enabled.',
69  1464435459
70  );
71  }
72 
73  $backendUser = $this->‪getBackendUser();
74  $languageService = $this->‪getLanguageService();
75  $queryParams = $request->getQueryParams();
76  $parsedBody = $request->getParsedBody();
77 
78  $id = (int)($parsedBody['id'] ?? $queryParams['id'] ?? 0);
79  $permsClause = $backendUser->getPagePermsClause(‪Permission::PAGE_SHOW);
80  $pageInfo = BackendUtility::readPageAccess($id, $permsClause) ?: [];
81  if ($pageInfo === []) {
82  throw new \RuntimeException("You don't have access to this page.", 1604308205);
83  }
84 
85  $inputData = $request->getParsedBody()['tx_impexp'] ?? $request->getQueryParams()['tx_impexp'] ?? [];
86  if ($inputData['new_import'] ?? false) {
87  unset($inputData['import_mode']);
88  }
89 
90  $view = $this->moduleTemplateFactory->create($request);
91 
92  $uploadStatus = ‪self::NO_UPLOAD;
93  $uploadedFileName = '';
94  if ($request->getMethod() === 'POST' && empty($parsedBody)) {
95  // This happens if the post request was larger than allowed on the server.
96  $view->addFlashMessage(
97  $languageService->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:importdata_upload_nodata'),
98  $languageService->sL('LLL:EXT:impexp/Resources/Private/Language/locallang.xlf:importdata_upload_error'),
99  ContextualFeedbackSeverity::ERROR
100  );
101  }
102  if ($request->getMethod() === 'POST' && isset($parsedBody['_upload'])) {
103  $uploadStatus = ‪self::UPLOAD_FAILED;
104  $file = $this->‪handleFileUpload($request);
105  if (($file instanceof ‪File) && in_array($file->getExtension(), ['t3d', 'xml'], true)) {
106  $inputData['file'] = $file->getCombinedIdentifier();
107  $uploadStatus = ‪self::UPLOAD_DONE;
108  $uploadedFileName = $file->getName();
109  }
110  }
111 
112  $import = $this->‪configureImportFromFormDataAndImportIfRequested($view, $id, $inputData);
113  $importFolder = $import->getOrCreateDefaultImportExportFolder();
114 
115  $view->assignMultiple([
116  'importFolder' => ($importFolder instanceof ‪Folder) ? $importFolder->getCombinedIdentifier() : '',
117  'import' => $import,
118  'errors' => $import->getErrorLog(),
119  'preview' => $import->renderPreview(),
120  'id' => $id,
121  'fileSelectOptions' => $this->getSelectableFileList($import),
122  'inData' => $inputData,
123  'isAdmin' => $this->getBackendUser()->isAdmin(),
124  'uploadedFile' => $uploadedFileName,
125  'uploadStatus' => $uploadStatus,
126  ]);
127  $view->setModuleName('');
128  $view->getDocHeaderComponent()->setMetaInformation($pageInfo);
129  if ((int)($pageInfo['uid'] ?? 0) > 0) {
130  $this->‪addDocHeaderPreviewButton($view, (int)$pageInfo['uid']);
131  }
132  return $view->renderResponse('Import');
133  }
134 
135  protected function ‪addDocHeaderPreviewButton(‪ModuleTemplate $view, int $pageUid): void
136  {
137  $buttonBar = $view->‪getDocHeaderComponent()->getButtonBar();
138  $previewDataAttributes = ‪PreviewUriBuilder::create($pageUid)
139  ->withRootLine(BackendUtility::BEgetRootLine($pageUid))
140  ->buildDispatcherDataAttributes();
141  $viewButton = $buttonBar->makeLinkButton()
142  ->setHref('#')
143  ->setDataAttributes($previewDataAttributes ?? [])
144  ->setDisabled(!$previewDataAttributes)
145  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.showPage'))
146  ->setIcon($this->iconFactory->getIcon('actions-view-page', IconSize::SMALL))
147  ->setShowLabelText(true);
148  $buttonBar->addButton($viewButton);
149  }
150 
151  protected function ‪handleFileUpload(ServerRequestInterface $request): ?‪File
152  {
153  $parsedBody = $request->getParsedBody() ?? [];
154  $file = $parsedBody['file'] ?? [];
155  $conflictMode = empty($parsedBody['overwriteExistingFiles']) ? ‪DuplicationBehavior::CANCEL : ‪DuplicationBehavior::REPLACE;
156  $this->fileProcessor->setActionPermissions();
157  $this->fileProcessor->setExistingFilesConflictMode(‪DuplicationBehavior::cast($conflictMode));
158  $this->fileProcessor->start($file);
159  $result = $this->fileProcessor->processData();
160  if (isset($result['upload'][0][0])) {
161  // If upload went well, set the new file as the import file.
162  return $result['upload'][0][0];
163  }
164  return null;
165  }
166 
172  protected function ‪configureImportFromFormDataAndImportIfRequested(‪ModuleTemplate $view, int $id, array $inputData): ‪Import
173  {
174  $import = GeneralUtility::makeInstance(Import::class);
175  $import->setPid($id);
176  $import->setUpdate((bool)($inputData['do_update'] ?? false));
177  $import->setImportMode((array)($inputData['import_mode'] ?? null));
178  $import->setEnableLogging((bool)($inputData['enableLogging'] ?? false));
179  $import->setGlobalIgnorePid((bool)($inputData['global_ignore_pid'] ?? false));
180  $import->setForceAllUids((bool)($inputData['force_all_UIDS'] ?? false));
181  $import->setShowDiff(!(bool)($inputData['notShowDiff'] ?? false));
182  $import->setSoftrefInputValues((array)($inputData['softrefInputValues'] ?? null));
183  if (!empty($inputData['file'])) {
184  if (‪PathUtility::isExtensionPath($inputData['file'])) {
185  $filePath = $inputData['file'];
186  } else {
187  $filePath = $this->‪getFilePathWithinFileMountBoundaries((string)$inputData['file']);
188  }
189  try {
190  $import->loadFile($filePath, true);
191  $import->checkImportPrerequisites();
192  if ($inputData['import_file'] ?? false) {
193  $import->importData();
194  BackendUtility::setUpdateSignal('updatePageTree');
195  }
196  } catch (\‪Exception $e) {
197  $view->‪addFlashMessage($e->getMessage(), '', ContextualFeedbackSeverity::ERROR);
198  }
199  }
200  return $import;
201  }
202 
203  protected function ‪getFilePathWithinFileMountBoundaries(string $filePath): string
204  {
205  try {
206  $file = $this->resourceFactory->getFileObjectFromCombinedIdentifier($filePath);
207  return $file->getForLocalProcessing(false);
208  } catch (\‪Exception $exception) {
209  return '';
210  }
211  }
212 
213  protected function ‪getSelectableFileList(‪Import $import): array
214  {
215  $exportFiles = [];
216 
217  // Fileadmin
218  $folder = $import->‪getOrCreateDefaultImportExportFolder();
219  if ($folder !== null) {
220  $filter = GeneralUtility::makeInstance(FileExtensionFilter::class);
221  $filter->setAllowedFileExtensions(['t3d', 'xml']);
222  $folder->getStorage()->addFileAndFolderNameFilter([$filter, 'filterFileList']);
223  $exportFiles = $folder->getFiles();
224  }
225  $selectableFiles = [''];
226  foreach ($exportFiles as $file) {
227  $selectableFiles[$file->getCombinedIdentifier()] = $file->getPublicUrl();
228  }
229 
230  // Extension Distribution
231  if ($this->‪getBackendUser()->isAdmin()) {
232  $possibleImportFiles = [
233  'Initialisation/data.t3d',
234  'Initialisation/data.xml',
235  ];
236  $activePackages = GeneralUtility::makeInstance(PackageManager::class)->getActivePackages();
237  foreach ($activePackages as $package) {
238  foreach ($possibleImportFiles as $possibleImportFile) {
239  if (!file_exists($package->getPackagePath() . $possibleImportFile)) {
240  continue;
241  }
242  $selectableFiles['EXT:' . $package->getPackageKey() . '/' . $possibleImportFile] = 'EXT:' . $package->getPackageKey() . '/' . $possibleImportFile;
243  }
244  }
245  }
246 
247  return $selectableFiles;
248  }
249 
251  {
252  return ‪$GLOBALS['BE_USER'];
253  }
254 
256  {
257  return ‪$GLOBALS['LANG'];
258  }
259 }
‪TYPO3\CMS\Impexp\Controller\ImportController\configureImportFromFormDataAndImportIfRequested
‪configureImportFromFormDataAndImportIfRequested(ModuleTemplate $view, int $id, array $inputData)
Definition: ImportController.php:172
‪TYPO3\CMS\Impexp\Controller\ImportController\__construct
‪__construct(protected readonly IconFactory $iconFactory, protected readonly ModuleTemplateFactory $moduleTemplateFactory, protected readonly ExtendedFileUtility $fileProcessor, protected readonly ResourceFactory $resourceFactory)
Definition: ImportController.php:56
‪TYPO3\CMS\Core\Utility\PathUtility\isExtensionPath
‪static isExtensionPath(string $path)
Definition: PathUtility.php:117
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Core\Resource\DuplicationBehavior
Definition: DuplicationBehavior.php:24
‪TYPO3\CMS\Impexp\Controller\ImportController\UPLOAD_FAILED
‪const UPLOAD_FAILED
Definition: ImportController.php:54
‪TYPO3\CMS\Core\Resource\DuplicationBehavior\CANCEL
‪const CANCEL
Definition: DuplicationBehavior.php:46
‪TYPO3\CMS\Impexp\Controller
Definition: ExportController.php:18
‪TYPO3\CMS\Core\Exception
Definition: Exception.php:22
‪TYPO3\CMS\Backend\Template\ModuleTemplateFactory
Definition: ModuleTemplateFactory.php:33
‪TYPO3\CMS\Backend\Template\ModuleTemplate\addFlashMessage
‪addFlashMessage(string $messageBody, string $messageTitle='', ContextualFeedbackSeverity $severity=ContextualFeedbackSeverity::OK, bool $storeInSession=true)
Definition: ModuleTemplate.php:229
‪TYPO3\CMS\Backend\Attribute\Controller
Definition: Controller.php:25
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:34
‪TYPO3\CMS\Impexp\Controller\ImportController
Definition: ImportController.php:51
‪TYPO3\CMS\Backend\Template\ModuleTemplate
Definition: ModuleTemplate.php:46
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:26
‪TYPO3\CMS\Impexp\Controller\ImportController\getSelectableFileList
‪getSelectableFileList(Import $import)
Definition: ImportController.php:213
‪TYPO3\CMS\Core\Type\ContextualFeedbackSeverity
‪ContextualFeedbackSeverity
Definition: ContextualFeedbackSeverity.php:25
‪TYPO3\CMS\Core\Type\Enumeration\cast
‪static static cast($value)
Definition: Enumeration.php:186
‪TYPO3\CMS\Core\Utility\File\ExtendedFileUtility
Definition: ExtendedFileUtility.php:77
‪TYPO3\CMS\Impexp\Controller\ImportController\handleFileUpload
‪handleFileUpload(ServerRequestInterface $request)
Definition: ImportController.php:151
‪TYPO3\CMS\Impexp\Import
Definition: Import.php:50
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:37
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:41
‪TYPO3\CMS\Backend\Routing\PreviewUriBuilder\create
‪static static create(int $pageId)
Definition: PreviewUriBuilder.php:65
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:26
‪TYPO3\CMS\Impexp\ImportExport\getOrCreateDefaultImportExportFolder
‪getOrCreateDefaultImportExportFolder()
Definition: ImportExport.php:1154
‪TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter
Definition: FileExtensionFilter.php:31
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:64
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:35
‪TYPO3\CMS\Impexp\Controller\ImportController\addDocHeaderPreviewButton
‪addDocHeaderPreviewButton(ModuleTemplate $view, int $pageUid)
Definition: ImportController.php:135
‪TYPO3\CMS\Backend\Template\ModuleTemplate\getDocHeaderComponent
‪getDocHeaderComponent()
Definition: ModuleTemplate.php:181
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Routing\PreviewUriBuilder
Definition: PreviewUriBuilder.php:44
‪TYPO3\CMS\Impexp\Controller\ImportController\UPLOAD_DONE
‪const UPLOAD_DONE
Definition: ImportController.php:53
‪TYPO3\CMS\Core\Resource\DuplicationBehavior\REPLACE
‪const REPLACE
Definition: DuplicationBehavior.php:39
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Impexp\Controller\ImportController\NO_UPLOAD
‪const NO_UPLOAD
Definition: ImportController.php:52
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Impexp\Controller\ImportController\handleRequest
‪handleRequest(ServerRequestInterface $request)
Definition: ImportController.php:64
‪TYPO3\CMS\Impexp\Controller\ImportController\getBackendUser
‪getBackendUser()
Definition: ImportController.php:250
‪TYPO3\CMS\Impexp\Controller\ImportController\getFilePathWithinFileMountBoundaries
‪getFilePathWithinFileMountBoundaries(string $filePath)
Definition: ImportController.php:203
‪TYPO3\CMS\Impexp\Controller\ImportController\getLanguageService
‪getLanguageService()
Definition: ImportController.php:255