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