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