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