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