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