[TASK] Use ModuleTemplate API for ext:impexp
[Packages/TYPO3.CMS.git] / typo3 / sysext / impexp / Classes / Controller / ImportExportController.php
1 <?php
2 namespace TYPO3\CMS\Impexp\Controller;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Psr\Http\Message\ResponseInterface;
18 use Psr\Http\Message\ServerRequestInterface;
19 use TYPO3\CMS\Backend\Module\BaseScriptClass;
20 use TYPO3\CMS\Backend\Template\Components\ButtonBar;
21 use TYPO3\CMS\Backend\Template\DocumentTemplate;
22 use TYPO3\CMS\Backend\Template\ModuleTemplate;
23 use TYPO3\CMS\Core\Database\DatabaseConnection;
24 use TYPO3\CMS\Core\Imaging\Icon;
25 use TYPO3\CMS\Core\Imaging\IconFactory;
26 use TYPO3\CMS\Core\Messaging\FlashMessage;
27 use TYPO3\CMS\Core\Resource\DuplicationBehavior;
28 use TYPO3\CMS\Core\Resource\ResourceFactory;
29 use TYPO3\CMS\Core\Utility\GeneralUtility;
30 use TYPO3\CMS\Backend\Utility\BackendUtility;
31 use TYPO3\CMS\Core\Utility\MathUtility;
32 use TYPO3\CMS\Core\Utility\PathUtility;
33 use TYPO3\CMS\Lang\LanguageService;
34
35 /**
36 * Main script class for the Import / Export facility
37 */
38 class ImportExportController extends BaseScriptClass
39 {
40 /**
41 * @var array|\TYPO3\CMS\Core\Resource\File[]
42 */
43 protected $uploadedFiles = array();
44
45 /**
46 * Array containing the current page.
47 *
48 * @var array
49 */
50 public $pageinfo;
51
52 /**
53 * @var \TYPO3\CMS\Impexp\ImportExport
54 */
55 protected $export;
56
57 /**
58 * @var \TYPO3\CMS\Impexp\ImportExport
59 */
60 protected $import;
61
62 /**
63 * @var \TYPO3\CMS\Core\Utility\File\ExtendedFileUtility
64 */
65 protected $fileProcessor;
66
67 /**
68 * @var string
69 */
70 protected $vC = '';
71
72 /**
73 * @var LanguageService
74 */
75 protected $lang = null;
76
77 /**
78 * @var string
79 */
80 protected $treeHTML = '';
81
82 /**
83 * @var IconFactory
84 */
85 protected $iconFactory;
86
87 /**
88 * The name of the module
89 *
90 * @var string
91 */
92 protected $moduleName = 'xMOD_tximpexp';
93
94 /**
95 * ModuleTemplate Container
96 *
97 * @var ModuleTemplate
98 */
99 protected $moduleTemplate;
100
101 /**
102 * Constructor
103 */
104 public function __construct()
105 {
106 $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
107 $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
108 }
109
110 /**
111 * @return void
112 */
113 public function init()
114 {
115 $this->MCONF['name'] = $this->moduleName;
116 parent::init();
117 $this->vC = GeneralUtility::_GP('vC');
118 $this->lang = $this->getLanguageService();
119 }
120
121 /**
122 * Main module function
123 *
124 * @throws \BadFunctionCallException
125 * @throws \InvalidArgumentException
126 * @return void
127 */
128 public function main()
129 {
130 $this->lang->includeLLFile('EXT:impexp/Resources/Private/Language/locallang.xlf');
131 // Start document template object:
132 // We keep this here, in case somebody relies on the old doc being here
133 $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
134 $this->doc->bodyTagId = 'imp-exp-mod';
135 $this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause);
136 $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($this->pageinfo);
137 // Setting up the context sensitive menu:
138 $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ClickMenu');
139 $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Impexp/ImportExport');
140 $this->moduleTemplate->addJavaScriptCode(
141 'ImpexpInLineJS',
142 'if (top.fsMod) top.fsMod.recentIds["web"] = ' . (int)$this->id . ';'
143 );
144 $this->moduleTemplate->setForm('<form action="' . htmlspecialchars(BackendUtility::getModuleUrl('xMOD_tximpexp')) . '" method="post" enctype="multipart/form-data">'
145 . '<input type="hidden" name="id" value="' . $this->id . '" />');
146 $this->content .= $this->moduleTemplate->sectionHeader($this->lang->getLL('title'));
147 $this->content .= $this->moduleTemplate->spacer(5);
148 // Input data grabbed:
149 $inData = GeneralUtility::_GP('tx_impexp');
150 $this->checkUpload();
151 switch ((string)$inData['action']) {
152 case 'export':
153 // Finally: If upload went well, set the new file as the thumbnail in the $inData array:
154 if (!empty($this->uploadedFiles[0])) {
155 $inData['meta']['thumbnail'] = $this->uploadedFiles[0]->getCombinedIdentifier();
156 }
157 // Call export interface
158 $this->exportData($inData);
159 break;
160 case 'import':
161 // Finally: If upload went well, set the new file as the import file:
162 if (!empty($this->uploadedFiles[0])) {
163 // Only allowed extensions....
164 if (GeneralUtility::inList('t3d,xml', $this->uploadedFiles[0]->getExtension())) {
165 $inData['file'] = $this->uploadedFiles[0]->getCombinedIdentifier();
166 }
167 }
168 // Call import interface:
169 $this->importData($inData);
170 break;
171 }
172 // Setting up the buttons and markers for docheader
173 $this->getButtons();
174 }
175
176 /**
177 * Print the content
178 *
179 * @return void
180 * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
181 */
182 public function printContent()
183 {
184 GeneralUtility::logDeprecatedFunction();
185 echo $this->content;
186 }
187
188 /**
189 * Injects the request object for the current request and gathers all data
190 *
191 * IMPORTING DATA:
192 *
193 * Incoming array has syntax:
194 * GETvar 'id' = import page id (must be readable)
195 *
196 * file = (pointing to filename relative to PATH_site)
197 *
198 * [all relation fields are clear, but not files]
199 * - page-tree is written first
200 * - then remaining pages (to the root of import)
201 * - 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)
202 * - then all internal relations are set and non-existing relations removed, relations to static tables preserved.
203 *
204 * EXPORTING DATA:
205 *
206 * Incoming array has syntax:
207 *
208 * file[] = file
209 * dir[] = dir
210 * list[] = table:pid
211 * record[] = table:uid
212 *
213 * pagetree[id] = (single id)
214 * pagetree[levels]=1,2,3, -1 = currently unpacked tree, -2 = only tables on page
215 * pagetree[tables][]=table/_ALL
216 *
217 * external_ref[tables][]=table/_ALL
218 *
219 * @param ServerRequestInterface $request the current request
220 * @param ResponseInterface $response
221 * @return ResponseInterface the response with the content
222 */
223 public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
224 {
225 $GLOBALS['SOBE'] = $this;
226 $this->init();
227 $this->main();
228 $this->moduleTemplate->setContent($this->content);
229 $response->getBody()->write($this->moduleTemplate->renderContent());
230 return $response;
231 }
232
233 /**
234 * Create the panel of buttons for submitting the form or otherwise perform operations.
235 *
236 * @return array all available buttons as an associated array
237 */
238 protected function getButtons()
239 {
240 $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
241 if ($this->getBackendUser()->mayMakeShortcut()) {
242 $shortcutButton = $buttonBar->makeShortcutButton()
243 ->setGetVariables(['tx_impexp'])
244 ->setModuleName($this->moduleName);
245 $buttonBar->addButton($shortcutButton);
246 }
247 // Input data grabbed:
248 $inData = GeneralUtility::_GP('tx_impexp');
249 if ((string)$inData['action'] == 'import') {
250 if ($this->id && is_array($this->pageinfo) || $this->getBackendUser()->user['admin'] && !$this->id) {
251 if (is_array($this->pageinfo) && $this->pageinfo['uid']) {
252 // View
253 $onClick = BackendUtility::viewOnClick(
254 $this->pageinfo['uid'],
255 '',
256 BackendUtility::BEgetRootLine($this->pageinfo['uid'])
257 );
258 $viewButton = $buttonBar->makeLinkButton()
259 ->setTitle($this->lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.showPage', true))
260 ->setHref('#')
261 ->setIcon($this->iconFactory->getIcon('actions-document-view', Icon::SIZE_SMALL))
262 ->setOnClick($onClick);
263 $buttonBar->addButton($viewButton);
264 }
265 }
266 }
267 }
268
269 /**************************
270 * EXPORT FUNCTIONS
271 **************************/
272
273 /**
274 * Export part of module
275 * Setting content in $this->content
276 *
277 * @param array $inData Content of POST VAR tx_impexp[]..
278 * @throws \InvalidArgumentException
279 * @throws \RuntimeException
280 * @throws \TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException
281 * @return void
282 */
283 public function exportData($inData)
284 {
285 // BUILDING EXPORT DATA:
286 // Processing of InData array values:
287 $inData['pagetree']['maxNumber'] = MathUtility::forceIntegerInRange($inData['pagetree']['maxNumber'], 1, 1000000, 100);
288 $inData['listCfg']['maxNumber'] = MathUtility::forceIntegerInRange($inData['listCfg']['maxNumber'], 1, 1000000, 100);
289 $inData['maxFileSize'] = MathUtility::forceIntegerInRange($inData['maxFileSize'], 1, 1000000, 1000);
290 $inData['filename'] = trim(preg_replace('/[^[:alnum:]._-]*/', '', preg_replace('/\\.(t3d|xml)$/', '', $inData['filename'])));
291 if (strlen($inData['filename'])) {
292 $inData['filename'] .= $inData['filetype'] == 'xml' ? '.xml' : '.t3d';
293 }
294 // Set exclude fields in export object:
295 if (!is_array($inData['exclude'])) {
296 $inData['exclude'] = array();
297 }
298 // Saving/Loading/Deleting presets:
299 $this->processPresets($inData);
300 // Create export object and configure it:
301 $this->export = GeneralUtility::makeInstance(\TYPO3\CMS\Impexp\ImportExport::class);
302 $this->export->init(0, 'export');
303 $this->export->setCharset($this->lang->charSet);
304 $this->export->maxFileSize = $inData['maxFileSize'] * 1024;
305 $this->export->excludeMap = (array)$inData['exclude'];
306 $this->export->softrefCfg = (array)$inData['softrefCfg'];
307 $this->export->extensionDependencies = (array)$inData['extension_dep'];
308 $this->export->showStaticRelations = $inData['showStaticRelations'];
309 $this->export->includeExtFileResources = !$inData['excludeHTMLfileResources'];
310 // Static tables:
311 if (is_array($inData['external_static']['tables'])) {
312 $this->export->relStaticTables = $inData['external_static']['tables'];
313 }
314 // Configure which tables external relations are included for:
315 if (is_array($inData['external_ref']['tables'])) {
316 $this->export->relOnlyTables = $inData['external_ref']['tables'];
317 }
318 $saveFilesOutsideExportFile = false;
319 if (isset($inData['save_export']) && isset($inData['saveFilesOutsideExportFile']) && $inData['saveFilesOutsideExportFile'] === '1') {
320 $this->export->setSaveFilesOutsideExportFile(true);
321 $saveFilesOutsideExportFile = true;
322 }
323 $this->export->setHeaderBasics();
324 // Meta data setting:
325
326 $beUser = $this->getBackendUser();
327 $this->export->setMetaData(
328 $inData['meta']['title'],
329 $inData['meta']['description'],
330 $inData['meta']['notes'],
331 $beUser->user['username'],
332 $beUser->user['realName'],
333 $beUser->user['email']
334 );
335 if ($inData['meta']['thumbnail']) {
336 $theThumb = $this->getFile($inData['meta']['thumbnail']);
337 if ($theThumb !== null && $theThumb->exists()) {
338 $this->export->addThumbnail($theThumb->getForLocalProcessing(false));
339 }
340 }
341 // Configure which records to export
342 if (is_array($inData['record'])) {
343 foreach ($inData['record'] as $ref) {
344 $rParts = explode(':', $ref);
345 $this->export->export_addRecord($rParts[0], BackendUtility::getRecord($rParts[0], $rParts[1]));
346 }
347 }
348 // Configure which tables to export
349 if (is_array($inData['list'])) {
350 $db = $this->getDatabaseConnection();
351 foreach ($inData['list'] as $ref) {
352 $rParts = explode(':', $ref);
353 if ($beUser->check('tables_select', $rParts[0])) {
354 $res = $this->exec_listQueryPid($rParts[0], $rParts[1], MathUtility::forceIntegerInRange($inData['listCfg']['maxNumber'], 1));
355 while ($subTrow = $db->sql_fetch_assoc($res)) {
356 $this->export->export_addRecord($rParts[0], $subTrow);
357 }
358 $db->sql_free_result($res);
359 }
360 }
361 }
362 // Pagetree
363 if (isset($inData['pagetree']['id'])) {
364 // Based on click-expandable tree
365 $idH = null;
366 if ($inData['pagetree']['levels'] == -1) {
367 $pagetree = GeneralUtility::makeInstance(\TYPO3\CMS\Impexp\View\ExportPageTreeView::class);
368 $tree = $pagetree->ext_tree($inData['pagetree']['id'], $this->filterPageIds($this->export->excludeMap));
369 $this->treeHTML = $pagetree->printTree($tree);
370 $idH = $pagetree->buffer_idH;
371 } elseif ($inData['pagetree']['levels'] == -2) {
372 $this->addRecordsForPid($inData['pagetree']['id'], $inData['pagetree']['tables'], $inData['pagetree']['maxNumber']);
373 } else {
374 // Based on depth
375 // Drawing tree:
376 // If the ID is zero, export root
377 if (!$inData['pagetree']['id'] && $beUser->isAdmin()) {
378 $sPage = array(
379 'uid' => 0,
380 'title' => 'ROOT'
381 );
382 } else {
383 $sPage = BackendUtility::getRecordWSOL('pages', $inData['pagetree']['id'], '*', ' AND ' . $this->perms_clause);
384 }
385 if (is_array($sPage)) {
386 $pid = $inData['pagetree']['id'];
387 $tree = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\View\PageTreeView::class);
388 $tree->init('AND ' . $this->perms_clause . $this->filterPageIds($this->export->excludeMap));
389 $HTML = $this->iconFactory->getIconForRecord('pages', $sPage, Icon::SIZE_SMALL)->render();
390 $tree->tree[] = array('row' => $sPage, 'HTML' => $HTML);
391 $tree->buffer_idH = array();
392 if ($inData['pagetree']['levels'] > 0) {
393 $tree->getTree($pid, $inData['pagetree']['levels'], '');
394 }
395 $idH = array();
396 $idH[$pid]['uid'] = $pid;
397 if (!empty($tree->buffer_idH)) {
398 $idH[$pid]['subrow'] = $tree->buffer_idH;
399 }
400 $pagetree = GeneralUtility::makeInstance(\TYPO3\CMS\Impexp\View\ExportPageTreeView::class);
401 $this->treeHTML = $pagetree->printTree($tree->tree);
402 }
403 }
404 // In any case we should have a multi-level array, $idH, with the page structure
405 // here (and the HTML-code loaded into memory for nice display...)
406 if (is_array($idH)) {
407 // Sets the pagetree and gets a 1-dim array in return with the pages (in correct submission order BTW...)
408 $flatList = $this->export->setPageTree($idH);
409 foreach ($flatList as $k => $value) {
410 $this->export->export_addRecord('pages', BackendUtility::getRecord('pages', $k));
411 $this->addRecordsForPid($k, $inData['pagetree']['tables'], $inData['pagetree']['maxNumber']);
412 }
413 }
414 }
415 // After adding ALL records we set relations:
416 for ($a = 0; $a < 10; $a++) {
417 $addR = $this->export->export_addDBRelations($a);
418 if (empty($addR)) {
419 break;
420 }
421 }
422 // Finally files are added:
423 // MUST be after the DBrelations are set so that files from ALL added records are included!
424 $this->export->export_addFilesFromRelations();
425
426 $this->export->export_addFilesFromSysFilesRecords();
427
428 // If the download button is clicked, return file
429 if ($inData['download_export'] || $inData['save_export']) {
430 switch ((string)$inData['filetype']) {
431 case 'xml':
432 $out = $this->export->compileMemoryToFileContent('xml');
433 $fExt = '.xml';
434 break;
435 case 't3d':
436 $this->export->dontCompress = 1;
437 // intentional fall-through
438 default:
439 $out = $this->export->compileMemoryToFileContent();
440 $fExt = ($this->export->doOutputCompress() ? '-z' : '') . '.t3d';
441 }
442 // Filename:
443 $dlFile = $inData['filename'];
444 if (!$dlFile) {
445 $exportName = substr(preg_replace('/[^[:alnum:]_]/', '-', $inData['download_export_name']), 0, 20);
446 $dlFile = 'T3D_' . $exportName . '_' . date('Y-m-d_H-i') . $fExt;
447 }
448
449 // Export for download:
450 if ($inData['download_export']) {
451 $mimeType = 'application/octet-stream';
452 Header('Content-Type: ' . $mimeType);
453 Header('Content-Length: ' . strlen($out));
454 Header('Content-Disposition: attachment; filename=' . basename($dlFile));
455 echo $out;
456 die;
457 }
458 // Export by saving:
459 if ($inData['save_export']) {
460 $saveFolder = $this->getDefaultImportExportFolder();
461 if ($saveFolder !== false && $saveFolder->checkActionPermission('write')) {
462 $temporaryFileName = GeneralUtility::tempnam('export');
463 file_put_contents($temporaryFileName, $out);
464 $file = $saveFolder->addFile($temporaryFileName, $dlFile, 'replace');
465 if ($saveFilesOutsideExportFile) {
466 $filesFolderName = $dlFile . '.files';
467 $filesFolder = $saveFolder->createFolder($filesFolderName);
468 $temporaryFolderForExport = ResourceFactory::getInstance()->retrieveFileOrFolderObject($this->export->getTemporaryFilesPathForExport());
469 $temporaryFilesForExport = $temporaryFolderForExport->getFiles();
470 foreach ($temporaryFilesForExport as $temporaryFileForExport) {
471 $filesFolder->getStorage()->moveFile($temporaryFileForExport, $filesFolder);
472 }
473 $temporaryFolderForExport->delete();
474 }
475
476 /** @var FlashMessage $flashMessage */
477 $flashMessage = GeneralUtility::makeInstance(
478 FlashMessage::class,
479 sprintf($GLOBALS['LANG']->getLL('exportdata_savedInSBytes', true), $file->getPublicUrl(), GeneralUtility::formatSize(strlen($out))),
480 $GLOBALS['LANG']->getLL('exportdata_savedFile'),
481 FlashMessage::OK
482 );
483 } else {
484 /** @var FlashMessage $flashMessage */
485 $flashMessage = GeneralUtility::makeInstance(
486 FlashMessage::class,
487 sprintf($GLOBALS['LANG']->getLL('exportdata_badPathS', true), $saveFolder->getPublicUrl()),
488 $GLOBALS['LANG']->getLL('exportdata_problemsSavingFile'),
489 FlashMessage::ERROR
490 );
491 }
492 $this->content .= $flashMessage->render();
493 }
494 }
495 // OUTPUT to BROWSER:
496 // Now, if we didn't make download file, show configuration form based on export:
497 $menuItems = array();
498 // Export configuration
499 $row = array();
500 $this->makeConfigurationForm($inData, $row);
501 $menuItems[] = array(
502 'label' => $this->lang->getLL('tableselec_configuration'),
503 'content' => '
504 <table border="0" cellpadding="1" cellspacing="1">
505 ' . implode('
506 ', $row) . '
507 </table>
508 '
509 );
510 // File options
511 $row = array();
512 $this->makeSaveForm($inData, $row);
513 $menuItems[] = array(
514 'label' => $this->lang->getLL('exportdata_filePreset'),
515 'content' => '
516 <table border="0" cellpadding="1" cellspacing="1">
517 ' . implode('
518 ', $row) . '
519 </table>
520 '
521 );
522 // File options
523 $row = array();
524 $this->makeAdvancedOptionsForm($inData, $row);
525 $menuItems[] = array(
526 'label' => $this->lang->getLL('exportdata_advancedOptions'),
527 'content' => '
528 <table border="0" cellpadding="1" cellspacing="1">
529 ' . implode('
530 ', $row) . '
531 </table>
532 '
533 );
534 // Generate overview:
535 $overViewContent = $this->export->displayContentOverview();
536 // Print errors that might be:
537 $errors = $this->export->printErrorLog();
538 $menuItems[] = array(
539 'label' => $this->lang->getLL('exportdata_messages'),
540 'content' => $errors,
541 'stateIcon' => $errors ? 2 : 0
542 );
543 // Add hidden fields and create tabs:
544
545 $content = $this->moduleTemplate->getDynamicTabMenu($menuItems, 'tx_impexp_export', 1, false, true, false);
546 $content .= '<input type="hidden" name="tx_impexp[action]" value="export" />';
547 $this->content .= $this->moduleTemplate->section('', $content, 0, 1);
548 // Output Overview:
549 $this->content .= $this->moduleTemplate->section($this->lang->getLL('execlistqu_structureToBeExported'), $overViewContent, 0, 1);
550 }
551
552 /**
553 * Adds records to the export object for a specific page id.
554 *
555 * @param int $k Page id for which to select records to add
556 * @param array $tables Array of table names to select from
557 * @param int $maxNumber Max amount of records to select
558 * @return void
559 */
560 public function addRecordsForPid($k, $tables, $maxNumber)
561 {
562 if (!is_array($tables)) {
563 return;
564 }
565 $db = $this->getDatabaseConnection();
566 foreach ($GLOBALS['TCA'] as $table => $value) {
567 if ($table != 'pages' && (in_array($table, $tables) || in_array('_ALL', $tables))) {
568 if ($this->getBackendUser()->check('tables_select', $table) && !$GLOBALS['TCA'][$table]['ctrl']['is_static']) {
569 $res = $this->exec_listQueryPid($table, $k, MathUtility::forceIntegerInRange($maxNumber, 1));
570 while ($subTrow = $db->sql_fetch_assoc($res)) {
571 $this->export->export_addRecord($table, $subTrow);
572 }
573 $db->sql_free_result($res);
574 }
575 }
576 }
577 }
578
579 /**
580 * Selects records from table / pid
581 *
582 * @param string $table Table to select from
583 * @param int $pid Page ID to select from
584 * @param int $limit Max number of records to select
585 * @return \mysqli_result|object Database resource
586 */
587 public function exec_listQueryPid($table, $pid, $limit)
588 {
589 $db = $this->getDatabaseConnection();
590 $orderBy = $GLOBALS['TCA'][$table]['ctrl']['sortby']
591 ? 'ORDER BY ' . $GLOBALS['TCA'][$table]['ctrl']['sortby']
592 : $GLOBALS['TCA'][$table]['ctrl']['default_sortby'];
593 $res = $db->exec_SELECTquery(
594 '*',
595 $table,
596 'pid=' . (int)$pid . BackendUtility::deleteClause($table) . BackendUtility::versioningPlaceholderClause($table),
597 '',
598 $db->stripOrderBy($orderBy),
599 $limit
600 );
601 // Warning about hitting limit:
602 if ($db->sql_num_rows($res) == $limit) {
603 $limitWarning = sprintf($this->lang->getLL('makeconfig_anSqlQueryReturned', true), $limit);
604 /** @var FlashMessage $flashMessage */
605 $flashMessage = GeneralUtility::makeInstance(
606 FlashMessage::class,
607 $this->lang->getLL('execlistqu_maxNumberLimit'),
608 $limitWarning,
609 FlashMessage::WARNING
610 );
611 $this->content .= $flashMessage->render();
612 }
613 return $res;
614 }
615
616 /**
617 * Create configuration form
618 *
619 * @param array $inData Form configurat data
620 * @param array $row Table row accumulation variable. This is filled with table rows.
621 * @return void Sets content in $this->content
622 */
623 public function makeConfigurationForm($inData, &$row)
624 {
625 $nameSuggestion = '';
626 // Page tree export options:
627 if (isset($inData['pagetree']['id'])) {
628 $nameSuggestion .= 'tree_PID' . $inData['pagetree']['id'] . '_L' . $inData['pagetree']['levels'];
629 $row[] = '
630 <tr class="tableheader bgColor5">
631 <td colspan="2">' . $this->lang->getLL('makeconfig_exportPagetreeConfiguration', true)
632 . BackendUtility::cshItem('xMOD_tx_impexp', 'pageTreeCfg') . '</td>
633 </tr>';
634 $row[] = '
635 <tr class="bgColor4">
636 <td><strong>' . $this->lang->getLL('makeconfig_pageId', true) . '</strong></td>
637 <td>' . htmlspecialchars($inData['pagetree']['id']) . '<input type="hidden" value="'
638 . htmlspecialchars($inData['pagetree']['id']) . '" name="tx_impexp[pagetree][id]" /></td>
639 </tr>';
640 $row[] = '
641 <tr class="bgColor4">
642 <td><strong>' . $this->lang->getLL('makeconfig_tree', true) . '</strong>'
643 . BackendUtility::cshItem('xMOD_tx_impexp', 'pageTreeDisplay') . '</td>
644 <td>' . ($this->treeHTML ?: $this->lang->getLL('makeconfig_noTreeExportedOnly', true)) . '</td>
645 </tr>';
646 $opt = array(
647 '-2' => $this->lang->getLL('makeconfig_tablesOnThisPage'),
648 '-1' => $this->lang->getLL('makeconfig_expandedTree'),
649 '0' => $this->lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_0'),
650 '1' => $this->lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_1'),
651 '2' => $this->lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_2'),
652 '3' => $this->lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_3'),
653 '4' => $this->lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_4'),
654 '999' => $this->lang->sL('LLL:EXT:lang/locallang_core.xlf:labels.depth_infi'),
655 );
656 $row[] = '
657 <tr class="bgColor4">
658 <td><strong>' . $this->lang->getLL('makeconfig_levels', true) . '</strong>'
659 . BackendUtility::cshItem('xMOD_tx_impexp', 'pageTreeMode') . '</td>
660 <td>' . $this->renderSelectBox('tx_impexp[pagetree][levels]', $inData['pagetree']['levels'], $opt) . '</td>
661 </tr>';
662 $row[] = '
663 <tr class="bgColor4">
664 <td><strong>' . $this->lang->getLL('makeconfig_includeTables', true) . '</strong>'
665 . BackendUtility::cshItem('xMOD_tx_impexp', 'pageTreeRecordLimit') . '</td>
666 <td>' . $this->tableSelector('tx_impexp[pagetree][tables]', $inData['pagetree']['tables'], 'pages') . '<br/>
667 ' . $this->lang->getLL('makeconfig_maxNumberOfRecords', true) . '<br/>
668 <input type="text" name="tx_impexp[pagetree][maxNumber]" value="'
669 . htmlspecialchars($inData['pagetree']['maxNumber']) . '"' . $this->doc->formWidth(10) . ' /><br/>
670 </td>
671 </tr>';
672 }
673 // Single record export:
674 if (is_array($inData['record'])) {
675 $row[] = '
676 <tr class="tableheader bgColor5">
677 <td colspan="2">' . $this->lang->getLL('makeconfig_exportSingleRecord', true)
678 . BackendUtility::cshItem('xMOD_tx_impexp', 'singleRecord') . '</td>
679 </tr>';
680 foreach ($inData['record'] as $ref) {
681 $rParts = explode(':', $ref);
682 $tName = $rParts[0];
683 $rUid = $rParts[1];
684 $nameSuggestion .= $tName . '_' . $rUid;
685 $rec = BackendUtility::getRecordWSOL($tName, $rUid);
686 if (!empty($rec)) {
687 $row[] = '
688 <tr class="bgColor4">
689 <td><strong>' . $this->lang->getLL('makeconfig_record', true) . '</strong></td>
690 <td>' . $this->iconFactory->getIconForRecord($tName, $rec, Icon::SIZE_SMALL)->render() . BackendUtility::getRecordTitle($tName, $rec, true)
691 . '<input type="hidden" name="tx_impexp[record][]" value="' . htmlspecialchars(($tName . ':' . $rUid)) . '" /></td>
692 </tr>';
693 }
694 }
695 }
696 // Single tables/pids:
697 if (is_array($inData['list'])) {
698 $row[] = '
699 <tr class="tableheader bgColor5">
700 <td colspan="2">' . $this->lang->getLL('makeconfig_exportTablesFromPages', true) . '</td>
701 </tr>';
702 // Display information about pages from which the export takes place
703 $tblList = '';
704 foreach ($inData['list'] as $reference) {
705 $referenceParts = explode(':', $reference);
706 $tableName = $referenceParts[0];
707 if ($this->getBackendUser()->check('tables_select', $tableName)) {
708 // If the page is actually the root, handle it differently
709 // NOTE: we don't compare integers, because the number actually comes from the split string above
710 if ($referenceParts[1] === '0') {
711 $iconAndTitle = $this->iconFactory->getIcon('apps-pagetree-root', Icon::SIZE_SMALL)->render() . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
712 } else {
713 $record = BackendUtility::getRecordWSOL('pages', $referenceParts[1]);
714 $iconAndTitle = $this->iconFactory->getIconForRecord('pages', $record, Icon::SIZE_SMALL)->render()
715 . BackendUtility::getRecordTitle('pages', $record, true);
716 }
717 $tblList .= 'Table "' . $tableName . '" from ' . $iconAndTitle
718 . '<input type="hidden" name="tx_impexp[list][]" value="' . htmlspecialchars($reference) . '" /><br/>';
719 }
720 }
721 $row[] = '
722 <tr class="bgColor4">
723 <td><strong>' . $this->lang->getLL('makeconfig_tablePids', true) . '</strong>'
724 . BackendUtility::cshItem('xMOD_tx_impexp', 'tableList') . '</td>
725 <td>' . $tblList . '</td>
726 </tr>';
727 $row[] = '
728 <tr class="bgColor4">
729 <td><strong>' . $this->lang->getLL('makeconfig_maxNumberOfRecords', true)
730 . BackendUtility::cshItem('xMOD_tx_impexp', 'tableListMaxNumber') . '</strong></td>
731 <td>
732 <input type="text" name="tx_impexp[listCfg][maxNumber]" value="'
733 . htmlspecialchars($inData['listCfg']['maxNumber']) . '" /><br/>
734 </td>
735 </tr>';
736 }
737 $row[] = '
738 <tr class="tableheader bgColor5">
739 <td colspan="2">' . $this->lang->getLL('makeconfig_relationsAndExclusions', true) . '</td>
740 </tr>';
741 // Add relation selector:
742 $row[] = '
743 <tr class="bgColor4">
744 <td><strong>' . $this->lang->getLL('makeconfig_includeRelationsToTables', true) . '</strong>'
745 . BackendUtility::cshItem('xMOD_tx_impexp', 'inclRelations') . '</td>
746 <td>' . $this->tableSelector('tx_impexp[external_ref][tables]', $inData['external_ref']['tables']) . '</td>
747 </tr>';
748 // Add static relation selector:
749 $row[] = '
750 <tr class="bgColor4">
751 <td><strong>' . $this->lang->getLL('makeconfig_useStaticRelationsFor', true) . '</strong>'
752 . BackendUtility::cshItem('xMOD_tx_impexp', 'staticRelations') . '</td>
753 <td>' . $this->tableSelector('tx_impexp[external_static][tables]', $inData['external_static']['tables']) . '<br/>
754 <label for="checkShowStaticRelations">' . $this->lang->getLL('makeconfig_showStaticRelations', true)
755 . '</label> <input type="checkbox" name="tx_impexp[showStaticRelations]" id="checkShowStaticRelations" value="1"'
756 . ($inData['showStaticRelations'] ? ' checked="checked"' : '') . ' />
757 </td>
758 </tr>';
759 // Exclude:
760 $excludeHiddenFields = '';
761 if (is_array($inData['exclude'])) {
762 foreach ($inData['exclude'] as $key => $value) {
763 $excludeHiddenFields .= '<input type="hidden" name="tx_impexp[exclude][' . $key . ']" value="1" />';
764 }
765 }
766 if (!empty($inData['exclude'])) {
767 $excludedElements = '<em>' . implode(', ', array_keys($inData['exclude'])) . '</em><hr/><label for="checkExclude">'
768 . $this->lang->getLL('makeconfig_clearAllExclusions', true)
769 . '</label> <input type="checkbox" name="tx_impexp[exclude]" id="checkExclude" value="1" />';
770 } else {
771 $excludedElements = $this->lang->getLL('makeconfig_noExcludedElementsYet', true);
772 }
773 $row[] = '
774 <tr class="bgColor4">
775 <td><strong>' . $this->lang->getLL('makeconfig_excludeElements', true) . '</strong>'
776 . BackendUtility::cshItem('xMOD_tx_impexp', 'excludedElements') . '</td>
777 <td>' . $excludeHiddenFields . '
778 ' . $excludedElements . '
779 </td>
780 </tr>';
781 // Add buttons:
782 $row[] = '
783 <tr class="bgColor4">
784 <td>&nbsp;</td>
785 <td>
786 <input class="btn btn-default" type="submit" value="' . $this->lang->getLL('makeadvanc_update', true) . '" />
787 <input type="hidden" name="tx_impexp[download_export_name]" value="' . substr($nameSuggestion, 0, 30) . '" />
788 </td>
789 </tr>';
790 }
791
792 /**
793 * Create advanced options form
794 * Sets content in $this->content
795 *
796 * @param array $inData Form configurat data
797 * @param array $row Table row accumulation variable. This is filled with table rows.
798 * @return void
799 */
800 public function makeAdvancedOptionsForm($inData, &$row)
801 {
802 // Soft references
803 $row[] = '
804 <tr class="tableheader bgColor5">
805 <td colspan="2">' . $this->lang->getLL('makeadvanc_softReferences', true) . '</td>
806 </tr>';
807 $row[] = '
808 <tr class="bgColor4">
809 <td><label for="checkExcludeHTMLfileResources"><strong>'
810 . $this->lang->getLL('makeadvanc_excludeHtmlCssFile', true) . '</strong></label>'
811 . BackendUtility::cshItem('xMOD_tx_impexp', 'htmlCssResources') . '</td>
812 <td><input type="checkbox" name="tx_impexp[excludeHTMLfileResources]" id="checkExcludeHTMLfileResources" value="1"'
813 . ($inData['excludeHTMLfileResources'] ? ' checked="checked"' : '') . ' /></td>
814 </tr>';
815
816 // Files options
817 $row[] = '
818 <tr class="tableheader bgColor5">
819 <td colspan="2">' . $this->lang->getLL('makeadvanc_files', true) . '</td>
820 </tr>';
821 $row[] = '
822 <tr class="bgColor4">
823 <td><label for="saveFilesOutsideExportFile"><strong>'
824 . $this->lang->getLL('makeadvanc_saveFilesOutsideExportFile', true) . '</strong><br />'
825 . $this->lang->getLL('makeadvanc_saveFilesOutsideExportFile_limit', true) . '</label></td>
826 <td><input type="checkbox" name="tx_impexp[saveFilesOutsideExportFile]" id="saveFilesOutsideExportFile" value="1"'
827 . ($inData['saveFilesOutsideExportFile'] ? ' checked="checked"' : '') . ' /></td>
828 </tr>';
829 // Extensions
830 $row[] = '
831 <tr class="tableheader bgColor5">
832 <td colspan="2">' . $this->lang->getLL('makeadvanc_extensionDependencies', true) . '</td>
833 </tr>';
834 $row[] = '
835 <tr class="bgColor4">
836 <td><strong>' . $this->lang->getLL('makeadvanc_selectExtensionsThatThe', true) . '</strong>'
837 . BackendUtility::cshItem('xMOD_tx_impexp', 'extensionDependencies') . '</td>
838 <td>' . $this->extensionSelector('tx_impexp[extension_dep]', $inData['extension_dep']) . '</td>
839 </tr>';
840 // Add buttons:
841 $row[] = '
842 <tr class="bgColor4">
843 <td>&nbsp;</td>
844 <td>
845 <input class="btn btn-default" type="submit" value="' . $this->lang->getLL('makesavefo_update', true) . '" />
846 <input type="hidden" name="tx_impexp[download_export_name]" value="" />
847 </td>
848 </tr>';
849 }
850
851 /**
852 * Create configuration form
853 *
854 * @param array $inData Form configurat data
855 * @param array $row Table row accumulation variable. This is filled with table rows.
856 * @return void Sets content in $this->content
857 */
858 public function makeSaveForm($inData, &$row)
859 {
860 // Presets:
861 $row[] = '
862 <tr class="tableheader bgColor5">
863 <td colspan="2">' . $this->lang->getLL('makesavefo_presets', true) . '</td>
864 </tr>';
865 $opt = array('');
866 $where = '(public>0 OR user_uid=' . (int)$this->getBackendUser()->user['uid'] . ')'
867 . ($inData['pagetree']['id'] ? ' AND (item_uid=' . (int)$inData['pagetree']['id'] . ' OR item_uid=0)' : '');
868 $presets = $this->getDatabaseConnection()->exec_SELECTgetRows('*', 'tx_impexp_presets', $where);
869 if (is_array($presets)) {
870 foreach ($presets as $presetCfg) {
871 $opt[$presetCfg['uid']] = $presetCfg['title'] . ' [' . $presetCfg['uid'] . ']'
872 . ($presetCfg['public'] ? ' [Public]' : '')
873 . ($presetCfg['user_uid'] === $this->getBackendUser()->user['uid'] ? ' [Own]' : '');
874 }
875 }
876 $row[] = '
877 <tr class="bgColor4">
878 <td><strong>' . $this->lang->getLL('makesavefo_presets', true) . '</strong>'
879 . BackendUtility::cshItem('xMOD_tx_impexp', 'presets') . '</td>
880 <td>
881 ' . $this->lang->getLL('makesavefo_selectPreset', true) . '<br/>
882 ' . $this->renderSelectBox('preset[select]', '', $opt) . '
883 <br/>
884 <input type="hidden" name="not-set" value="1" id="t3js-submit-field" />
885 <input class="btn btn-default" type="submit" value="' . $this->lang->getLL('makesavefo_load', true) . '" name="preset[load]" />
886 <input class="btn btn-default t3js-confirm-trigger" type="button" value="' . $this->lang->getLL('makesavefo_save', true) . '" name="preset[save]" data-title="' . $this->lang->getLL('pleaseConfirm', true) . '" data-message="' . $this->lang->getLL('makesavefo_areYouSure', true) . '" />
887 <input class="btn btn-default t3js-confirm-trigger" type="button" value="' . $this->lang->getLL('makesavefo_delete', true) . '" name="preset[delete]" data-title="' . $this->lang->getLL('pleaseConfirm', true) . '" data-message="' . $this->lang->getLL('makesavefo_areYouSure', true) . '" />
888 <input class="btn btn-default t3js-confirm-trigger" type="button" value="' . $this->lang->getLL('makesavefo_merge', true) . '" name="preset[merge]" data-title="' . $this->lang->getLL('pleaseConfirm', true) . '" data-message="' . $this->lang->getLL('makesavefo_areYouSure', true) . '" />
889 <br/>
890 ' . $this->lang->getLL('makesavefo_titleOfNewPreset', true) . '
891 <input type="text" name="tx_impexp[preset][title]" value="'
892 . htmlspecialchars($inData['preset']['title']) . '" /><br/>
893 <label for="checkPresetPublic">' . $this->lang->getLL('makesavefo_public', true) . '</label>
894 <input type="checkbox" name="tx_impexp[preset][public]" id="checkPresetPublic" value="1"'
895 . ($inData['preset']['public'] ? ' checked="checked"' : '') . ' /><br/>
896 </td>
897 </tr>';
898 // Output options:
899 $row[] = '
900 <tr class="tableheader bgColor5">
901 <td colspan="2">' . $this->lang->getLL('makesavefo_outputOptions', true) . '</td>
902 </tr>';
903 // Meta data:
904 $thumbnailFiles = array();
905 foreach ($this->getThumbnailFiles() as $thumbnailFile) {
906 $thumbnailFiles[$thumbnailFile->getCombinedIdentifier()] = $thumbnailFile->getName();
907 }
908 if (!empty($thumbnailFiles)) {
909 array_unshift($thumbnailFiles, '');
910 }
911 $thumbnail = null;
912 if (!empty($inData['meta']['thumbnail'])) {
913 $thumbnail = $this->getFile($inData['meta']['thumbnail']);
914 }
915 $saveFolder = $this->getDefaultImportExportFolder();
916
917 $row[] = '
918 <tr class="bgColor4">
919 <td><strong>' . $this->lang->getLL('makesavefo_metaData', true) . '</strong>'
920 . BackendUtility::cshItem('xMOD_tx_impexp', 'metadata') . '</td>
921 <td>
922 ' . $this->lang->getLL('makesavefo_title', true) . ' <br/>
923 <input type="text" name="tx_impexp[meta][title]" value="' . htmlspecialchars($inData['meta']['title']) . '" /><br/>
924 ' . $this->lang->getLL('makesavefo_description', true) . ' <br/>
925 <input type="text" name="tx_impexp[meta][description]" value="' . htmlspecialchars($inData['meta']['description']) . '" /><br/>
926 ' . $this->lang->getLL('makesavefo_notes', true) . ' <br/>
927 <textarea name="tx_impexp[meta][notes]">' . htmlspecialchars($inData['meta']['notes']) . '</textarea><br/>
928 ' . (!empty($thumbnailFiles) ? '
929 ' . $this->lang->getLL('makesavefo_thumbnail', true) . '<br/>
930 ' . $this->renderSelectBox('tx_impexp[meta][thumbnail]', $inData['meta']['thumbnail'], $thumbnailFiles) : '') . '<br/>
931 ' . ($thumbnail ? '<img src="' . htmlspecialchars($thumbnail->getPublicUrl(true)) . '" vspace="5" style="border: solid black 1px;" alt="" /><br/>' : '') . '
932 ' . $this->lang->getLL('makesavefo_uploadThumbnail', true) . '<br/>
933 ' . ($saveFolder ? '<input type="file" name="upload_1" size="30" /><br/>
934 <input type="hidden" name="file[upload][1][target]" value="' . htmlspecialchars($saveFolder->getCombinedIdentifier()) . '" />
935 <input type="hidden" name="file[upload][1][data]" value="1" /><br />' : '') . '
936 </td>
937 </tr>';
938 // Add file options:
939 $opt = array();
940 if ($this->export->compress) {
941 $opt['t3d_compressed'] = $this->lang->getLL('makesavefo_t3dFileCompressed');
942 }
943 $opt['t3d'] = $this->lang->getLL('makesavefo_t3dFile');
944 $opt['xml'] = $this->lang->getLL('makesavefo_xml');
945 $fileName = '';
946 if ($saveFolder) {
947 $fileName = sprintf($this->lang->getLL('makesavefo_filenameSavedInS', true), $saveFolder->getCombinedIdentifier())
948 . '<br/>
949 <input type="text" name="tx_impexp[filename]" value="'
950 . htmlspecialchars($inData['filename']) . '" /><br/>';
951 }
952 $row[] = '
953 <tr>
954 <td>
955 <strong>' . $this->lang->getLL('makesavefo_fileFormat', true) . '</strong>'
956 . BackendUtility::cshItem('xMOD_tx_impexp', 'fileFormat') . '
957 </td>
958 <td>
959 ' . $this->renderSelectBox('tx_impexp[filetype]', $inData['filetype'], $opt) . '<br/>
960 ' . $this->lang->getLL('makesavefo_maxSizeOfFiles', true) . '<br/>
961 <input type="text" name="tx_impexp[maxFileSize]" value="' . htmlspecialchars($inData['maxFileSize']) . '" />
962 <br/>
963 ' . $fileName . '
964 </td>
965 </tr>';
966 // Add buttons:
967 $row[] = '
968 <tr>
969 <td>&nbsp;</td>
970 <td>
971 <input class="btn btn-default" type="submit" value="' . $this->lang->getLL('makesavefo_update', true) . '" /> -
972 <input class="btn btn-default" type="submit" value="' . $this->lang->getLL('makesavefo_downloadExport', true) . '" name="tx_impexp[download_export]" />
973 ' . ($saveFolder ? ' - <input class="btn btn-default" type="submit" value="' . $this->lang->getLL('importdata_saveToFilename', true) . '" name="tx_impexp[save_export]" />' : '') . '
974 </td>
975 </tr>';
976 }
977
978 /**************************
979 * IMPORT FUNCTIONS
980 **************************/
981
982 /**
983 * Import part of module
984 *
985 * @param array $inData Content of POST VAR tx_impexp[]..
986 * @throws \BadFunctionCallException
987 * @throws \InvalidArgumentException
988 * @throws \RuntimeException
989 * @return void Setting content in $this->content
990 */
991 public function importData($inData)
992 {
993 $access = is_array($this->pageinfo) ? 1 : 0;
994 $beUser = $this->getBackendUser();
995 if ($this->id && $access || $beUser->user['admin'] && !$this->id) {
996 if ($beUser->user['admin'] && !$this->id) {
997 $this->pageinfo = array('title' => '[root-level]', 'uid' => 0, 'pid' => 0);
998 }
999 if ($inData['new_import']) {
1000 unset($inData['import_mode']);
1001 }
1002 /** @var $import \TYPO3\CMS\Impexp\ImportExport */
1003 $import = GeneralUtility::makeInstance(\TYPO3\CMS\Impexp\ImportExport::class);
1004 $import->init(0, 'import');
1005 $import->update = $inData['do_update'];
1006 $import->import_mode = $inData['import_mode'];
1007 $import->enableLogging = $inData['enableLogging'];
1008 $import->global_ignore_pid = $inData['global_ignore_pid'];
1009 $import->force_all_UIDS = $inData['force_all_UIDS'];
1010 $import->showDiff = !$inData['notShowDiff'];
1011 $import->allowPHPScripts = $inData['allowPHPScripts'];
1012 $import->softrefInputValues = $inData['softrefInputValues'];
1013 // OUTPUT creation:
1014 $menuItems = array();
1015 // Make input selector:
1016 // must have trailing slash.
1017 $path = $this->getDefaultImportExportFolder();
1018 $exportFiles = $this->getExportFiles();
1019 // Configuration
1020 $row = array();
1021 $selectOptions = array('');
1022 foreach ($exportFiles as $file) {
1023 $selectOptions[$file->getCombinedIdentifier()] = $file->getPublicUrl();
1024 }
1025 $row[] = '
1026 <tr>
1027 <th colspan="2">' . $this->lang->getLL('importdata_selectFileToImport', true) . '</th>
1028 </tr>';
1029 $noCompressorAvailable = !$import->compress
1030 ? '<br /><span class="text-danger">' . $this->lang->getLL('importdata_noteNoDecompressorAvailable', true) . '</span>'
1031 : '';
1032 $row[] = '
1033 <tr>
1034 <td valign="top">
1035 ' . $this->lang->getLL('importdata_file', true) . ''
1036 . BackendUtility::cshItem('xMOD_tx_impexp', 'importFile') . '
1037 </td>
1038 <td>
1039 ' . $this->renderSelectBox('tx_impexp[file]', $inData['file'], $selectOptions) . '<br />'
1040 . sprintf($this->lang->getLL('importdata_fromPathS', true), $path ? $path->getCombinedIdentifier() : $this->lang->getLL('importdata_no_accessible_file_mount', true)) .
1041 $noCompressorAvailable . '
1042 </td>
1043 </tr>';
1044 $row[] = '
1045 <tr>
1046 <th colspan="2">
1047 ' . $this->lang->getLL('importdata_importOptions', true) . '
1048 </th>
1049 </tr>';
1050 $row[] = '
1051 <tr>
1052 <td valign="top">
1053 ' . $this->lang->getLL('importdata_update', true)
1054 . BackendUtility::cshItem('xMOD_tx_impexp', 'update') . '
1055 </td>
1056 <td>
1057 <input type="checkbox" name="tx_impexp[do_update]" id="checkDo_update" value="1"'
1058 . ($inData['do_update'] ? ' checked="checked"' : '') . ' />
1059 <label for="checkDo_update">' . $this->lang->getLL('importdata_updateRecords', true) . '</label>
1060 <br/>
1061 <em>(' . $this->lang->getLL('importdata_thisOptionRequiresThat', true) . ')</em>' . ($inData['do_update'] ? ' <hr/>
1062 <input type="checkbox" name="tx_impexp[global_ignore_pid]" id="checkGlobal_ignore_pid" value="1"'
1063 . ($inData['global_ignore_pid'] ? ' checked="checked"' : '') . ' />
1064 <label for="checkGlobal_ignore_pid">' . $this->lang->getLL('importdata_ignorePidDifferencesGlobally', true) . '</label><br/>
1065 <em>(' . $this->lang->getLL('importdata_ifYouSetThis', true) . ')</em>
1066 ' : '') . '
1067 </td>
1068 </tr>';
1069 $allowPhpScripts = $beUser->isAdmin()
1070 ? '
1071 <input type="checkbox" name="tx_impexp[allowPHPScripts]" id="checkAllowPHPScripts" value="1"'
1072 . ($inData['allowPHPScripts'] ? ' checked="checked"' : '') . ' />
1073 <label for="checkAllowPHPScripts">' . $this->lang->getLL('importdata_allowToWriteBanned', true) . '</label><br/>'
1074 : '';
1075 $doUpdate = !$inData['do_update'] && $beUser->isAdmin()
1076 ? '
1077 <br/>
1078 <input type="checkbox" name="tx_impexp[force_all_UIDS]" id="checkForce_all_UIDS" value="1"'
1079 . ($inData['force_all_UIDS'] ? ' checked="checked"' : '') . ' />
1080 <label for="checkForce_all_UIDS"><span class="text-danger">'
1081 . $this->lang->getLL('importdata_force_all_UIDS', true) . '</span></label><br/>
1082 <em>(' . $this->lang->getLL('importdata_force_all_UIDS_descr', true) . ')</em>'
1083 : '';
1084 $row[] = '<tr>
1085 <td valign="top">
1086 ' . $this->lang->getLL('importdata_options', true) . BackendUtility::cshItem('xMOD_tx_impexp', 'options') . '
1087 </td>
1088 <td>
1089 <input type="checkbox" name="tx_impexp[notShowDiff]" id="checkNotShowDiff" value="1"'
1090 . ($inData['notShowDiff'] ? ' checked="checked"' : '') . ' />
1091 <label for="checkNotShowDiff">' . $this->lang->getLL('importdata_doNotShowDifferences', true) . '</label><br/>
1092 <em>(' . $this->lang->getLL('importdata_greenValuesAreFrom', true) . ')</em>
1093 <br/><br/>
1094
1095 ' . $allowPhpScripts . $doUpdate . '
1096 </td>
1097 </tr>';
1098 $newImport = !$inData['import_file']
1099 ? '<input class="btn btn-default" type="submit" value="' . $this->lang->getLL('importdata_preview', true) . '" />' . ($inData['file']
1100 ? ' - <input type="hidden" name="not-set" value="1" id="t3js-submit-field" /><input class="btn btn-default t3js-confirm-trigger" type="button" value="' . ($inData['do_update']
1101 ? $this->lang->getLL('importdata_update_299e', true)
1102 : $this->lang->getLL('importdata_import', true)) . '" name="tx_impexp[import_file]" data-title="' . $this->lang->getLL('pleaseConfirm', true) . '" data-message="' . $this->lang->getLL('importdata_areYouSure', true) . '" />'
1103 : '')
1104 : '<input class="btn btn-default" type="submit" name="tx_impexp[new_import]" value="' . $this->lang->getLL('importdata_newImport', true) . '" />';
1105 $row[] = '<tr>
1106 <td valign="top">
1107 ' . $this->lang->getLL('importdata_action', true) . BackendUtility::cshItem('xMOD_tx_impexp', 'action') . '
1108 </td>
1109 <td>
1110 ' . $newImport . '
1111 <input type="hidden" name="tx_impexp[action]" value="import" />
1112 </td>
1113 </tr>';
1114 $row[] = '<tr>
1115 <td valign="top">
1116 ' . $this->lang->getLL('importdata_enableLogging', true)
1117 . BackendUtility::cshItem('xMOD_tx_impexp', 'enableLogging') . '
1118 </td>
1119 <td>
1120 <input type="checkbox" name="tx_impexp[enableLogging]" id="checkEnableLogging" value="1"'
1121 . ($inData['enableLogging'] ? ' checked="checked"' : '') . ' />
1122 <label for="checkEnableLogging">' . $this->lang->getLL('importdata_writeIndividualDbActions', true) . '</label><br/>
1123 <em>(' . $this->lang->getLL('importdata_thisIsDisabledBy', true) . ')</em>
1124 </td>
1125 </tr>';
1126 $menuItems[] = array(
1127 'label' => $this->lang->getLL('importdata_import', true),
1128 'content' => '
1129 <table border="0" cellpadding="1" cellspacing="1">
1130 ' . implode('
1131 ', $row) . '
1132 </table>
1133 '
1134 );
1135 // Upload file:
1136 $tempFolder = $this->getDefaultImportExportFolder();
1137 if ($tempFolder) {
1138 $row = array();
1139 $row[] = '
1140 <tr>
1141 <th colspan="2">' . $this->lang->getLL('importdata_uploadFileFromLocal', true) . '</th>
1142 </tr>';
1143 $row[] = '
1144 <tr>
1145 <td valign="top">
1146 ' . $this->lang->getLL('importdata_browse', true) . BackendUtility::cshItem('xMOD_tx_impexp', 'upload') . '
1147 </td>
1148 <td>
1149 <input type="file" name="upload_1" size="40" />
1150 <input type="hidden" name="file[upload][1][target]" value="' . htmlspecialchars($tempFolder->getCombinedIdentifier()) . '" />
1151 <input type="hidden" name="file[upload][1][data]" value="1" />
1152 <br />
1153 <input class="btn btn-default" type="submit" name="_upload" value="' . $this->lang->sL('LLL:EXT:lang/locallang_core.xlf:file_upload.php.submit', true) . '" />
1154 <input type="checkbox" name="overwriteExistingFiles" id="checkOverwriteExistingFiles" value="1" checked="checked" />
1155 <label for="checkOverwriteExistingFiles">' . $this->lang->sL('LLL:EXT:lang/locallang_misc.xlf:overwriteExistingFiles', true) . '</label>
1156 </td>
1157 </tr>';
1158 if (GeneralUtility::_POST('_upload')) {
1159 $noFileUploaded = $this->fileProcessor->internalUploadMap[1]
1160 ? $this->lang->getLL('importdata_success', true) . ' ' . $this->uploadedFiles[0]->getName()
1161 : '<span class="text-danger">' . $this->lang->getLL('importdata_failureNoFileUploaded', true) . '</span>';
1162 $row[] = '<tr class="bgColor4">
1163 <td>' . $this->lang->getLL('importdata_uploadStatus', true) . '</td>
1164 <td>' . $noFileUploaded . '</td>
1165 </tr>';
1166 }
1167 $menuItems[] = array(
1168 'label' => $this->lang->getLL('importdata_upload'),
1169 'content' => '
1170 <table border="0" cellpadding="1" cellspacing="1">
1171 ' . implode('
1172 ', $row) . '
1173 </table>
1174 '
1175 );
1176 }
1177 // Perform import or preview depending:
1178 $overviewContent = '';
1179 $extensionInstallationMessage = '';
1180 $inFile = $this->getFile($inData['file']);
1181 if ($inFile !== null && $inFile->exists()) {
1182 $trow = array();
1183 if ($import->loadFile($inFile->getForLocalProcessing(false), 1)) {
1184 // Check extension dependencies:
1185 $extKeysToInstall = array();
1186 if (is_array($import->dat['header']['extensionDependencies'])) {
1187 foreach ($import->dat['header']['extensionDependencies'] as $extKey) {
1188 if (!\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($extKey)) {
1189 $extKeysToInstall[] = $extKey;
1190 }
1191 }
1192 }
1193 if (!empty($extKeysToInstall)) {
1194 $extensionInstallationMessage = 'Before you can install this T3D file you need to install the extensions "'
1195 . implode('", "', $extKeysToInstall) . '".';
1196 }
1197 if ($inData['import_file']) {
1198 if (empty($extKeysToInstall)) {
1199 $import->importData($this->id);
1200 BackendUtility::setUpdateSignal('updatePageTree');
1201 }
1202 }
1203 $import->display_import_pid_record = $this->pageinfo;
1204 $overviewContent = $import->displayContentOverview();
1205 }
1206 // Meta data output:
1207 $trow[] = '<tr class="bgColor5">
1208 <td colspan="2"><strong>' . $this->lang->getLL('importdata_metaData', true) . '</strong></td>
1209 </tr>';
1210 $trow[] = '<tr class="bgColor4">
1211 <td><strong>' . $this->lang->getLL('importdata_title', true) . '</strong></td>
1212 <td width="95%">' . nl2br(htmlspecialchars($import->dat['header']['meta']['title'])) . '</td>
1213 </tr>';
1214 $trow[] = '<tr class="bgColor4">
1215 <td><strong>' . $this->lang->getLL('importdata_description', true) . '</strong></td>
1216 <td width="95%">' . nl2br(htmlspecialchars($import->dat['header']['meta']['description'])) . '</td>
1217 </tr>';
1218 $trow[] = '<tr class="bgColor4">
1219 <td><strong>' . $this->lang->getLL('importdata_notes', true) . '</strong></td>
1220 <td width="95%">' . nl2br(htmlspecialchars($import->dat['header']['meta']['notes'])) . '</td>
1221 </tr>';
1222 $trow[] = '<tr class="bgColor4">
1223 <td><strong>' . $this->lang->getLL('importdata_packager', true) . '</strong></td>
1224 <td width="95%">' . nl2br(htmlspecialchars(($import->dat['header']['meta']['packager_name']
1225 . ' (' . $import->dat['header']['meta']['packager_username'] . ')'))) . '<br/>
1226 ' . $this->lang->getLL('importdata_email', true) . ' '
1227 . $import->dat['header']['meta']['packager_email'] . '</td>
1228 </tr>';
1229 // Thumbnail icon:
1230 if (is_array($import->dat['header']['thumbnail'])) {
1231 $pI = pathinfo($import->dat['header']['thumbnail']['filename']);
1232 if (GeneralUtility::inList('gif,jpg,png,jpeg', strtolower($pI['extension']))) {
1233 // Construct filename and write it:
1234 $fileName = PATH_site . 'typo3temp/importthumb.' . $pI['extension'];
1235 GeneralUtility::writeFile($fileName, $import->dat['header']['thumbnail']['content']);
1236 // Check that the image really is an image and not a malicious PHP script...
1237 if (getimagesize($fileName)) {
1238 // Create icon tag:
1239 $iconTag = '<img src="../' . PathUtility::stripPathSitePrefix($fileName)
1240 . '" ' . $import->dat['header']['thumbnail']['imgInfo'][3]
1241 . ' vspace="5" style="border: solid black 1px;" alt="" />';
1242 $trow[] = '<tr class="bgColor4">
1243 <td><strong>' . $this->lang->getLL('importdata_icon', true) . '</strong></td>
1244 <td>' . $iconTag . '</td>
1245 </tr>';
1246 } else {
1247 GeneralUtility::unlink_tempfile($fileName);
1248 }
1249 }
1250 }
1251 $menuItems[] = array(
1252 'label' => $this->lang->getLL('importdata_metaData_1387'),
1253 'content' => '
1254 <table border="0" cellpadding="1" cellspacing="1">
1255 ' . implode('
1256 ', $trow) . '
1257 </table>
1258 '
1259 );
1260 }
1261 // Print errors that might be:
1262 $errors = $import->printErrorLog();
1263 $menuItems[] = array(
1264 'label' => $this->lang->getLL('importdata_messages'),
1265 'content' => $errors,
1266 'stateIcon' => $errors ? 2 : 0
1267 );
1268 // Output tabs:
1269 $content = $this->moduleTemplate->getDynamicTabMenu($menuItems, 'tx_impexp_import', 1, false, true, false);
1270 if ($extensionInstallationMessage) {
1271 $content = '<div style="border: 1px black solid; margin: 10px 10px 10px 10px; padding: 10px 10px 10px 10px;">'
1272 . $this->moduleTemplate->icons(1) . htmlspecialchars($extensionInstallationMessage) . '</div>' . $content;
1273 }
1274 $this->content .= $this->moduleTemplate->section('', $content, 0, 1);
1275 // Print overview:
1276 if ($overviewContent) {
1277 $this->content .= $this->moduleTemplate->section($inData['import_file']
1278 ? $this->lang->getLL('importdata_structureHasBeenImported', true)
1279 : $this->lang->getLL('filterpage_structureToBeImported', true), $overviewContent, 0, 1);
1280 }
1281 }
1282 }
1283
1284 /****************************
1285 * Preset functions
1286 ****************************/
1287
1288 /**
1289 * Manipulate presets
1290 *
1291 * @param array $inData In data array, passed by reference!
1292 * @return void
1293 */
1294 public function processPresets(&$inData)
1295 {
1296 $presetData = GeneralUtility::_GP('preset');
1297 $err = false;
1298 $msg = '';
1299 // Save preset
1300 $beUser = $this->getBackendUser();
1301 // cast public checkbox to int, since this is an int field and NULL is not allowed
1302 $inData['preset']['public'] = (int)$inData['preset']['public'];
1303 if (isset($presetData['save'])) {
1304 $preset = $this->getPreset($presetData['select']);
1305 // Update existing
1306 if (is_array($preset)) {
1307 if ($beUser->isAdmin() || $preset['user_uid'] === $beUser->user['uid']) {
1308 $fields_values = array(
1309 'public' => $inData['preset']['public'],
1310 'title' => $inData['preset']['title'],
1311 'item_uid' => $inData['pagetree']['id'],
1312 'preset_data' => serialize($inData)
1313 );
1314 $this->getDatabaseConnection()->exec_UPDATEquery('tx_impexp_presets', 'uid=' . (int)$preset['uid'], $fields_values);
1315 $msg = 'Preset #' . $preset['uid'] . ' saved!';
1316 } else {
1317 $msg = 'ERROR: The preset was not saved because you were not the owner of it!';
1318 $err = true;
1319 }
1320 } else {
1321 // Insert new:
1322 $fields_values = array(
1323 'user_uid' => $beUser->user['uid'],
1324 'public' => $inData['preset']['public'],
1325 'title' => $inData['preset']['title'],
1326 'item_uid' => $inData['pagetree']['id'],
1327 'preset_data' => serialize($inData)
1328 );
1329 $this->getDatabaseConnection()->exec_INSERTquery('tx_impexp_presets', $fields_values);
1330 $msg = 'New preset "' . htmlspecialchars($inData['preset']['title']) . '" is created';
1331 }
1332 }
1333 // Delete preset:
1334 if (isset($presetData['delete'])) {
1335 $preset = $this->getPreset($presetData['select']);
1336 if (is_array($preset)) {
1337 // Update existing
1338 if ($beUser->isAdmin() || $preset['user_uid'] === $beUser->user['uid']) {
1339 $this->getDatabaseConnection()->exec_DELETEquery('tx_impexp_presets', 'uid=' . (int)$preset['uid']);
1340 $msg = 'Preset #' . $preset['uid'] . ' deleted!';
1341 } else {
1342 $msg = 'ERROR: You were not the owner of the preset so you could not delete it.';
1343 $err = true;
1344 }
1345 } else {
1346 $msg = 'ERROR: No preset selected for deletion.';
1347 $err = true;
1348 }
1349 }
1350 // Load preset
1351 if (isset($presetData['load']) || isset($presetData['merge'])) {
1352 $preset = $this->getPreset($presetData['select']);
1353 if (is_array($preset)) {
1354 // Update existing
1355 $inData_temp = unserialize($preset['preset_data']);
1356 if (is_array($inData_temp)) {
1357 if (isset($presetData['merge'])) {
1358 // Merge records in:
1359 if (is_array($inData_temp['record'])) {
1360 $inData['record'] = array_merge((array)$inData['record'], $inData_temp['record']);
1361 }
1362 // Merge lists in:
1363 if (is_array($inData_temp['list'])) {
1364 $inData['list'] = array_merge((array)$inData['list'], $inData_temp['list']);
1365 }
1366 } else {
1367 $msg = 'Preset #' . $preset['uid'] . ' loaded!';
1368 $inData = $inData_temp;
1369 }
1370 } else {
1371 $msg = 'ERROR: No configuratio data found in preset record!';
1372 $err = true;
1373 }
1374 } else {
1375 $msg = 'ERROR: No preset selected for loading.';
1376 $err = true;
1377 }
1378 }
1379 // Show message:
1380 if ($msg !== '') {
1381 /** @var FlashMessage $flashMessage */
1382 $flashMessage = GeneralUtility::makeInstance(
1383 FlashMessage::class,
1384 'Presets',
1385 $msg,
1386 $err ? FlashMessage::ERROR : FlashMessage::INFO
1387 );
1388 $this->content .= $flashMessage->render();
1389 }
1390 }
1391
1392 /**
1393 * Get single preset record
1394 *
1395 * @param int $uid Preset record
1396 * @return array Preset record, if any (otherwise FALSE)
1397 */
1398 public function getPreset($uid)
1399 {
1400 return $this->getDatabaseConnection()->exec_SELECTgetSingleRow('*', 'tx_impexp_presets', 'uid=' . (int)$uid);
1401 }
1402
1403 /****************************
1404 * Helper functions
1405 ****************************/
1406
1407 /**
1408 * Returns a \TYPO3\CMS\Core\Resource\Folder object for saving export files
1409 * to the server and is also used for uploading import files.
1410 *
1411 * @throws \InvalidArgumentException
1412 * @return NULL|\TYPO3\CMS\Core\Resource\Folder
1413 */
1414 protected function getDefaultImportExportFolder()
1415 {
1416 $defaultImportExportFolder = null;
1417
1418 $defaultTemporaryFolder = $this->getBackendUser()->getDefaultUploadTemporaryFolder();
1419 if ($defaultTemporaryFolder !== null) {
1420 $importExportFolderName = 'importexport';
1421 $createFolder = !$defaultTemporaryFolder->hasFolder($importExportFolderName);
1422 if ($createFolder === true) {
1423 try {
1424 $defaultImportExportFolder = $defaultTemporaryFolder->createFolder($importExportFolderName);
1425 } catch (\TYPO3\CMS\Core\Resource\Exception $folderAccessException) {
1426 }
1427 } else {
1428 $defaultImportExportFolder = $defaultTemporaryFolder->getSubfolder($importExportFolderName);
1429 }
1430 }
1431
1432 return $defaultImportExportFolder;
1433 }
1434
1435
1436 /**
1437 * Check if a file has been uploaded
1438 *
1439 * @throws \InvalidArgumentException
1440 * @throws \UnexpectedValueException
1441 * @return void
1442 */
1443 public function checkUpload()
1444 {
1445 $file = GeneralUtility::_GP('file');
1446 // Initializing:
1447 $this->fileProcessor = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Utility\File\ExtendedFileUtility::class);
1448 $this->fileProcessor->init(array(), $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
1449 $this->fileProcessor->setActionPermissions();
1450 $this->fileProcessor->setExistingFilesConflictMode((int)GeneralUtility::_GP('overwriteExistingFiles') === 1 ? DuplicationBehavior::REPLACE : DuplicationBehavior::CANCEL);
1451 // Checking referer / executing:
1452 $refInfo = parse_url(GeneralUtility::getIndpEnv('HTTP_REFERER'));
1453 $httpHost = GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY');
1454 if (
1455 $httpHost != $refInfo['host']
1456 && !$GLOBALS['$TYPO3_CONF_VARS']['SYS']['doNotCheckReferer']
1457 && $this->vC != $this->getBackendUser()->veriCode()
1458 ) {
1459 $this->fileProcessor->writeLog(0, 2, 1, 'Referer host "%s" and server host "%s" did not match!', array($refInfo['host'], $httpHost));
1460 } else {
1461 $this->fileProcessor->start($file);
1462 $result = $this->fileProcessor->processData();
1463 if (!empty($result['upload'])) {
1464 foreach ($result['upload'] as $uploadedFiles) {
1465 $this->uploadedFiles += $uploadedFiles;
1466 }
1467 }
1468 }
1469 }
1470
1471 /**
1472 * Makes a selector-box from optValues
1473 *
1474 * @param string $prefix Form element name
1475 * @param string $value Current value
1476 * @param array $optValues Options to display (key/value pairs)
1477 * @return string HTML select element
1478 */
1479 public function renderSelectBox($prefix, $value, $optValues)
1480 {
1481 $opt = array();
1482 $isSelFlag = 0;
1483 foreach ($optValues as $k => $v) {
1484 $sel = (string)$k === (string)$value ? ' selected="selected"' : '';
1485 if ($sel) {
1486 $isSelFlag++;
1487 }
1488 $opt[] = '<option value="' . htmlspecialchars($k) . '"' . $sel . '>' . htmlspecialchars($v) . '</option>';
1489 }
1490 if (!$isSelFlag && (string)$value !== '') {
1491 $opt[] = '<option value="' . htmlspecialchars($value) . '" selected="selected">'
1492 . htmlspecialchars(('[\'' . $value . '\']')) . '</option>';
1493 }
1494 return '<select name="' . $prefix . '">' . implode('', $opt) . '</select>';
1495 }
1496
1497 /**
1498 * Returns a selector-box with TCA tables
1499 *
1500 * @param string $prefix Form element name prefix
1501 * @param array $value The current values selected
1502 * @param string $excludeList Table names (and the string "_ALL") to exclude. Comma list
1503 * @return string HTML select element
1504 */
1505 public function tableSelector($prefix, $value, $excludeList = '')
1506 {
1507 $optValues = array();
1508 if (!GeneralUtility::inList($excludeList, '_ALL')) {
1509 $optValues['_ALL'] = '[' . $this->lang->getLL('ALL_tables') . ']';
1510 }
1511 foreach ($GLOBALS['TCA'] as $table => $_) {
1512 if ($this->getBackendUser()->check('tables_select', $table) && !GeneralUtility::inList($excludeList, $table)) {
1513 $optValues[$table] = $table;
1514 }
1515 }
1516 // make box:
1517 $opt = array();
1518 $opt[] = '<option value=""></option>';
1519 $sel = '';
1520 foreach ($optValues as $k => $v) {
1521 if (is_array($value)) {
1522 $sel = in_array($k, $value) ? ' selected="selected"' : '';
1523 }
1524 $opt[] = '<option value="' . htmlspecialchars($k) . '"' . $sel . '>' . htmlspecialchars($v) . '</option>';
1525 }
1526 return '<select name="' . $prefix . '[]" multiple="multiple" size="'
1527 . MathUtility::forceIntegerInRange(count($opt), 5, 10) . '">' . implode('', $opt) . '</select>';
1528 }
1529
1530 /**
1531 * Returns a selector-box with loaded extension keys
1532 *
1533 * @param string $prefix Form element name prefix
1534 * @param array $value The current values selected
1535 * @return string HTML select element
1536 */
1537 public function extensionSelector($prefix, $value)
1538 {
1539 $loadedExtensions = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getLoadedExtensionListArray();
1540
1541 // make box:
1542 $opt = array();
1543 $opt[] = '<option value=""></option>';
1544 foreach ($loadedExtensions as $extensionKey) {
1545 $sel = '';
1546 if (is_array($value)) {
1547 $sel = in_array($extensionKey, $value) ? ' selected="selected"' : '';
1548 }
1549 $opt[] = '<option value="' . htmlspecialchars($extensionKey) . '"' . $sel . '>'
1550 . htmlspecialchars($extensionKey) . '</option>';
1551 }
1552 return '<select name="' . $prefix . '[]" multiple="multiple" size="'
1553 . MathUtility::forceIntegerInRange(count($opt), 5, 10) . '">' . implode('', $opt) . '</select>';
1554 }
1555
1556 /**
1557 * Filter page IDs by traversing exclude array, finding all
1558 * excluded pages (if any) and making an AND NOT IN statement for the select clause.
1559 *
1560 * @param array $exclude Exclude array from import/export object.
1561 * @return string AND where clause part to filter out page uids.
1562 */
1563 public function filterPageIds($exclude)
1564 {
1565 // Get keys:
1566 $exclude = array_keys($exclude);
1567 // Traverse
1568 $pageIds = array();
1569 foreach ($exclude as $element) {
1570 list($table, $uid) = explode(':', $element);
1571 if ($table === 'pages') {
1572 $pageIds[] = (int)$uid;
1573 }
1574 }
1575 // Add to clause:
1576 if (!empty($pageIds)) {
1577 return ' AND uid NOT IN (' . implode(',', $pageIds) . ')';
1578 }
1579 return '';
1580 }
1581
1582 /**
1583 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
1584 */
1585 protected function getBackendUser()
1586 {
1587 return $GLOBALS['BE_USER'];
1588 }
1589
1590 /**
1591 * @return DatabaseConnection
1592 */
1593 protected function getDatabaseConnection()
1594 {
1595 return $GLOBALS['TYPO3_DB'];
1596 }
1597
1598 /**
1599 * @return LanguageService
1600 */
1601 protected function getLanguageService()
1602 {
1603 return $GLOBALS['LANG'];
1604 }
1605
1606 /**
1607 * Gets thumbnail files.
1608 *
1609 * @throws \InvalidArgumentException
1610 * @return array|\TYPO3\CMS\Core\Resource\File[]
1611 */
1612 protected function getThumbnailFiles()
1613 {
1614 $thumbnailFiles = array();
1615 $defaultTemporaryFolder = $this->getDefaultImportExportFolder();
1616
1617 if ($defaultTemporaryFolder === null) {
1618 return $thumbnailFiles;
1619 }
1620
1621 /** @var $filter \TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter */
1622 $filter = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter::class);
1623 $filter->setAllowedFileExtensions(array('png', 'gif', 'jpg'));
1624 $defaultTemporaryFolder->getStorage()->addFileAndFolderNameFilter(array($filter, 'filterFileList'));
1625 $thumbnailFiles = $defaultTemporaryFolder->getFiles();
1626
1627 return $thumbnailFiles;
1628 }
1629
1630 /**
1631 * Gets all export files.
1632 *
1633 * @throws \InvalidArgumentException
1634 * @return array|\TYPO3\CMS\Core\Resource\File[]
1635 */
1636 protected function getExportFiles()
1637 {
1638 $exportFiles = array();
1639
1640 $folder = $this->getDefaultImportExportFolder();
1641 if ($folder !== null) {
1642
1643 /** @var $filter \TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter */
1644 $filter = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter::class);
1645 $filter->setAllowedFileExtensions(array('t3d', 'xml'));
1646 $folder->getStorage()->addFileAndFolderNameFilter(array($filter, 'filterFileList'));
1647
1648 $exportFiles = $folder->getFiles();
1649 }
1650
1651 return $exportFiles;
1652 }
1653
1654 /**
1655 * Gets a file by combined identifier.
1656 *
1657 * @param string $combinedIdentifier
1658 * @return NULL|\TYPO3\CMS\Core\Resource\File
1659 */
1660 protected function getFile($combinedIdentifier)
1661 {
1662 try {
1663 $file = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->getFileObjectFromCombinedIdentifier($combinedIdentifier);
1664 } catch (\Exception $exception) {
1665 $file = null;
1666 }
1667
1668 return $file;
1669 }
1670 }