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