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