More work on import/export + removal of "lower" range limit for endtimes on core...
[Packages/TYPO3.CMS.git] / typo3 / sysext / impexp / app / index.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2004 Kasper Skaarhoj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Import / Export module
29 *
30 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
31 */
32 /**
33 * [CLASS/FUNCTION INDEX of SCRIPT]
34 *
35 *
36 *
37 * 136: class localPageTree extends t3lib_browseTree
38 * 143: function localPageTree()
39 * 154: function wrapTitle($title,$v)
40 * 167: function PM_ATagWrap($icon,$cmd,$bMark='')
41 * 178: function wrapIcon($icon,$row)
42 * 187: function permsC()
43 * 197: function ext_tree($pid)
44 *
45 *
46 * 278: class SC_mod_tools_log_index extends t3lib_SCbase
47 * 287: function main()
48 * 339: function printContent()
49 *
50 * SECTION: EXPORT FUNCTIONS
51 * 367: function exportData($inData)
52 * 641: function addRecordsForPid($k, $tables, $maxNumber)
53 * 667: function exec_listQueryPid($table,$pid,$limit)
54 * 695: function makeConfigurationForm($inData, &$row)
55 * 859: function makeAdvancedOptionsForm($inData, &$row)
56 * 906: function makeSaveForm($inData, &$row)
57 *
58 * SECTION: IMPORT FUNCTIONS
59 * 1036: function importData($inData)
60 *
61 * SECTION: Preset functions
62 * 1314: function processPresets(&$inData)
63 * 1411: function getPreset($uid)
64 *
65 * SECTION: Helper functions
66 * 1437: function userTempFolder()
67 * 1453: function userSaveFolder()
68 * 1477: function checkUploadOfThumbnail(&$inData)
69 * 1512: function renderSelectBox($prefix,$value,$optValues)
70 * 1535: function tableSelector($prefix,$value,$excludeList='')
71 * 1570: function extensionSelector($prefix,$value)
72 *
73 * TOTAL FUNCTIONS: 23
74 * (This index is automatically created/updated by the extension "extdeveval")
75 *
76 */
77 /**
78 * IMPORTING DATA:
79 *
80 * Incoming array has syntax:
81 * GETvar 'id' = import page id (must be readable)
82 *
83 * file = (pointing to filename relative to PATH_site)
84 *
85 *
86 *
87 * [all relation fields are clear, but not files]
88 * - page-tree is written first
89 * - then remaining pages (to the root of import)
90 * - then all other records are written either to related included pages or if not found to import-root (should be a sysFolder in most cases)
91 * - then all internal relations are set and non-existing relations removed, relations to static tables preserved.
92 *
93 * EXPORTING DATA:
94 *
95 * Incoming array has syntax:
96 *
97 * file[] = file
98 * dir[] = dir
99 * list[] = table:pid
100 * record[] = table:uid
101 *
102 * pagetree[id] = (single id)
103 * pagetree[levels]=1,2,3, -1 = currently unpacked tree, -2 = only tables on page
104 * pagetree[tables][]=table/_ALL
105 *
106 * external_ref[tables][]=table/_ALL
107 */
108
109
110 unset($MCONF);
111 require ('conf.php');
112 require ($BACK_PATH.'init.php');
113 require ($BACK_PATH.'template.php');
114 $LANG->includeLLFile('EXT:impexp/app/locallang.php');
115 require_once (PATH_t3lib.'class.t3lib_scbase.php');
116 require_once (t3lib_extMgm::extPath('impexp').'class.tx_impexp.php');
117 require_once (PATH_t3lib.'class.t3lib_browsetree.php');
118 require_once (PATH_t3lib.'class.t3lib_pagetree.php');
119
120 require_once (PATH_t3lib.'class.t3lib_basicfilefunc.php');
121 require_once (PATH_t3lib.'class.t3lib_extfilefunc.php');
122
123 t3lib_extMgm::isLoaded('impexp',1);
124
125
126
127
128
129 /**
130 * Extension of the page tree class. Used to get the tree of pages to export.
131 *
132 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
133 * @package TYPO3
134 * @subpackage tx_impexp
135 */
136 class localPageTree extends t3lib_browseTree {
137
138 /**
139 * Initialization
140 *
141 * @return void
142 */
143 function localPageTree() {
144 $this->init();
145 }
146
147 /**
148 * Wrapping title from page tree.
149 *
150 * @param string Title to wrap
151 * @param mixed (See parent class)
152 * @return string Wrapped title
153 */
154 function wrapTitle($title,$v) {
155 $title = (!strcmp(trim($title),'')) ? '<em>['.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.no_title',1).']</em>' : htmlspecialchars($title);
156 return $title;
157 }
158
159 /**
160 * Wrapping Plus/Minus icon
161 *
162 * @param string Icon HTML
163 * @param mixed (See parent class)
164 * @param mixed (See parent class)
165 * @return string Icon HTML
166 */
167 function PM_ATagWrap($icon,$cmd,$bMark='') {
168 return $icon;
169 }
170
171 /**
172 * Wrapping Icon
173 *
174 * @param string Icon HTML
175 * @param array Record row (page)
176 * @return string Icon HTML
177 */
178 function wrapIcon($icon,$row) {
179 return $icon;
180 }
181
182 /**
183 * Select permissions
184 *
185 * @return string SQL where clause
186 */
187 function permsC() {
188 return $this->BE_USER->getPagePermsClause(1);
189 }
190
191 /**
192 * Tree rendering
193 *
194 * @param integer PID value
195 * @param string Additional where clause
196 * @return array Array of tree elements
197 */
198 function ext_tree($pid, $clause='') {
199
200 // Initialize:
201 $this->init(' AND '.$this->permsC().$clause);
202
203 // Get stored tree structure:
204 $this->stored = unserialize($this->BE_USER->uc['browseTrees']['browsePages']);
205
206 // PM action:
207 $PM = t3lib_div::intExplode('_',t3lib_div::_GP('PM'));
208
209 // traverse mounts:
210 $titleLen = intval($this->BE_USER->uc['titleLen']);
211 $treeArr = array();
212
213 $idx = 0;
214
215 // Set first:
216 $this->bank = $idx;
217 $isOpen = $this->stored[$idx][$pid] || $this->expandFirst;
218
219 $curIds = $this->ids; // save ids
220 $this->reset();
221 $this->ids = $curIds;
222
223 // Set PM icon:
224 $cmd = $this->bank.'_'.($isOpen?'0_':'1_').$pid;
225 $icon = '<img'.t3lib_iconWorks::skinImg($this->backPath,'t3lib/gfx/ol/'.($isOpen?'minus':'plus').'only.gif','width="18" height="16"').' align="top" alt="" />';
226 $firstHtml = $this->PM_ATagWrap($icon,$cmd);
227
228 if ($pid>0) {
229 $rootRec = t3lib_befunc::getRecord('pages',$pid);
230 $firstHtml.= $this->wrapIcon(t3lib_iconWorks::getIconImage('pages',$rootRec,$this->backPath,'align="top"'),$rootRec);
231 } else {
232 $rootRec = array(
233 'title' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'],
234 'uid' => 0
235 );
236 $firstHtml.= $this->wrapIcon('<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/i/_icon_website.gif','width="18" height="16"').' align="top" alt="" />',$rootRec);
237 }
238 $this->tree[] = array('HTML'=>$firstHtml, 'row'=>$rootRec);
239 if ($isOpen) {
240 // Set depth:
241 $depthD = '<img'.t3lib_iconWorks::skinImg($this->backPath,'t3lib/gfx/ol/blank.gif','width="18" height="16"').' align="top" alt="" />';
242 if ($this->addSelfId) $this->ids[] = $pid;
243 $this->getTree($pid,999,$depthD);
244
245 $idH = array();
246 $idH[$pid]['uid'] = $pid;
247 if (count($this->buffer_idH)) $idH[$pid]['subrow'] = $this->buffer_idH;
248 $this->buffer_idH = $idH;
249
250 }
251
252 // Add tree:
253 $treeArr = array_merge($treeArr,$this->tree);
254
255 return $treeArr;
256 }
257 }
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272 /**
273 * Main script class for the Import / Export facility
274 *
275 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
276 * @package TYPO3
277 * @subpackage tx_impexp
278 */
279 class SC_mod_tools_log_index extends t3lib_SCbase {
280
281 var $pageinfo; // array containing the current page.
282
283 /**
284 * Main module function
285 *
286 * @return void
287 */
288 function main() {
289 global $BE_USER,$LANG,$BACK_PATH;
290
291 // Start document template object:
292 $this->doc = t3lib_div::makeInstance('mediumDoc');
293 $this->doc->backPath = $BACK_PATH;
294 $this->doc->docType = 'xhtml_trans';
295
296 // JavaScript
297 $this->doc->JScode = $this->doc->wrapScriptTags('
298 script_ended = 0;
299 function jumpToUrl(URL) { //
300 document.location = URL;
301 }
302 ');
303
304 // Set up JS for dynamic tab menu
305 $this->doc->JScode .= $this->doc->getDynTabMenuJScode();
306
307 $this->doc->postCode = $this->doc->wrapScriptTags('
308 script_ended = 1;
309 if (top.fsMod) top.fsMod.recentIds["web"] = '.intval($this->id).';
310 ');
311 $this->doc->form = '<form action="index.php" method="post" enctype="'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'].'"><input type="hidden" name="id" value="'.$this->id.'" />';
312
313 $this->content.= $this->doc->startPage($LANG->getLL('title'));
314 $this->content.= $this->doc->header($LANG->getLL('title'));
315 $this->content.= $this->doc->spacer(5);
316
317 // Input data grabbed:
318 $inData = t3lib_div::_GP('tx_impexp');
319
320 $this->checkUpload();
321
322 switch((string)$inData['action']) {
323 case 'export':
324
325 // Finally: If upload went well, set the new file as the thumbnail in the $inData array:
326 if (is_object($this->fileProcessor) && $this->fileProcessor->internalUploadMap[1]) {
327 $inData['meta']['thumbnail'] = md5($this->fileProcessor->internalUploadMap[1]);
328 }
329
330 // Call export interface
331 $this->exportData($inData);
332 break;
333 case 'import':
334
335 // Finally: If upload went well, set the new file as the import file:
336 if (is_object($this->fileProcessor) && $this->fileProcessor->internalUploadMap[1]) {
337 $fI = pathinfo($this->fileProcessor->internalUploadMap[1]);
338 if (t3lib_div::inList('t3d,xml',strtolower($fI['extension']))) { // Only allowed extensions....
339 $inData['file'] = $this->fileProcessor->internalUploadMap[1];
340 }
341 }
342
343 // Call import interface:
344 $this->importData($inData);
345 break;
346 }
347
348 if ($BE_USER->mayMakeShortcut()) {
349 $this->content.=$this->doc->spacer(20).$this->doc->section('',$this->doc->makeShortcutIcon('tx_impexp','',$this->MCONF['name']));
350 }
351 }
352
353 /**
354 * Print the content
355 *
356 * @return void
357 */
358 function printContent() {
359
360 $this->content.= $this->doc->spacer(20);
361 $this->content.= $this->doc->endPage();
362 echo $this->content;
363 }
364
365
366
367
368
369
370
371
372
373
374 /**************************
375 *
376 * EXPORT FUNCTIONS
377 *
378 **************************/
379
380 /**
381 * Export part of module
382 *
383 * @param array Content of POST VAR tx_impexp[]..
384 * @return void Setting content in $this->content
385 */
386 function exportData($inData) {
387 global $TCA, $LANG;
388
389 // BUILDING EXPORT DATA:
390
391 // Processing of InData array values:
392 $inData['pagetree']['maxNumber'] = t3lib_div::intInRange($inData['pagetree']['maxNumber'],1,10000,100);
393 $inData['listCfg']['maxNumber'] = t3lib_div::intInRange($inData['listCfg']['maxNumber'],1,10000,100);
394 $inData['maxFileSize'] = t3lib_div::intInRange($inData['maxFileSize'],1,10000,1000);
395 $inData['filename'] = trim(ereg_replace('[^[:alnum:]./_-]*','',ereg_replace('\.(t3d|xml)$','',$inData['filename'])));
396 if (strlen($inData['filename'])) {
397 $inData['filename'].= $inData['filetype']=='xml' ? '.xml' : '.t3d';
398 }
399
400 // Set exclude fields in export object:
401 if (!is_array($inData['exclude'])) {
402 $inData['exclude'] = array();
403 }
404
405
406 // Saving/Loading/Deleting presets:
407 $this->processPresets($inData);
408
409 // Create export object and configure it:
410 $this->export = t3lib_div::makeInstance('tx_impexp');
411 $this->export->init(0,'export');
412 $this->export->setCharset($LANG->charSet);
413
414 $this->export->maxFileSize = $inData['maxFileSize']*1024;
415 $this->export->excludeMap = (array)$inData['exclude'];
416 $this->export->softrefCfg = (array)$inData['softrefCfg'];
417 $this->export->extensionDependencies = (array)$inData['extension_dep'];
418 $this->export->showStaticRelations = $inData['showStaticRelations'];
419
420 $this->export->includeExtFileResources = !$inData['excludeHTMLfileResources'];
421 #debug($inData);
422 // Static tables:
423 if (is_array($inData['external_static']['tables'])) {
424 $this->export->relStaticTables = $inData['external_static']['tables'];
425 }
426
427 // Configure which tables external relations are included for:
428 if (is_array($inData['external_ref']['tables'])) {
429 $this->export->relOnlyTables = $inData['external_ref']['tables'];
430 }
431 $this->export->setHeaderBasics();
432
433 // Meta data setting:
434 $this->export->setMetaData(
435 $inData['meta']['title'],
436 $inData['meta']['description'],
437 $inData['meta']['notes'],
438 $GLOBALS['BE_USER']->user['username'],
439 $GLOBALS['BE_USER']->user['realName'],
440 $GLOBALS['BE_USER']->user['email']
441 );
442 if ($inData['meta']['thumbnail']) {
443 $tempDir = $this->userTempFolder();
444 if ($tempDir) {
445 $thumbnails = t3lib_div::getFilesInDir($tempDir,'png,gif,jpg',1);
446 $theThumb = $thumbnails[$inData['meta']['thumbnail']];
447 if ($theThumb) {
448 $this->export->addThumbnail($theThumb);
449 }
450 }
451 }
452
453
454 // Configure which records to export
455 if (is_array($inData['record'])) {
456 foreach($inData['record'] as $ref) {
457 $rParts = explode(':',$ref);
458 $this->export->export_addRecord($rParts[0],t3lib_BEfunc::getRecord($rParts[0],$rParts[1]));
459 }
460 }
461
462 // Configure which tables to export
463 if (is_array($inData['list'])) {
464 foreach($inData['list'] as $ref) {
465 $rParts = explode(':',$ref);
466 if ($GLOBALS['BE_USER']->check('tables_select',$rParts[0])) {
467 $res = $this->exec_listQueryPid($rParts[0],$rParts[1],t3lib_div::intInRange($inData['listCfg']['maxNumber'],1));
468 while($subTrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
469 $this->export->export_addRecord($rParts[0],$subTrow);
470 }
471 }
472 }
473 }
474
475 // Pagetree
476 if (isset($inData['pagetree']['id'])) {
477 if ($inData['pagetree']['levels']==-1) { // Based on click-expandable tree
478 $pagetree = t3lib_div::makeInstance('localPageTree');
479
480 $tree = $pagetree->ext_tree($inData['pagetree']['id'],$this->filterPageIds($this->export->excludeMap));
481 $this->treeHTML = $pagetree->printTree($tree);
482
483 $idH = $pagetree->buffer_idH;
484 # debug($pagetree->buffer_idH);
485 } elseif ($inData['pagetree']['levels']==-2) { // Only tables on page
486 $this->addRecordsForPid($inData['pagetree']['id'],$inData['pagetree']['tables'],$inData['pagetree']['maxNumber']);
487 } else { // Based on depth
488 // Drawing tree:
489 // If the ID is zero, export root
490 if (!$inData['pagetree']['id'] && $GLOBALS['BE_USER']->isAdmin()) {
491 $sPage = array(
492 'uid' => 0,
493 'title' => 'ROOT'
494 );
495 } else {
496 $sPage = t3lib_BEfunc::getRecord('pages',$inData['pagetree']['id'],'*',' AND '.$this->perms_clause);
497 }
498 if (is_array($sPage)) {
499 $pid = $inData['pagetree']['id'];
500 $tree = t3lib_div::makeInstance('t3lib_pageTree');
501 $tree->init('AND '.$this->perms_clause.$this->filterPageIds($this->export->excludeMap));
502
503 $HTML = t3lib_iconWorks::getIconImage('pages',$sPage,$GLOBALS['BACK_PATH'],'align="top"');
504 $tree->tree[] = Array('row'=>$sPage,'HTML'=>$HTML);
505 $tree->buffer_idH = array();
506 if ($inData['pagetree']['levels']>0) {
507 $tree->getTree($pid,$inData['pagetree']['levels'],'');
508 }
509
510 $idH = array();
511 $idH[$pid]['uid'] = $pid;
512 if (count($tree->buffer_idH)) {
513 $idH[$pid]['subrow'] = $tree->buffer_idH;
514 }
515
516 $pagetree = t3lib_div::makeInstance('localPageTree');
517 $this->treeHTML = $pagetree->printTree($tree->tree);
518 #debug($idH);
519 }
520 }
521 // 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...)
522 if (is_array($idH)) {
523 $flatList = $this->export->setPageTree($idH); // Sets the pagetree and gets a 1-dim array in return with the pages (in correct submission order BTW...)
524 reset($flatList);
525 while(list($k)=each($flatList)) {
526 $this->export->export_addRecord('pages',t3lib_BEfunc::getRecord('pages',$k));
527 $this->addRecordsForPid($k,$inData['pagetree']['tables'],$inData['pagetree']['maxNumber']);
528 }
529 }
530 }
531
532 // After adding ALL records we set relations:
533 # debug($this->export->relOnlyTables);
534 # if (count($this->export->relOnlyTables)) {
535 for($a=0;$a<10;$a++) {
536 $addR = $this->export->export_addDBRelations($a);
537 if (!count($addR)) break;
538 }
539 # }
540
541 // Finally files are added:
542 $this->export->export_addFilesFromRelations(); // MUST be after the DBrelations are set so that files from ALL added records are included!
543 #debug($this->export->dat['header']);
544 // If the download button is clicked, return file
545 if ($inData['download_export'] || $inData['save_export']) {
546 switch((string)$inData['filetype']) {
547 case 'xml':
548 $out = $this->export->compileMemoryToFileContent('xml');
549 $fExt = '.xml';
550 break;
551 case 't3d':
552 $this->export->dontCompress = 1;
553 default:
554 $out = $this->export->compileMemoryToFileContent();
555 $fExt = ($this->export->doOutputCompress()?'-z':'').'.t3d';
556 break;
557 }
558
559 // Filename:
560 $dlFile = $inData['filename'] ? $inData['filename'] : 'T3D_'.substr(ereg_replace('[^[:alnum:]_]','-',$inData['download_export_name']),0,20).'_'.date('d-m-H-i-s').$fExt;
561
562 // Export for download:
563 if ($inData['download_export']) {
564 $mimeType = 'application/octet-stream';
565 Header('Content-Type: '.$mimeType);
566 Header('Content-Length: '.strlen($out));
567 Header('Content-Disposition: attachment; filename='.basename($dlFile));
568
569 echo $out;
570 exit;
571 }
572
573 // Export by saving:
574 if ($inData['save_export']) {
575 $savePath = $this->userSaveFolder();
576 $fullName = $savePath.$dlFile;
577
578 if (t3lib_div::isAllowedAbsPath($savePath) && @is_dir(dirname($fullName)) && t3lib_div::isAllowedAbsPath($fullName)) {
579 t3lib_div::writeFile($fullName, $out);
580 $this->content.= $this->doc->section('SAVED FILE','Saved in "'.substr($savePath.$dlFile,strlen(PATH_site)).'", bytes '.t3lib_div::formatSize(strlen($out)),0,1);
581 } else {
582 $this->content.= $this->doc->section('Problems saving file','Bad path: "'.$fullName.'"',0,1,2);
583 }
584 }
585 }
586
587
588 // OUTPUT to BROWSER:
589 // Now, if we didn't make download file, show configuration form based on export:
590 $menuItems = array();
591
592 // Export configuration
593 $row = array();
594 $this->makeConfigurationForm($inData, $row);
595 $menuItems[] = array(
596 'label' => $LANG->getLL('tableselec_configuration','1'),
597 'content' => '
598 <table border="0" cellpadding="1" cellspacing="1">
599 '.implode('
600 ',$row).'
601 </table>
602 '
603 );
604
605 // File options
606 $row = array();
607 $this->makeSaveForm($inData, $row);
608 $menuItems[] = array(
609 'label' => 'File & Preset',
610 'content' => '
611 <table border="0" cellpadding="1" cellspacing="1">
612 '.implode('
613 ',$row).'
614 </table>
615 '
616 );
617
618 // File options
619 $row = array();
620 $this->makeAdvancedOptionsForm($inData, $row);
621 $menuItems[] = array(
622 'label' => 'Advanced Options',
623 'content' => '
624 <table border="0" cellpadding="1" cellspacing="1">
625 '.implode('
626 ',$row).'
627 </table>
628 '
629 );
630
631 // Generate overview:
632 $overViewContent = $this->export->displayContentOverview();
633
634 // Print errors that might be:
635 $errors = $this->export->printErrorLog();
636 $menuItems[] = array(
637 'label' => 'Messages',
638 'content' => $errors,
639 'stateIcon' => $errors ? 2 : 0
640 );
641
642 // Add hidden fields and create tabs:
643 $content = $this->doc->getDynTabMenu($menuItems,'tx_impexp_export',-1);
644 $content.= '<input type="hidden" name="tx_impexp[action]" value="export" />';
645 $this->content.= $this->doc->section('',$content,0,1);
646
647 // Output Overview:
648 $this->content.= $this->doc->section('Structure to be exported:',$overViewContent,0,1);
649
650 }
651
652 /**
653 * Adds records to the export object for a specific page id.
654 *
655 * @param integer Page id for which to select records to add
656 * @param array Array of table names to select from
657 * @param integer Max amount of records to select
658 * @return void
659 */
660 function addRecordsForPid($k, $tables, $maxNumber) {
661 global $TCA;
662
663 if (is_array($tables)) {
664 reset($TCA);
665 while(list($table)=each($TCA)) {
666 if ($table!='pages' && (in_array($table,$tables) || in_array('_ALL',$tables))) {
667 if ($GLOBALS['BE_USER']->check('tables_select',$table) && !$TCA[$table]['ctrl']['is_static']) {
668 $res = $this->exec_listQueryPid($table,$k,t3lib_div::intInRange($maxNumber,1));
669 while($subTrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
670 $this->export->export_addRecord($table,$subTrow);
671 }
672 }
673 }
674 }
675 }
676 }
677
678 /**
679 * Selects records from table / pid
680 *
681 * @param string Table to select from
682 * @param integer Page ID to select from
683 * @param integer Max number of records to select
684 * @return pointer SQL resource pointer
685 */
686 function exec_listQueryPid($table,$pid,$limit) {
687 global $TCA;
688 $orderBy = $TCA[$table]['ctrl']['sortby'] ? 'ORDER BY '.$TCA[$table]['ctrl']['sortby'] : $TCA[$table]['ctrl']['default_sortby'];
689 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
690 '*',
691 $table,
692 'pid='.intval($pid).
693 t3lib_BEfunc::deleteClause($table),
694 '',
695 $GLOBALS['TYPO3_DB']->stripOrderBy($orderBy),
696 $limit
697 );
698
699 // Warning about hitting limit:
700 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res) == $limit) {
701 $this->content.= $this->doc->section('Max number limit!','An SQL query returned exactly the amount of records specified by the limit value ('.$limit.') - that could indicate an incomplete selection of records! Make sure this is on purpose.',0,1, 2);
702 }
703
704 return $res;
705 }
706
707 /**
708 * Create configuration form
709 *
710 * @param array Form configurat data
711 * @param array Table row accumulation variable. This is filled with table rows.
712 * @return void Sets content in $this->content
713 */
714 function makeConfigurationForm($inData, &$row) {
715
716 $nameSuggestion = '';
717
718 // Page tree export options:
719 if (isset($inData['pagetree']['id'])) {
720
721 $nameSuggestion.= 'tree_PID'.$inData['pagetree']['id'].'_L'.$inData['pagetree']['levels'];
722
723 $row[] = '
724 <tr class="tableheader bgColor5">
725 <td colspan="2">Export pagetree configuration:</td>
726 </tr>';
727
728 $row[] = '
729 <tr class="bgColor4">
730 <td><strong>Page ID:</strong></td>
731 <td>'.htmlspecialchars($inData['pagetree']['id']).
732 '<input type="hidden" value="'.htmlspecialchars($inData['pagetree']['id']).'" name="tx_impexp[pagetree][id]" /></td>
733 </tr>';
734
735 $row[] = '
736 <tr class="bgColor4">
737 <td><strong>Tree:</strong></td>
738 <td>'.($this->treeHTML ? $this->treeHTML : 'No tree exported - only tables on the page.').'</td>
739 </tr>';
740
741 $opt = array(
742 '-2' => 'Tables on this page',
743 '-1' => 'Expanded tree',
744 '0' => 'Only this page',
745 '1' => '1 level',
746 '2' => '2 levels',
747 '3' => '3 levels',
748 '4' => '4 levels',
749 '999' => 'Infinite'
750 );
751 $row[] = '
752 <tr class="bgColor4">
753 <td><strong>Levels:</strong></td>
754 <td>'.$this->renderSelectBox('tx_impexp[pagetree][levels]',$inData['pagetree']['levels'],$opt).'</td>
755 </tr>';
756
757 $row[] = '
758 <tr class="bgColor4">
759 <td><strong>Include tables:</strong></td>
760 <td>'.$this->tableSelector('tx_impexp[pagetree][tables]',$inData['pagetree']['tables'],'pages').'<br/>
761 Max number of records:<br/>
762 <input type="text" name="tx_impexp[pagetree][maxNumber]" value="'.htmlspecialchars($inData['pagetree']['maxNumber']).'"'.$this->doc->formWidth(10).' /><br/>
763 </td>
764 </tr>';
765 }
766
767 // Single record export:
768 if (is_array($inData['record'])) {
769 $row[] = '
770 <tr class="tableheader bgColor5">
771 <td colspan="2">Export single record:</td>
772 </tr>';
773 foreach($inData['record'] as $ref) {
774 $rParts = explode(':', $ref);
775 $tName = $rParts[0];
776 $rUid = $rParts[1];
777 $nameSuggestion.= $tName.'_'.$rUid;
778 $rec = t3lib_BEfunc::getRecord($tName,$rUid);
779
780 $row[] = '
781 <tr class="bgColor4">
782 <td><strong>Record:</strong></td>
783 <td>'.t3lib_iconworks::getIconImage($tName,$rec,$GLOBALS['BACK_PATH'],' align="top"').
784 t3lib_BEfunc::getRecordTitle($tName,$rec,1).
785 '<input type="hidden" name="tx_impexp[record][]" value="'.htmlspecialchars($tName.':'.$rUid).'" /></td>
786 </tr>';
787 }
788 }
789
790 // Single tables/pids:
791 if (is_array($inData['list'])) {
792 $row[] = '
793 <tr class="tableheader bgColor5">
794 <td colspan="2">Export tables from pages:</td>
795 </tr>';
796
797 foreach($inData['list'] as $ref) {
798 $rParts = explode(':', $ref);
799 $tName = $rParts[0];
800
801 if ($GLOBALS['BE_USER']->check('tables_select',$tName)) {
802 $rec = t3lib_BEfunc::getRecord('pages', $rParts[1]);
803 $row[] = '
804 <tr class="bgColor4">
805 <td><strong>Table/Pids:</strong></td>
806 <td>Table "'.$tName.'" from '.t3lib_iconworks::getIconImage('pages',$rec,$GLOBALS['BACK_PATH'],' align="top"').
807 t3lib_BEfunc::getRecordTitle('pages',$rec,1).
808 '<input type="hidden" name="tx_impexp[list][]" value="'.htmlspecialchars($ref).'" /></td>
809 </tr>';
810 }
811 }
812 $row[] = '
813 <tr class="bgColor4">
814 <td>Max number of records:</td>
815 <td>
816 <input type="text" name="tx_impexp[listCfg][maxNumber]" value="'.htmlspecialchars($inData['listCfg']['maxNumber']).'"'.$this->doc->formWidth(10).' /><br/>
817 </td>
818 </tr>';
819 }
820
821
822 $row[] = '
823 <tr class="tableheader bgColor5">
824 <td colspan="2">Relations and Exclusions:</td>
825 </tr>';
826
827 // Add relation selector:
828 $row[] = '
829 <tr class="bgColor4">
830 <td><strong>Include relations to tables:</strong></td>
831 <td>'.$this->tableSelector('tx_impexp[external_ref][tables]',$inData['external_ref']['tables']).'</td>
832 </tr>';
833
834 // Add static relation selector:
835 $row[] = '
836 <tr class="bgColor4">
837 <td><strong>Use static relations for tables:</strong></td>
838 <td>'.$this->tableSelector('tx_impexp[external_static][tables]',$inData['external_static']['tables']).'<br/>
839 Show static relations: <input type="checkbox" name="tx_impexp[showStaticRelations]" value="1"'.($inData['showStaticRelations'] ? ' checked="checked"' : '').' />
840 </td>
841 </tr>';
842
843 // Exclude:
844 $excludeHiddenFields = '';
845 if (is_array($inData['exclude'])) {
846 foreach($inData['exclude'] as $key => $value) {
847 $excludeHiddenFields.= '<input type="hidden" name="tx_impexp[exclude]['.$key.']" value="1" />';
848 }
849 }
850 $row[] = '
851 <tr class="bgColor4">
852 <td><strong>Exclude elements:</strong></td>
853 <td>'.$excludeHiddenFields.'
854 '.(count($inData['exclude']) ? '<em>'.implode(', ',array_keys($inData['exclude'])).'</em><hr/>Clear all exclusions: <input type="checkbox" name="tx_impexp[exclude]" value="1" />' : 'No excluded elements yet. Exclude by setting checkboxes below in the element display.').'
855 </td>
856 </tr>';
857
858
859 // Add buttons:
860 $row[] = '
861 <tr class="bgColor4">
862 <td>&nbsp;</td>
863 <td>
864 <input type="submit" value="Update" />
865 <input type="hidden" name="tx_impexp[download_export_name]" value="'.substr($nameSuggestion,0,30).'" />
866 </td>
867 </tr>';
868
869 }
870
871 /**
872 * Create advanced options form
873 *
874 * @param array Form configurat data
875 * @param array Table row accumulation variable. This is filled with table rows.
876 * @return void Sets content in $this->content
877 */
878 function makeAdvancedOptionsForm($inData, &$row) {
879
880 // Soft references
881 $row[] = '
882 <tr class="tableheader bgColor5">
883 <td colspan="2">Soft References:</td>
884 </tr>';
885 $row[] = '
886 <tr class="bgColor4">
887 <td><strong>Exclude HTML/CSS file resources:</strong></td>
888 <td><input type="checkbox" name="tx_impexp[excludeHTMLfileResources]" value="1"'.($inData['excludeHTMLfileResources'] ? ' checked="checked"' : '').' /></td>
889 </tr>';
890
891
892 // Extensions
893 $row[] = '
894 <tr class="tableheader bgColor5">
895 <td colspan="2">Extension dependencies:</td>
896 </tr>';
897 $row[] = '
898 <tr class="bgColor4">
899 <td><strong>Select extensions that the exported content depends on:</strong></td>
900 <td>'.$this->extensionSelector('tx_impexp[extension_dep]',$inData['extension_dep']).'</td>
901 </tr>';
902
903
904
905 // Add buttons:
906 $row[] = '
907 <tr class="bgColor4">
908 <td>&nbsp;</td>
909 <td>
910 <input type="submit" value="Update" />
911 <input type="hidden" name="tx_impexp[download_export_name]" value="'.substr($nameSuggestion,0,30).'" />
912 </td>
913 </tr>';
914
915
916 }
917
918 /**
919 * Create configuration form
920 *
921 * @param array Form configurat data
922 * @param array Table row accumulation variable. This is filled with table rows.
923 * @return void Sets content in $this->content
924 */
925 function makeSaveForm($inData, &$row) {
926
927 // Presets:
928 $row[] = '
929 <tr class="tableheader bgColor5">
930 <td colspan="2">Presets:</td>
931 </tr>';
932
933 $opt = array('');
934 $presets = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
935 '*',
936 'tx_impexp_presets',
937 '(public>0 || user_uid='.intval($GLOBALS['BE_USER']->user['uid']).')'.
938 ($inData['pagetree']['id'] ? ' AND item_uid='.intval($inData['pagetree']['id']) : '')
939
940 );
941 if (is_array($presets)) {
942 foreach($presets as $presetCfg) {
943 $opt[$presetCfg['uid']] = $presetCfg['title'].' ['.$presetCfg['uid'].']'.
944 ($presetCfg['public'] ? ' [Public]' : '').
945 ($presetCfg['user_uid']===$GLOBALS['BE_USER']->user['uid'] ? ' [Own]' : '');
946 }
947 }
948
949 $row[] = '
950 <tr class="bgColor4">
951 <td><strong>Presets:</strong></td>
952 <td>
953 Select preset:<br/>
954 '.$this->renderSelectBox('preset[select]','',$opt).'
955 <br/>
956 <input type="submit" value="Load" name="preset[load]" />
957 <input type="submit" value="Save" name="preset[save]" onclick="return confirm(\''.htmlspecialchars('Are you sure?').'\');" />
958 <input type="submit" value="Delete" name="preset[delete]" onclick="return confirm(\''.htmlspecialchars('Are you sure?').'\');" />
959 <input type="submit" value="Merge" name="preset[merge]" onclick="return confirm(\''.htmlspecialchars('Are you sure?').'\');" />
960 <br/>
961 Title of new preset:
962 <input type="text" name="tx_impexp[preset][title]" value="'.htmlspecialchars($inData['preset']['title']).'"'.$this->doc->formWidth(30).' /><br/>
963 Public:
964 <input type="checkbox" name="tx_impexp[preset][public]" value="1"'.($inData['preset']['public'] ? ' checked="checked"' : '').' /><br/>
965 </td>
966 </tr>';
967
968 // Output options:
969 $row[] = '
970 <tr class="tableheader bgColor5">
971 <td colspan="2">Output options:</td>
972 </tr>';
973
974 // Meta data:
975 $tempDir = $this->userTempFolder();
976 if ($tempDir) {
977 $thumbnails = t3lib_div::getFilesInDir($tempDir,'png,gif,jpg');
978 array_unshift($thumbnails,'');
979 } else $thumbnails = FALSE;
980 $row[] = '
981 <tr class="bgColor4">
982 <td><strong>Meta data:</strong></td>
983 <td>
984 Title: <br/>
985 <input type="text" name="tx_impexp[meta][title]" value="'.htmlspecialchars($inData['meta']['title']).'"'.$this->doc->formWidth(30).' /><br/>
986 Description: <br/>
987 <input type="text" name="tx_impexp[meta][description]" value="'.htmlspecialchars($inData['meta']['description']).'"'.$this->doc->formWidth(30).' /><br/>
988 Notes: <br/>
989 <textarea name="tx_impexp[meta][notes]"'.$this->doc->formWidth(30,1).'>'.t3lib_div::formatForTextarea($inData['meta']['notes']).'</textarea><br/>
990 '.(is_array($thumbnails) ? '
991 Thumbnail:<br/>
992 '.$this->renderSelectBox('tx_impexp[meta][thumbnail]',$inData['meta']['thumbnail'],$thumbnails).'<br/>
993 '.($inData['meta']['thumbnail'] ? '<img src="'.$this->doc->backPath.'../'.substr($tempDir,strlen(PATH_site)).$thumbnails[$inData['meta']['thumbnail']].'" vspace="5" style="border: solid black 1px;" alt="" /><br/>' : '').'
994 Upload thumbnail:<br/>
995 <input type="file" name="upload_1" '.$this->doc->formWidth(30).' size="30" /><br/>
996 <input type="hidden" name="file[upload][1][target]" value="'.htmlspecialchars($tempDir).'" />
997 <input type="hidden" name="file[upload][1][data]" value="1" /><br />
998 ' : '').'
999 </td>
1000 </tr>';
1001
1002 // Add file options:
1003 $savePath = $this->userSaveFolder();
1004 $opt = array();
1005 if ($this->export->compress) {
1006 $opt['t3d_compressed'] = 'T3D file / compressed';
1007 }
1008 $opt['t3d'] = 'T3D file';
1009 $opt['xml'] = 'XML';
1010 $row[] = '
1011 <tr class="bgColor4">
1012 <td><strong>File format:</strong></td>
1013 <td>'.$this->renderSelectBox('tx_impexp[filetype]',$inData['filetype'],$opt).'<br/>
1014 Max size of files to include (kb):<br/>
1015 <input type="text" name="tx_impexp[maxFileSize]" value="'.htmlspecialchars($inData['maxFileSize']).'"'.$this->doc->formWidth(10).' /><br/>
1016 '.($savePath ? 'Filename (saved in "'.substr($savePath,strlen(PATH_site)).'"):<br/>
1017 <input type="text" name="tx_impexp[filename]" value="'.htmlspecialchars($inData['filename']).'"'.$this->doc->formWidth(30).' /><br/>' : '').'
1018 </td>
1019 </tr>';
1020
1021
1022 // Add buttons:
1023 $row[] = '
1024 <tr class="bgColor4">
1025 <td>&nbsp;</td>
1026 <td><input type="submit" value="Update" /> - <input type="submit" value="Download export" name="tx_impexp[download_export]" />'.
1027 ($savePath ? ' - <input type="submit" value="Save to filename" name="tx_impexp[save_export]" />' : '').'</td>
1028 </tr>';
1029 }
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043 /**************************
1044 *
1045 * IMPORT FUNCTIONS
1046 *
1047 **************************/
1048
1049 /**
1050 * Import part of module
1051 *
1052 * @param array Content of POST VAR tx_impexp[]..
1053 * @return void Setting content in $this->content
1054 */
1055 function importData($inData) {
1056 global $TCA,$LANG,$BE_USER;
1057
1058 $this->pageinfo = t3lib_BEfunc::readPageAccess($this->id,$this->perms_clause);
1059 $access = is_array($this->pageinfo) ? 1 : 0;
1060
1061 if (($this->id && $access) || ($BE_USER->user['admin'] && !$this->id)) {
1062 if ($BE_USER->user['admin'] && !$this->id) {
1063 $this->pageinfo=array('title' => '[root-level]','uid'=>0,'pid'=>0);
1064 }
1065
1066 $headerSection = $this->doc->getHeader('pages',$this->pageinfo,$this->pageinfo['_thePath']).'<br />'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.path').': '.t3lib_div::fixed_lgd_cs($this->pageinfo['_thePath'],-50);
1067 $this->content.= $this->doc->section('',$headerSection);
1068
1069 if ($inData['new_import']) {
1070 unset($inData['import_mode']);
1071 }
1072
1073 $import = t3lib_div::makeInstance('tx_impexp');
1074 $import->init(0,'import');
1075 $import->update = $inData['do_update'];
1076 $import->import_mode = $inData['import_mode'];
1077 $import->enableLogging = $inData['enableLogging'];
1078 $import->global_ignore_pid = $inData['global_ignore_pid'];
1079 $import->showDiff = !$inData['notShowDiff'];
1080 $import->allowPHPScripts = $inData['allowPHPScripts'];
1081 $import->softrefInputValues = $inData['softrefInputValues'];
1082
1083
1084 // OUTPUT creation:
1085 $menuItems = array();
1086
1087
1088 // Make input selector:
1089 $path = 'fileadmin/'; // must have trailing slash.
1090 $filesInDir = t3lib_div::getFilesInDir(PATH_site.$path,'t3d,xml',1,1);
1091 if (is_dir(PATH_site.$path.'export/')) {
1092 $filesInDir = array_merge($filesInDir, t3lib_div::getFilesInDir(PATH_site.$path.'export/','t3d,xml',1,1));
1093 }
1094 $tempFolder = $this->userTempFolder();
1095 if ($tempFolder) {
1096 $temp_filesInDir = t3lib_div::getFilesInDir($tempFolder,'t3d,xml',1,1);
1097 $filesInDir = array_merge($filesInDir, $temp_filesInDir);
1098 }
1099
1100 // Configuration
1101 $row = array();
1102 $opt = array('');
1103 foreach($filesInDir as $file) {
1104 $opt[$file] = substr($file,strlen(PATH_site));
1105 }
1106
1107 $row[] = '<tr class="bgColor5">
1108 <td colspan="2"><strong>Select file to import:</strong></td>
1109 </tr>';
1110
1111 $row[] = '<tr class="bgColor4">
1112 <td><strong>File:</strong></td>
1113 <td>'.
1114 $this->renderSelectBox('tx_impexp[file]',$inData['file'],$opt).'<br />(From path: '.$path.')'.
1115 (!$import->compress ? '<br /><span class="typo3-red">NOTE: No decompressor available for compressed files!</span>':'').
1116 '</td>
1117 </tr>';
1118
1119 $row[] = '<tr class="bgColor5">
1120 <td colspan="2"><strong>Import Options:</strong></td>
1121 </tr>';
1122
1123 $row[] = '<tr class="bgColor4">
1124 <td><strong>Update:</strong></td>
1125 <td>
1126 <input type="checkbox" name="tx_impexp[do_update]" value="1"'.($inData['do_update'] ? ' checked="checked"' : '').' />
1127 Update records<br/>
1128 <em>(This option requires that the structure you import already exists on this server and only needs to be updated with new content!)</em>'.
1129 ($inData['do_update'] ?
1130 ' <hr/>
1131 <input type="checkbox" name="tx_impexp[global_ignore_pid]" value="1"'.($inData['global_ignore_pid'] ? ' checked="checked"' : '').' />
1132 Ignore PID differences globally<br/>
1133 <em>(If you set this option, the position of updated elements will not be updated to match the structure of the input file.)</em>
1134
1135 ' : ''
1136 ).'</td>
1137 </tr>';
1138
1139 $row[] = '<tr class="bgColor4">
1140 <td><strong>Options:</strong></td>
1141 <td>
1142 <input type="checkbox" name="tx_impexp[notShowDiff]" value="1"'.($inData['notShowDiff'] ? ' checked="checked"' : '').' />
1143 Do not show differences in records<br/>
1144 <em>(Green values are from the import file, red values from the current database record and black values are similar in both versions.)</em>
1145 <br/><br/>
1146
1147 '.($GLOBALS['BE_USER']->isAdmin() ? '
1148 <input type="checkbox" name="tx_impexp[allowPHPScripts]" value="1"'.($inData['allowPHPScripts'] ? ' checked="checked"' : '').' />
1149 Allow to write banned file extensions (eg. PHP scripts), if any<br/>' : '').'
1150 </td>
1151 </tr>';
1152
1153 $row[] = '<tr class="bgColor4">
1154 <td><strong>Action:</strong></td>
1155 <td>'.
1156 (!$inData['import_file'] ? '<input type="submit" value="Preview" />'.($inData['file'] ? ' - <input type="submit" value="'.($inData['do_update']?'Update':'Import').'" name="tx_impexp[import_file]" onclick="return confirm(\'Are you sure?\');" />':''):'<input type="submit" name="tx_impexp[new_import]" value="New import" />').'
1157 <input type="hidden" name="tx_impexp[action]" value="import" /></td>
1158 </tr>';
1159
1160 $row[] = '<tr class="bgColor4">
1161 <td><strong>Enable logging:</strong></td>
1162 <td>
1163 <input type="checkbox" name="tx_impexp[enableLogging]" value="1"'.($inData['enableLogging'] ? ' checked="checked"' : '').' />
1164 Write individual DB actions during import to the log<br/>
1165 <em>(This is disabled by default since there may be hundred of entries generated.)</em>
1166 </td>
1167 </tr>';
1168
1169 $menuItems[] = array(
1170 'label' => 'Import',
1171 'content' => '
1172 <table border="0" cellpadding="1" cellspacing="1">
1173 '.implode('
1174 ',$row).'
1175 </table>
1176 '
1177 );
1178
1179 // Upload file:
1180 $tempFolder = $this->userTempFolder();
1181 if ($tempFolder) {
1182 $row = array();
1183
1184 $row[] = '<tr class="bgColor5">
1185 <td colspan="2"><strong>Upload file from local computer:</strong></td>
1186 </tr>';
1187
1188 $row[] = '<tr class="bgColor4">
1189 <td>Browse:</td>
1190 <td>
1191
1192 <input type="file" name="upload_1"'.$this->doc->formWidth(35).' size="40" />
1193 <input type="hidden" name="file[upload][1][target]" value="'.htmlspecialchars($tempFolder).'" />
1194 <input type="hidden" name="file[upload][1][data]" value="1" /><br />
1195
1196 <input type="submit" name="submit" value="'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:file_upload.php.submit',1).'" />
1197 <input type="checkbox" name="overwriteExistingFiles" value="1" checked="checked" /> '.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.php:overwriteExistingFiles',1).'
1198 </td>
1199 </tr>';
1200
1201 if (t3lib_div::_POST('file')) {
1202 $row[] = '<tr class="bgColor4">
1203 <td>Upload status:</td>
1204 <td>'.($this->fileProcessor->internalUploadMap[1] ? 'Success: '.substr($this->fileProcessor->internalUploadMap[1],strlen(PATH_site)) : '<span class="typo3-red">Failure: No file uploaded - was it too big? Check system log.</span>').'</td>
1205 </tr>';
1206 }
1207
1208 $menuItems[] = array(
1209 'label' => 'Upload',
1210 'content' => '
1211 <table border="0" cellpadding="1" cellspacing="1">
1212 '.implode('
1213 ',$row).'
1214 </table>
1215 '
1216 );
1217 }
1218
1219
1220 // Perform import or preview depending:
1221 $overviewContent = '';
1222 $inFile = t3lib_div::getFileAbsFileName($inData['file']);
1223 if ($inFile && @is_file($inFile)) {
1224 $trow = array();
1225 if ($import->loadFile($inFile,1)) {
1226
1227 if ($inData['import_file']) {
1228 $import->importData($this->id);
1229 t3lib_BEfunc::getSetUpdateSignal('updatePageTree');
1230 }
1231
1232 $import->display_import_pid_record = $this->pageinfo;
1233 $overviewContent = $import->displayContentOverview();
1234 }
1235
1236 // Meta data output:
1237 $trow[] = '<tr class="bgColor5">
1238 <td colspan="2"><strong>Meta data:</strong></td>
1239 </tr>';
1240
1241 $opt = array('');
1242 foreach($filesInDir as $file) {
1243 $opt[$file] = substr($file,strlen(PATH_site));
1244 }
1245
1246 $trow[] = '<tr class="bgColor4">
1247 <td><strong>Title:</strong></td>
1248 <td width="95%">'.nl2br(htmlspecialchars($import->dat['header']['meta']['title'])).'</td>
1249 </tr>';
1250
1251 $trow[] = '<tr class="bgColor4">
1252 <td><strong>Description:</strong></td>
1253 <td width="95%">'.nl2br(htmlspecialchars($import->dat['header']['meta']['description'])).'</td>
1254 </tr>';
1255
1256 $trow[] = '<tr class="bgColor4">
1257 <td><strong>Notes:</strong></td>
1258 <td width="95%">'.nl2br(htmlspecialchars($import->dat['header']['meta']['notes'])).'</td>
1259 </tr>';
1260
1261 $trow[] = '<tr class="bgColor4">
1262 <td><strong>Packager:</strong></td>
1263 <td width="95%">'.nl2br(htmlspecialchars($import->dat['header']['meta']['packager_name'].' ('.$import->dat['header']['meta']['packager_username'].')')).'<br/>
1264 Email: '.$import->dat['header']['meta']['packager_email'].'</td>
1265 </tr>';
1266
1267 // Thumbnail icon:
1268 if (is_array($import->dat['header']['thumbnail'])) {
1269 $pI = pathinfo($import->dat['header']['thumbnail']['filename']);
1270 if (t3lib_div::inList('gif,jpg,png,jpeg',strtolower($pI['extension']))) {
1271
1272 // Construct filename and write it:
1273 $fileName = PATH_site.
1274 'typo3temp/importthumb.'.$pI['extension'];
1275 t3lib_div::writeFile($fileName, $import->dat['header']['thumbnail']['content']);
1276
1277 // Check that the image really is an image and not a malicious PHP script...
1278 if (getimagesize($fileName)) {
1279 // Create icon tag:
1280 $iconTag = '<img src="'.$this->doc->backPath.'../'.substr($fileName,strlen(PATH_site)).'" '.$import->dat['header']['thumbnail']['imgInfo'][3].' vspace="5" style="border: solid black 1px;" alt="" />';
1281
1282 $trow[] = '<tr class="bgColor4">
1283 <td><strong>Icon:</strong></td>
1284 <td>'.$iconTag.'</td>
1285 </tr>';
1286 } else {
1287 t3lib_div::unlink_tempfile($fileName);
1288 }
1289 }
1290 }
1291
1292 $menuItems[] = array(
1293 'label' => 'Meta data',
1294 'content' => '
1295 <table border="0" cellpadding="1" cellspacing="1">
1296 '.implode('
1297 ',$trow).'
1298 </table>
1299 '
1300 );
1301 }
1302
1303 // Print errors that might be:
1304 $errors = $import->printErrorLog();
1305 $menuItems[] = array(
1306 'label' => 'Messages',
1307 'content' => $errors,
1308 'stateIcon' => $errors ? 2 : 0
1309 );
1310
1311 // Output tabs:
1312 $content = $this->doc->getDynTabMenu($menuItems,'tx_impexp_import',-1);
1313 $this->content.= $this->doc->section('',$content,0,1);
1314
1315
1316 // Print overview:
1317 if ($overviewContent) {
1318 $this->content.= $this->doc->section($inData['import_file'] ? 'Structure has been imported:' : 'Structure to be imported:', $overviewContent, 0, 1);
1319 }
1320 }
1321 }
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335 /****************************
1336 *
1337 * Preset functions
1338 *
1339 ****************************/
1340
1341 /**
1342 * Manipulate presets
1343 *
1344 * @param array In data array, passed by reference!
1345 * @return void
1346 */
1347 function processPresets(&$inData) {
1348
1349 $presetData = t3lib_div::_GP('preset');
1350 $err = FALSE;
1351
1352 // Save preset
1353 if (isset($presetData['save'])) {
1354 $preset = $this->getPreset($presetData['select']);
1355 if (is_array($preset)) { // Update existing
1356 if ($GLOBALS['BE_USER']->isAdmin() || $preset['user_uid'] === $GLOBALS['BE_USER']->user['uid']) {
1357 $fields_values = array(
1358 'public' => $inData['preset']['public'],
1359 'title' => $inData['preset']['title'],
1360 'item_uid' => $inData['pagetree']['id'],
1361 'preset_data' => serialize($inData)
1362 );
1363 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tx_impexp_presets','uid='.intval($preset['uid']),$fields_values);
1364 $msg = 'Preset #'.$preset['uid'].' saved!';
1365 } else {
1366 $msg = 'ERROR: The preset was not saved because you were not the owner of it!';
1367 $err = TRUE;
1368 }
1369 } else { // Insert new:
1370 $fields_values = array(
1371 'user_uid' => $GLOBALS['BE_USER']->user['uid'],
1372 'public' => $inData['preset']['public'],
1373 'title' => $inData['preset']['title'],
1374 'item_uid' => $inData['pagetree']['id'],
1375 'preset_data' => serialize($inData)
1376 );
1377 $GLOBALS['TYPO3_DB']->exec_INSERTquery('tx_impexp_presets',$fields_values);
1378 $msg = 'New preset "'.$inData['preset']['title'].'" is created';
1379 }
1380 }
1381
1382 // Delete preset:
1383 if (isset($presetData['delete'])) {
1384 $preset = $this->getPreset($presetData['select']);
1385 if (is_array($preset)) { // Update existing
1386 if ($GLOBALS['BE_USER']->isAdmin() || $preset['user_uid'] === $GLOBALS['BE_USER']->user['uid']) {
1387 $GLOBALS['TYPO3_DB']->exec_DELETEquery('tx_impexp_presets','uid='.intval($preset['uid']));
1388 $msg = 'Preset #'.$preset['uid'].' deleted!';
1389 } else {
1390 $msg = 'ERROR: You were not the owner of the preset so you could not delete it.';
1391 $err = TRUE;
1392 }
1393 } else {
1394 $msg = 'ERROR: No preset selected for deletion.';
1395 $err = TRUE;
1396 }
1397 }
1398
1399 // Load preset
1400 if (isset($presetData['load']) || isset($presetData['merge'])) {
1401 $preset = $this->getPreset($presetData['select']);
1402 if (is_array($preset)) { // Update existing
1403 $inData_temp = unserialize($preset['preset_data']);
1404 if (is_array($inData_temp)) {
1405 if (isset($presetData['merge'])) {
1406 // Merge records in:
1407 if (is_array($inData_temp['record'])) {
1408 $inData_temp['record'] = array_merge($inData_temp['record'], $inData['record']);
1409 } else $inData_temp['record'] = $inData['record'];
1410 // Merge lists in:
1411 if (is_array($inData_temp['list'])) {
1412 $inData_temp['list'] = array_merge($inData_temp['list'], $inData['list']);
1413 } else $inData_temp['list'] = $inData['list'];
1414 $inData_temp['listCfg'] = $inData['listCfg'];
1415
1416 // Swap:
1417 $inData = $inData_temp;
1418 } else {
1419 $msg = 'Preset #'.$preset['uid'].' loaded!';
1420 $inData = $inData_temp;
1421 }
1422 } else {
1423 $msg = 'ERROR: No configuratio data found in preset record!';
1424 $err = TRUE;
1425 }
1426 } else {
1427 $msg = 'ERROR: No preset selected for loading.';
1428 $err = TRUE;
1429 }
1430 }
1431
1432 // Show message:
1433 if (strlen($msg)) {
1434 $this->content.= $this->doc->section('Presets',$msg,0,1,$err ? 3 : 1);
1435 }
1436 }
1437
1438 /**
1439 * Get single preset record
1440 *
1441 * @param integer Preset record
1442 * @return array Preset record, if any (otherwise false)
1443 */
1444 function getPreset($uid) {
1445 list($preset) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*','tx_impexp_presets','uid='.intval($uid));
1446 return $preset;
1447 }
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459 /****************************
1460 *
1461 * Helper functions
1462 *
1463 ****************************/
1464
1465 /**
1466 * Returns first temporary folder of the user account (from $FILEMOUNTS)
1467 *
1468 * @return string Absolute path to first "_temp_" folder of the current user, otherwise blank.
1469 */
1470 function userTempFolder() {
1471 global $FILEMOUNTS;
1472
1473 foreach($FILEMOUNTS as $filePathInfo) {
1474 $tempFolder = $filePathInfo['path'].'_temp_/';
1475 if (@is_dir($tempFolder)) {
1476 return $tempFolder;
1477 }
1478 }
1479 }
1480
1481 /**
1482 * Returns folder where user can save export files.
1483 *
1484 * @return string Absolute path to folder where export files can be saved.
1485 */
1486 function userSaveFolder() {
1487 global $FILEMOUNTS;
1488
1489 reset($FILEMOUNTS);
1490 $filePathInfo = current($FILEMOUNTS);
1491
1492 if (is_array($filePathInfo)) {
1493 $tempFolder = $filePathInfo['path'].'export/';
1494 if (!@is_dir($tempFolder)) {
1495 $tempFolder = $filePathInfo['path'];
1496 if (!@is_dir($tempFolder)) {
1497 return FALSE;
1498 }
1499 }
1500 return $tempFolder;
1501 }
1502 }
1503
1504 /**
1505 * Check if a file has been uploaded
1506 *
1507 * @return void
1508 */
1509 function checkUpload() {
1510 global $FILEMOUNTS,$TYPO3_CONF_VARS,$BE_USER;
1511
1512 $file = t3lib_div::_GP('file');
1513
1514 // Initializing:
1515 $this->fileProcessor = t3lib_div::makeInstance('t3lib_extFileFunctions');
1516 $this->fileProcessor->init($FILEMOUNTS, $TYPO3_CONF_VARS['BE']['fileExtensions']);
1517 $this->fileProcessor->init_actionPerms($BE_USER->user['fileoper_perms']);
1518 $this->fileProcessor->dontCheckForUnique = t3lib_div::_GP('overwriteExistingFiles') ? 1 : 0;
1519
1520 // Checking referer / executing:
1521 $refInfo = parse_url(t3lib_div::getIndpEnv('HTTP_REFERER'));
1522 $httpHost = t3lib_div::getIndpEnv('TYPO3_HOST_ONLY');
1523 if ($httpHost!=$refInfo['host'] && $this->vC!=$BE_USER->veriCode() && !$TYPO3_CONF_VARS['SYS']['doNotCheckReferer']) {
1524 $this->fileProcessor->writeLog(0,2,1,'Referer host "%s" and server host "%s" did not match!',array($refInfo['host'],$httpHost));
1525 } else {
1526 $this->fileProcessor->start($file);
1527 $this->fileProcessor->processData();
1528 }
1529 }
1530
1531 /**
1532 * Makes a selector-box from optValues
1533 *
1534 * @param string Form element name
1535 * @param string Current value
1536 * @param array Options to display (key/value pairs)
1537 * @return string HTML select element
1538 */
1539 function renderSelectBox($prefix,$value,$optValues) {
1540 $opt = array();
1541 $isSelFlag = 0;
1542 reset($optValues);
1543 while(list($k,$v) = each($optValues)) {
1544 $sel = (!strcmp($k,$value) ? ' selected="selected"' : '');
1545 if ($sel) $isSelFlag++;
1546 $opt[] = '<option value="'.htmlspecialchars($k).'"'.$sel.'>'.htmlspecialchars($v).'</option>';
1547 }
1548 if (!$isSelFlag && strcmp('',$value)) {
1549 $opt[] = '<option value="'.htmlspecialchars($value).'" selected="selected">'.htmlspecialchars("['".$value."']").'</option>';
1550 }
1551 return '<select name="'.$prefix.'">'.implode('',$opt).'</select>';
1552 }
1553
1554 /**
1555 * Returns a selector-box with TCA tables
1556 *
1557 * @param string Form element name prefix
1558 * @param array The current values selected
1559 * @param string Table names (and the string "_ALL") to exclude. Comma list
1560 * @return string HTML select element
1561 */
1562 function tableSelector($prefix,$value,$excludeList='') {
1563 global $TCA;
1564 reset($TCA);
1565 $optValues = array();
1566
1567 if (!t3lib_div::inList($excludeList,'_ALL')) {
1568 $optValues['_ALL'] = '[ALL tables]';
1569 }
1570
1571 while(list($table) = each($TCA)) {
1572 if ($GLOBALS['BE_USER']->check('tables_select',$table) && !t3lib_div::inList($excludeList,$table)) {
1573 $optValues[$table] = $table;
1574 }
1575 }
1576
1577 // make box:
1578 $opt = array();
1579 $opt[] = '<option value=""></option>';
1580 reset($optValues);
1581 while(list($k,$v)=each($optValues)) {
1582 if (is_array($value)) {
1583 $sel = in_array($k,$value)?' selected="selected"':'';
1584 }
1585 $opt[] = '<option value="'.htmlspecialchars($k).'"'.$sel.'>'.htmlspecialchars($v).'</option>';
1586 }
1587 return '<select name="'.$prefix.'[]" multiple="multiple" size="'.t3lib_div::intInRange(count($opt),5,10).'">'.implode('',$opt).'</select>';
1588 }
1589
1590 /**
1591 * Returns a selector-box with loaded extension keys
1592 *
1593 * @param string Form element name prefix
1594 * @param array The current values selected
1595 * @return string HTML select element
1596 */
1597 function extensionSelector($prefix,$value) {
1598 global $TYPO3_LOADED_EXT;
1599
1600 $extTrav = array_keys($TYPO3_LOADED_EXT);
1601
1602 // make box:
1603 $opt = array();
1604 $opt[] = '<option value=""></option>';
1605 foreach($extTrav as $v) {
1606 if ($v!=='_CACHEFILE') {
1607 if (is_array($value)) {
1608 $sel = in_array($v,$value)?' selected="selected"':'';
1609 }
1610 $opt[] = '<option value="'.htmlspecialchars($v).'"'.$sel.'>'.htmlspecialchars($v).'</option>';
1611 }
1612 }
1613 return '<select name="'.$prefix.'[]" multiple="multiple" size="'.t3lib_div::intInRange(count($opt),5,10).'">'.implode('',$opt).'</select>';
1614 }
1615
1616 /**
1617 * Filter page IDs by traversing exclude array, finding all excluded pages (if any) and making an AND NOT IN statement for the select clause.
1618 *
1619 * @param array Exclude array from import/export object.
1620 * @return string AND where clause part to filter out page uids.
1621 */
1622 function filterPageIds($exclude) {
1623
1624 // Get keys:
1625 $exclude = array_keys($exclude);
1626
1627 // Traverse
1628 $pageIds = array();
1629 foreach($exclude as $element) {
1630 list($table,$uid) = explode(':', $element);
1631 if ($table==='pages') {
1632 $pageIds[] = intval($uid);
1633 }
1634 }
1635
1636 // Add to clause:
1637 if (count($pageIds)) {
1638 return ' AND uid NOT IN ('.implode(',', $pageIds).')';
1639 }
1640 }
1641 }
1642
1643 // Include extension?
1644 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/impexp/app/index.php']) {
1645 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/impexp/app/index.php']);
1646 }
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659 // Make instance:
1660 $SOBE = t3lib_div::makeInstance('SC_mod_tools_log_index');
1661 $SOBE->init();
1662 $SOBE->main();
1663 $SOBE->printContent();
1664 ?>