00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00174 require_once(PATH_t3lib.'class.t3lib_tcemain.php');
00175 require_once (PATH_t3lib.'class.t3lib_diff.php');
00176 require_once (PATH_t3lib.'class.t3lib_parsehtml.php');
00177
00178 require_once (PATH_t3lib.'class.t3lib_basicfilefunc.php');
00179 require_once (PATH_t3lib.'class.t3lib_extfilefunc.php');
00180 require_once (PATH_t3lib.'class.t3lib_refindex.php');
00181
00182 @ini_set('max_execution_time',600);
00183 @ini_set('memory_limit','256m');
00184
00185
00186
00187
00188
00189
00190
00198 class tx_impexp {
00199
00200
00201 var $showStaticRelations = FALSE;
00202 var $fileadminFolderName = 'fileadmin';
00203
00204 var $mode = '';
00205 var $update = FALSE;
00206 var $doesImport = FALSE;
00207
00208
00209 var $display_import_pid_record = '';
00210 var $suggestedInsertUids = array();
00211 var $import_mode = array();
00212 var $global_ignore_pid = FALSE;
00213 var $force_all_UIDS = FALSE;
00214 var $showDiff = FALSE;
00215 var $allowPHPScripts = FALSE;
00216 var $enableLogging = FALSE;
00217 var $softrefInputValues = array();
00218 var $fileIDMap = array();
00219
00220
00221 var $maxFileSize = 1000000;
00222 var $maxRecordSize = 1000000;
00223 var $maxExportSize = 10000000;
00224 var $relOnlyTables = array();
00225 var $relStaticTables = array();
00226 var $excludeMap = array();
00227 var $softrefCfg = array();
00228 var $extensionDependencies = array();
00229 var $dontCompress = 0;
00230 var $includeExtFileResources = 0;
00231 var $extFileResourceExtensions = 'html,htm,css';
00232
00233
00234 var $import_mapId = array();
00235 var $import_newId = array();
00236 var $import_newId_pids = array();
00237 var $import_data = array();
00238 var $errorLog = array();
00239 var $cache_getRecordPath = array();
00240 var $checkPID_cache = array();
00241
00242 var $compress = 0;
00243 var $dat = array();
00244 var $fileProcObj = '';
00245
00246
00247
00248
00249
00250
00251
00252
00253
00261 function init($dontCompress=0,$mode='') {
00262 $this->compress = function_exists('gzcompress');
00263 $this->dontCompress = $dontCompress;
00264
00265 $this->mode = $mode;
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00292 function setHeaderBasics() {
00293
00294
00295 if (is_array($this->softrefCfg)) {
00296 foreach($this->softrefCfg as $key => $value) {
00297 if (!strlen($value['mode'])) unset($this->softrefCfg[$key]);
00298 }
00299 }
00300
00301
00302 $this->dat['header']['XMLversion'] = '1.0';
00303 $this->dat['header']['meta'] = array();
00304 $this->dat['header']['relStaticTables'] = $this->relStaticTables;
00305 $this->dat['header']['excludeMap'] = $this->excludeMap;
00306 $this->dat['header']['softrefCfg'] = $this->softrefCfg;
00307 $this->dat['header']['extensionDependencies'] = $this->extensionDependencies;
00308 }
00309
00316 function setCharset($charset) {
00317 $this->dat['header']['charset'] = $charset;
00318 }
00319
00331 function setMetaData($title,$description,$notes,$packager_username,$packager_name,$packager_email) {
00332 $this->dat['header']['meta'] = array(
00333 'title' => $title,
00334 'description' => $description,
00335 'notes' => $notes,
00336 'packager_username' => $packager_username,
00337 'packager_name' => $packager_name,
00338 'packager_email' => $packager_email,
00339 'TYPO3_version' => TYPO3_version,
00340 # 'loaded_extensions' => $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList'],
00341 'created' => strftime('%A %e. %B %Y', time())
00342 );
00343 }
00344
00351 function addThumbnail($imgFilepath) {
00352 if (@is_file($imgFilepath)) {
00353 $imgInfo = @getimagesize($imgFilepath);
00354 if (is_array($imgInfo)) {
00355 $fileContent = t3lib_div::getUrl($imgFilepath);
00356 $this->dat['header']['thumbnail'] = array(
00357 'imgInfo' => $imgInfo,
00358 'content' => $fileContent,
00359 'filesize' => strlen($fileContent),
00360 'filemtime' => filemtime($imgFilepath),
00361 'filename' => basename($imgFilepath)
00362 );
00363 }
00364 }
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00389 function setPageTree($idH) {
00390 $this->dat['header']['pagetree'] = $this->unsetExcludedSections($idH);
00391 return $this->flatInversePageTree($this->dat['header']['pagetree']);
00392 }
00393
00402 function unsetExcludedSections($idH) {
00403 if (is_array($idH)) {
00404 reset($idH);
00405 while(list($k,$v) = each($idH)) {
00406 if ($this->excludeMap['pages:'.$idH[$k]['uid']]) {
00407 unset($idH[$k]);
00408 } elseif (is_array($idH[$k]['subrow'])) {
00409 $idH[$k]['subrow'] = $this->unsetExcludedSections($idH[$k]['subrow']);
00410 }
00411 }
00412 }
00413 return $idH;
00414 }
00415
00424 function flatInversePageTree($idH,$a=array()) {
00425 if (is_array($idH)) {
00426 $idH = array_reverse($idH);
00427 reset($idH);
00428 while(list($k,$v) = each($idH)) {
00429 $a[$v['uid']] = $v['uid'];
00430 if (is_array($v['subrow'])) {
00431 $a = $this->flatInversePageTree($v['subrow'],$a);
00432 }
00433 }
00434 }
00435 return $a;
00436 }
00437
00447 function flatInversePageTree_pid($idH,$a=array(),$pid=-1) {
00448 if (is_array($idH)) {
00449 $idH = array_reverse($idH);
00450 reset($idH);
00451 while(list($k,$v) = each($idH)) {
00452 $a[$v['uid']] = $pid;
00453 if (is_array($v['subrow'])) {
00454 $a = $this->flatInversePageTree_pid($v['subrow'],$a,$v['uid']);
00455 }
00456 }
00457 }
00458 return $a;
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00486 function export_addRecord($table,$row,$relationLevel=0) {
00487
00488 t3lib_BEfunc::workspaceOL($table,$row);
00489
00490 if (strcmp($table,'') && is_array($row) && $row['uid']>0 && !$this->excludeMap[$table.':'.$row['uid']]) {
00491 if ($this->checkPID($table==='pages' ? $row['uid'] : $row['pid'])) {
00492 if (!isset($this->dat['records'][$table.':'.$row['uid']])) {
00493
00494
00495 $headerInfo = array();
00496 $headerInfo['uid'] = $row['uid'];
00497 $headerInfo['pid'] = $row['pid'];
00498 $headerInfo['title'] = t3lib_div::fixed_lgd_cs(t3lib_BEfunc::getRecordTitle($table,$row),40);
00499 $headerInfo['size'] = strlen(serialize($row));
00500 if ($relationLevel) {
00501 $headerInfo['relationLevel'] = $relationLevel;
00502 }
00503
00504
00505 if ($headerInfo['size']<$this->maxRecordSize) {
00506
00507
00508 $this->dat['header']['records'][$table][$row['uid']] = $headerInfo;
00509
00510
00511 $this->dat['header']['pid_lookup'][$row['pid']][$table][$row['uid']]=1;
00512
00513
00514 $refIndexObj = t3lib_div::makeInstance('t3lib_refindex');
00515 $refIndexObj->WSOL = TRUE;
00516
00517
00518 $this->dat['records'][$table.':'.$row['uid']] = array();
00519 $this->dat['records'][$table.':'.$row['uid']]['data'] = $row;
00520 $this->dat['records'][$table.':'.$row['uid']]['rels'] = $refIndexObj->getRelations($table,$row);
00521 $this->errorLog = array_merge($this->errorLog,$refIndexObj->errorLog);
00522
00523
00524 $this->dat['header']['records'][$table][$row['uid']]['rels'] = $this->flatDBrels($this->dat['records'][$table.':'.$row['uid']]['rels']);
00525
00526
00527 $this->dat['header']['records'][$table][$row['uid']]['softrefs'] = $this->flatSoftRefs($this->dat['records'][$table.':'.$row['uid']]['rels']);
00528
00529 } else $this->error('Record '.$table.':'.$row['uid'].' was larger than maxRecordSize ('.t3lib_div::formatSize($this->maxRecordSize).')');
00530 } else $this->error('Record '.$table.':'.$row['uid'].' already added.');
00531 } else $this->error('Record '.$table.':'.$row['uid'].' was outside your DB mounts!');
00532 }
00533 }
00534
00544 function export_addDBRelations($relationLevel=0) {
00545 global $TCA;
00546
00547
00548 $addR = array();
00549
00550
00551 if (is_array($this->dat['records'])) {
00552 reset($this->dat['records']);
00553 while(list($k) = each($this->dat['records'])) {
00554 if (is_array($this->dat['records'][$k])) {
00555 reset($this->dat['records'][$k]['rels']);
00556 while(list($fieldname,$vR) = each($this->dat['records'][$k]['rels'])) {
00557 #debug($vR);
00558
00559 if ($vR['type']=='db') {
00560 foreach($vR['itemArray'] as $fI) {
00561 $this->export_addDBRelations_registerRelation($fI, $addR);
00562 }
00563 }
00564
00565
00566 if ($vR['type']=='flex') {
00567
00568 if (is_array($vR['flexFormRels']['db'])) {
00569 foreach($vR['flexFormRels']['db'] as $subList) {
00570 foreach($subList as $fI) {
00571 $this->export_addDBRelations_registerRelation($fI, $addR);
00572 }
00573 }
00574 }
00575
00576 if (is_array($vR['flexFormRels']['softrefs'])) {
00577 foreach($vR['flexFormRels']['softrefs'] as $subList) {
00578 foreach($subList['keys'] as $spKey => $elements) {
00579 foreach($elements as $el) {
00580 if ($el['subst']['type'] === 'db' && $this->includeSoftref($el['subst']['tokenID'])) {
00581 list($tempTable, $tempUid) = explode(':', $el['subst']['recordRef']);
00582 $fI = array(
00583 'table' => $tempTable,
00584 'id' => $tempUid
00585 );
00586 $this->export_addDBRelations_registerRelation($fI, $addR, $el['subst']['tokenID']);
00587 }
00588 }
00589 }
00590 }
00591 }
00592 }
00593
00594
00595 if (is_array($vR['softrefs']['keys'])) {
00596 foreach($vR['softrefs']['keys'] as $spKey => $elements) {
00597 foreach($elements as $el) {
00598 if ($el['subst']['type'] === 'db' && $this->includeSoftref($el['subst']['tokenID'])) {
00599 list($tempTable, $tempUid) = explode(':', $el['subst']['recordRef']);
00600 $fI = array(
00601 'table' => $tempTable,
00602 'id' => $tempUid
00603 );
00604 $this->export_addDBRelations_registerRelation($fI, $addR, $el['subst']['tokenID']);
00605 }
00606 }
00607 }
00608 }
00609 }
00610 }
00611 }
00612 } else $this->error('There were no records available.');
00613
00614
00615 if (count($addR)) {
00616 foreach($addR as $fI) {
00617
00618
00619 $row = t3lib_BEfunc::getRecord($fI['table'],$fI['id']);
00620 if (is_array($row)) {
00621 $this->export_addRecord($fI['table'],$row,$relationLevel+1);
00622 }
00623
00624
00625 if ($fI['id']>0) {
00626 $rId = $fI['table'].':'.$fI['id'];
00627 if (!isset($this->dat['records'][$rId])) {
00628 $this->dat['records'][$rId] = 'NOT_FOUND';
00629 $this->error('Relation record '.$rId.' was not found!');
00630 }
00631 }
00632 }
00633 }
00634
00635
00636 return $addR;
00637 }
00638
00648 function export_addDBRelations_registerRelation($fI, &$addR, $tokenID='') {
00649 global $TCA;
00650
00651 $rId = $fI['table'].':'.$fI['id'];
00652 if (isset($TCA[$fI['table']])
00653 && !$this->isTableStatic($fI['table'])
00654 && !$this->isExcluded($fI['table'],$fI['id'])
00655 && (!$tokenID || $this->includeSoftref($tokenID))
00656 && $this->inclRelation($fI['table'])
00657 ) {
00658 if (!isset($this->dat['records'][$rId])) {
00659
00660 $addR[$rId] = $fI;
00661 }
00662 }
00663 }
00664
00672 function export_addFilesFromRelations() {
00673
00674
00675 if (is_array($this->dat['records'])) {
00676 reset($this->dat['records']);
00677 while(list($k)=each($this->dat['records'])) {
00678 if (is_array($this->dat['records'][$k]['rels'])) {
00679 reset($this->dat['records'][$k]['rels']);
00680 while(list($fieldname,$vR)=each($this->dat['records'][$k]['rels'])) {
00681
00682
00683 if ($vR['type']=='file') {
00684 foreach($vR['newValueFiles'] as $key => $fI) {
00685 $this->export_addFile($fI, $k, $fieldname);
00686
00687 unset($this->dat['records'][$k]['rels'][$fieldname]['newValueFiles'][$key]['ID_absFile']);
00688 }
00689 }
00690
00691
00692 if ($vR['type']=='flex') {
00693 if (is_array($vR['flexFormRels']['file'])) {
00694 foreach($vR['flexFormRels']['file'] as $key => $subList) {
00695 foreach($subList as $subKey => $fI) {
00696 $this->export_addFile($fI, $k, $fieldname);
00697
00698 unset($this->dat['records'][$k]['rels'][$fieldname]['flexFormRels']['file'][$key][$subKey]['ID_absFile']);
00699 }
00700 }
00701 }
00702
00703
00704 if (is_array($vR['flexFormRels']['softrefs'])) {
00705 foreach($vR['flexFormRels']['softrefs'] as $key => $subList) {
00706 foreach($subList['keys'] as $spKey => $elements) {
00707 foreach($elements as $subKey => $el) {
00708 if ($el['subst']['type'] === 'file' && $this->includeSoftref($el['subst']['tokenID'])) {
00709
00710
00711 $ID_absFile = t3lib_div::getFileAbsFileName(PATH_site.$el['subst']['relFileName']);
00712 $ID = md5($ID_absFile);
00713
00714 if ($ID_absFile) {
00715 if (!$this->dat['files'][$ID]) {
00716 $fI = array(
00717 'filename' => basename($ID_absFile),
00718 'ID_absFile' => $ID_absFile,
00719 'ID' => $ID,
00720 'relFileName' => $el['subst']['relFileName']
00721 );
00722 $this->export_addFile($fI, '_SOFTREF_');
00723 }
00724 $this->dat['records'][$k]['rels'][$fieldname]['flexFormRels']['softrefs'][$key]['keys'][$spKey][$subKey]['file_ID'] = $ID;
00725 }
00726 }
00727 }
00728 }
00729 }
00730 }
00731 }
00732
00733
00734 if (is_array($vR['softrefs']['keys'])) {
00735 foreach($vR['softrefs']['keys'] as $spKey => $elements) {
00736 foreach($elements as $subKey => $el) {
00737 if ($el['subst']['type'] === 'file' && $this->includeSoftref($el['subst']['tokenID'])) {
00738
00739
00740 $ID_absFile = t3lib_div::getFileAbsFileName(PATH_site.$el['subst']['relFileName']);
00741 $ID = md5($ID_absFile);
00742
00743 if ($ID_absFile) {
00744 if (!$this->dat['files'][$ID]) {
00745 $fI = array(
00746 'filename' => basename($ID_absFile),
00747 'ID_absFile' => $ID_absFile,
00748 'ID' => $ID,
00749 'relFileName' => $el['subst']['relFileName']
00750 );
00751 $this->export_addFile($fI, '_SOFTREF_');
00752 }
00753 $this->dat['records'][$k]['rels'][$fieldname]['softrefs']['keys'][$spKey][$subKey]['file_ID'] = $ID;
00754 }
00755 }
00756 }
00757 }
00758 }
00759 }
00760 }
00761 }
00762 } else $this->error('There were no records available.');
00763 }
00764
00773 function export_addFile($fI, $recordRef='', $fieldname='') {
00774 if (@is_file($fI['ID_absFile'])) {
00775 if (filesize($fI['ID_absFile']) < $this->maxFileSize) {
00776 $fileRec = array();
00777 $fileRec['filesize'] = filesize($fI['ID_absFile']);
00778 $fileRec['filename'] = basename($fI['ID_absFile']);
00779 $fileRec['filemtime'] = filemtime($fI['ID_absFile']);
00780 if ($recordRef) {
00781 $fileRec['record_ref'] = $recordRef.'/'.$fieldname;
00782 }
00783 if ($fI['relFileName']) {
00784 $fileRec['relFileName'] = $fI['relFileName'];
00785 }
00786
00787
00788 $this->dat['header']['files'][$fI['ID']] = $fileRec;
00789
00790
00791 if ($recordRef && $recordRef!=='_SOFTREF_') {
00792 $refParts = explode(':',$recordRef,2);
00793 if (!is_array($this->dat['header']['records'][$refParts[0]][$refParts[1]]['filerefs'])) {
00794 $this->dat['header']['records'][$refParts[0]][$refParts[1]]['filerefs'] = array();
00795 }
00796 $this->dat['header']['records'][$refParts[0]][$refParts[1]]['filerefs'][] = $fI['ID'];
00797 }
00798
00799
00800 $fileRec['content'] = t3lib_div::getUrl($fI['ID_absFile']);
00801 $fileRec['content_md5'] = md5($fileRec['content']);
00802 $this->dat['files'][$fI['ID']] = $fileRec;
00803
00804
00805
00806 if ($recordRef === '_SOFTREF_') {
00807
00808
00809 if ($RTEoriginal = $this->getRTEoriginalFilename(basename($fI['ID_absFile']))) {
00810 $RTEoriginal_absPath = dirname($fI['ID_absFile']).'/'.$RTEoriginal;
00811 if (@is_file($RTEoriginal_absPath)) {
00812
00813 $RTEoriginal_ID = md5($RTEoriginal_absPath);
00814
00815 $fileRec = array();
00816 $fileRec['filesize'] = filesize($RTEoriginal_absPath);
00817 $fileRec['filename'] = basename($RTEoriginal_absPath);
00818 $fileRec['filemtime'] = filemtime($RTEoriginal_absPath);
00819 $fileRec['record_ref'] = '_RTE_COPY_ID:'.$fI['ID'];
00820 $this->dat['header']['files'][$fI['ID']]['RTE_ORIG_ID'] = $RTEoriginal_ID;
00821
00822
00823 $this->dat['header']['files'][$RTEoriginal_ID] = $fileRec;
00824
00825
00826 $fileRec['content'] = t3lib_div::getUrl($RTEoriginal_absPath);
00827 $fileRec['content_md5'] = md5($fileRec['content']);
00828 $this->dat['files'][$RTEoriginal_ID] = $fileRec;
00829 } else {
00830 $this->error('RTE original file "'.substr($RTEoriginal_absPath,strlen(PATH_site)).'" was not found!');
00831 }
00832 }
00833
00834
00835
00836 $html_fI = pathinfo(basename($fI['ID_absFile']));
00837 if ($this->includeExtFileResources && t3lib_div::inList($this->extFileResourceExtensions,strtolower($html_fI['extension']))) {
00838 $uniquePrefix = '###'.md5(time()).'###';
00839
00840 if (strtolower($html_fI['extension'])==='css') {
00841 $prefixedMedias = explode($uniquePrefix, eregi_replace('(url[[:space:]]*\([[:space:]]*["\']?)([^"\')]*)(["\']?[[:space:]]*\))', '\1'.$uniquePrefix.'\2'.$uniquePrefix.'\3', $fileRec['content']));
00842 } else { // html, htm:
00843 $htmlParser = t3lib_div::makeInstance('t3lib_parsehtml');
00844 $prefixedMedias = explode($uniquePrefix, $htmlParser->prefixResourcePath($uniquePrefix,$fileRec['content'],array(),$uniquePrefix));
00845 }
00846
00847 $htmlResourceCaptured = FALSE;
00848 foreach($prefixedMedias as $k => $v) {
00849 if ($k%2) {
00850 $EXTres_absPath = t3lib_div::resolveBackPath(dirname($fI['ID_absFile']).'/'.$v);
00851 $EXTres_absPath = t3lib_div::getFileAbsFileName($EXTres_absPath);
00852 if ($EXTres_absPath && t3lib_div::isFirstPartOfStr($EXTres_absPath,PATH_site.$this->fileadminFolderName.'/') && @is_file($EXTres_absPath)) {
00853
00854 $htmlResourceCaptured = TRUE;
00855 $EXTres_ID = md5($EXTres_absPath);
00856 $this->dat['header']['files'][$fI['ID']]['EXT_RES_ID'][] = $EXTres_ID;
00857 $prefixedMedias[$k] = '{EXT_RES_ID:'.$EXTres_ID.'}';
00858
00859 // Add file to memory if it is not set already:
00860 if (!isset($this->dat['header']['files'][$EXTres_ID])) {
00861 $fileRec = array();
00862 $fileRec['filesize'] = filesize($EXTres_absPath);
00863 $fileRec['filename'] = basename($EXTres_absPath);
00864 $fileRec['filemtime'] = filemtime($EXTres_absPath);
00865 $fileRec['record_ref'] = '_EXT_PARENT_:'.$fI['ID'];
00866
00867 $fileRec['parentRelFileName'] = $v; // Media relative to the HTML file.
00868
00869 // Setting this data in the header
00870 $this->dat['header']['files'][$EXTres_ID] = $fileRec;
00871
00872 // ... and finally add the heavy stuff:
00873 $fileRec['content'] = t3lib_div::getUrl($EXTres_absPath);
00874 $fileRec['content_md5'] = md5($fileRec['content']);
00875 $this->dat['files'][$EXTres_ID] = $fileRec;
00876 }
00877 }
00878 }
00879 }
00880
00881 if ($htmlResourceCaptured) {
00882 $this->dat['files'][$fI['ID']]['tokenizedContent'] = implode('', $prefixedMedias);
00883 }
00884 }
00885 }
00886
00887 } else $this->error($fI['ID_absFile'].' was larger ('.t3lib_div::formatSize(filesize($fI['ID_absFile'])).') than the maxFileSize ('.t3lib_div::formatSize($this->maxFileSize).')! Skipping.');
00888 } else $this->error($fI['ID_absFile'].' was not a file! Skipping.');
00889 }
00890
00898 function flatDBrels($dbrels) {
00899 $list = array();
00900
00901 foreach($dbrels as $dat) {
00902 if ($dat['type']=='db') {
00903 foreach($dat['itemArray'] as $i) {
00904 $list[$i['table'].':'.$i['id']] = $i;
00905 }
00906 }
00907 if ($dat['type']=='flex' && is_array($dat['flexFormRels']['db'])) {
00908 foreach($dat['flexFormRels']['db'] as $subList) {
00909 foreach($subList as $i) {
00910 $list[$i['table'].':'.$i['id']] = $i;
00911 }
00912 }
00913 }
00914 }
00915 return $list;
00916 }
00917
00924 function flatSoftRefs($dbrels) {
00925 $list = array();
00926 #debug($dbrels);
00927 foreach($dbrels as $field => $dat) {
00928 if (is_array($dat['softrefs']['keys'])) {
00929 foreach($dat['softrefs']['keys'] as $spKey => $elements) {
00930 if (is_array($elements)) {
00931 foreach($elements as $subKey => $el) {
00932 $lKey = $field.':'.$spKey.':'.$subKey;
00933 $list[$lKey] = array_merge(array('field' => $field, 'spKey' => $spKey),$el);
00934
00935 // Add file_ID key to header - slightly "risky" way of doing this because if the calculation changes for the same value in $this->records[...] this will not work anymore!
00936 if ($el['subst'] && $el['subst']['relFileName']) {
00937 $list[$lKey]['file_ID'] = md5(PATH_site.$el['subst']['relFileName']);
00938 }
00939 }
00940 }
00941 }
00942 }
00943 if ($dat['type']=='flex' && is_array($dat['flexFormRels']['softrefs'])) {
00944 foreach($dat['flexFormRels']['softrefs'] as $structurePath => $subSoftrefs) {
00945 if (is_array($subSoftrefs['keys'])) {
00946 foreach($subSoftrefs['keys'] as $spKey => $elements) {
00947 foreach($elements as $subKey => $el) {
00948 $lKey = $field.':'.$structurePath.':'.$spKey.':'.$subKey;
00949 $list[$lKey] = array_merge(array('field' => $field, 'spKey' => $spKey, 'structurePath' => $structurePath),$el);
00950
00951 // Add file_ID key to header - slightly "risky" way of doing this because if the calculation changes for the same value in $this->records[...] this will not work anymore!
00952 if ($el['subst'] && $el['subst']['relFileName']) {
00953 $list[$lKey]['file_ID'] = md5(PATH_site.$el['subst']['relFileName']);
00954 }
00955 }
00956 }
00957 }
00958 }
00959 }
00960 }
00961
00962 #debug($list);
00963 return $list;
00964 }
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976 /**************************
00977 *
00978 * File Output
00979 *
00980 *************************/
00981
00988 function compileMemoryToFileContent($type='') {
00989
00990 if ($type=='xml') {
00991 $out = $this->createXML();
00992 } else {
00993 $compress = $this->doOutputCompress();
00994 $out = '';
00995
00996 // adding header:
00997 $out.= $this->addFilePart(serialize($this->dat['header']),$compress);
00998
00999 // adding records:
01000 $out.= $this->addFilePart(serialize($this->dat['records']),$compress);
01001
01002 // adding files:
01003 $out.= $this->addFilePart(serialize($this->dat['files']),$compress);
01004 }
01005
01006 return $out;
01007 }
01008
01014 function createXML() {
01015
01016 // Options:
01017 $options = array(
01018 'alt_options' => array(
01019 '/header' => array(
01020 'disableTypeAttrib' => TRUE,
01021 'clearStackPath' => TRUE,
01022 'parentTagMap' => array(
01023 'files' => 'file',
01024 'records' => 'table',
01025 'table' => 'rec',
01026 'rec:rels' => 'relations',
01027 'relations' => 'element',
01028 'filerefs' => 'file',
01029 'pid_lookup' => 'page_contents',
01030 'header:relStaticTables' => 'static_tables',
01031 'static_tables' => 'tablename',
01032 'excludeMap' => 'item',
01033 'softrefCfg' => 'softrefExportMode',
01034 'extensionDependencies' => 'extkey',
01035 'softrefs' => 'softref_element',
01036 ),
01037 'alt_options' => array(
01038 '/pagetree' => array(
01039 'disableTypeAttrib' => TRUE,
01040 'useIndexTagForNum' => 'node',
01041 'parentTagMap' => array(
01042 'node:subrow' => 'node'
01043 )
01044 ),
01045 '/pid_lookup/page_contents' => array(
01046 'disableTypeAttrib' => TRUE,
01047 'parentTagMap' => array(
01048 'page_contents' => 'table'
01049 ),
01050 'grandParentTagMap' => array(
01051 'page_contents/table' => 'item'
01052 )
01053 )
01054 )
01055 ),
01056 '/records' => array(
01057 'disableTypeAttrib' => TRUE,
01058 'parentTagMap' => array(
01059 'records' => 'tablerow',
01060 'tablerow:data' => 'fieldlist',
01061 'tablerow:rels' => 'related',
01062 'related' => 'field',
01063 'field:itemArray' => 'relations',
01064 'field:newValueFiles' => 'filerefs',
01065 'field:flexFormRels' => 'flexform',
01066 'relations' => 'element',
01067 'filerefs' => 'file',
01068 'flexform:db' => 'db_relations',
01069 'flexform:file' => 'file_relations',
01070 'flexform:softrefs' => 'softref_relations',
01071 'softref_relations' => 'structurePath',
01072 'db_relations' => 'path',
01073 'file_relations' => 'path',
01074 'path' => 'element',
01075 'keys' => 'softref_key',
01076 'softref_key' => 'softref_element',
01077 ),
01078 'alt_options' => array(
01079 '/records/tablerow/fieldlist' => array(
01080 'useIndexTagForAssoc' => 'field',
01081 )
01082 )
01083 ),
01084 '/files' => array(
01085 'disableTypeAttrib' => TRUE,
01086 'parentTagMap' => array(
01087 'files' => 'file',
01088 ),
01089 ),
01090 )
01091 );
01092
01093 // Creating XML file from $outputArray:
01094 $charset = $this->dat['header']['charset'] ? $this->dat['header']['charset'] : 'iso-8859-1';
01095 $XML = '<?xml version="1.0" encoding="'.$charset.'" standalone="yes" ?>'.chr(10);
01096 $XML.= t3lib_div::array2xml($this->dat,'',0,'T3RecordDocument',0,$options);
01097
01098 return $XML;
01099 }
01100
01106 function doOutputCompress() {
01107 return $this->compress && !$this->dontCompress;
01108 }
01109
01117 function addFilePart($data, $compress=FALSE) {
01118 if ($compress) $data = gzcompress($data);
01119 return md5($data).':'.
01120 ($compress?'1':'0').':'.
01121 str_pad(strlen($data),10,'0',STR_PAD_LEFT).':'.
01122 $data.':';
01123 }
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138 /***********************
01139 *
01140 * Import
01141 *
01142 ***********************/
01143
01150 function importData($pid) {
01151
01152 // Set this flag to indicate that an import is being/has been done.
01153 $this->doesImport = 1;
01154
01155 // Initialize:
01156 // These vars MUST last for the whole section not being cleared. They are used by the method setRelations() which are called at the end of the import session.
01157 $this->import_mapId = array();
01158 $this->import_newId = array();
01159 $this->import_newId_pids = array();
01160
01161 // Temporary files stack initialized:
01162 $this->unlinkFiles = array();
01163 $this->alternativeFileName = array();
01164
01165 // Write records, first pages, then the rest
01166 // Fields with "hard" relations to database, files and flexform fields are kept empty during this run
01167 $this->writeRecords_pages($pid);
01168 $this->writeRecords_records($pid);
01169
01170 // Finally all the file and DB record references must be fixed. This is done after all records have supposedly been written to database:
01171 // $this->import_mapId will indicate two things: 1) that a record WAS written to db and 2) that it has got a new id-number.
01172 $this->setRelations();
01173
01174 // And when all DB relations are in place, we can fix file and DB relations in flexform fields (since data structures often depends on relations to a DS record):
01175 $this->setFlexFormRelations();
01176
01177 // Unlink temporary files:
01178 $this->unlinkTempFiles();
01179
01180 // Finally, traverse all records and process softreferences with substitution attributes.
01181 $this->processSoftReferences();
01182 }
01183
01191 function writeRecords_pages($pid) {
01192
01193 // First, write page structure if any:
01194 if (is_array($this->dat['header']['records']['pages'])) {
01195
01196 // $pageRecords is a copy of the pages array in the imported file. Records here are unset one by one when the addSingle function is called.
01197 $pageRecords = $this->dat['header']['records']['pages'];
01198 $this->import_data = array();
01199 #debug($pageRecords);
01200 // First add page tree if any
01201 if (is_array($this->dat['header']['pagetree'])) {
01202 $pagesFromTree = $this->flatInversePageTree($this->dat['header']['pagetree']);
01203 foreach($pagesFromTree as $uid) {
01204 $thisRec = $this->dat['header']['records']['pages'][$uid];
01205 // PID: Set the main $pid, unless a NEW-id is found
01206 $setPid = isset($this->import_newId_pids[$thisRec['pid']]) ? $this->import_newId_pids[$thisRec['pid']] : $pid;
01207 $this->addSingle('pages',$uid,$setPid);
01208 unset($pageRecords[$uid]);
01209 }
01210 }
01211 #debug($pageRecords);
01212 // Then add all remaining pages not in tree on root level:
01213 if (count($pageRecords)) {
01214 $remainingPageUids = array_keys($pageRecords);
01215 foreach($remainingPageUids as $pUid) {
01216 $this->addSingle('pages',$pUid,$pid);
01217 }
01218 }
01219
01220 // Now write to database:
01221 $tce = $this->getNewTCE();
01222 $tce->suggestedInsertUids = $this->suggestedInsertUids;
01223 $tce->start($this->import_data,Array());
01224 $tce->process_datamap();
01225 #debug($this->import_data,'PAGES');
01226
01227 // post-processing: Registering new ids (end all tcemain sessions with this)
01228 $this->addToMapId($tce->substNEWwithIDs);
01229
01230 // In case of an update, order pages from the page tree correctly:
01231 if ($this->update && is_array($this->dat['header']['pagetree'])) {
01232 $this->writeRecords_pages_order($pid);
01233 }
01234 }
01235 }
01236
01246 function writeRecords_pages_order($pid) {
01247 $cmd_data = array();
01248
01249 // Get uid-pid relations and traverse them in order to map to possible new IDs
01250 $pidsFromTree = $this->flatInversePageTree_pid($this->dat['header']['pagetree']);
01251 #debug($this->dat['header']['pagetree'],'pagetree');
01252 #debug($pidsFromTree,'$pidsFromTree');
01253 #debug($this->import_newId_pids,'import_newId_pids');
01254 foreach($pidsFromTree as $origPid => $newPid) {
01255 if ($newPid>=0 && $this->dontIgnorePid('pages', $origPid)) {
01256 if (substr($this->import_newId_pids[$origPid],0,3)==='NEW') { // If the page had a new id (because it was created) use that instead!
01257
01258 if ($this->import_mapId['pages'][$origPid]) {
01259 $mappedPid = $this->import_mapId['pages'][$origPid];
01260 $cmd_data['pages'][$mappedPid]['move'] = $newPid;
01261 }
01262 } else {
01263 $cmd_data['pages'][$origPid]['move'] = $newPid;
01264 }
01265 }
01266 }
01267
01268 // Execute the move commands if any:
01269 if (count($cmd_data)) {
01270 $tce = $this->getNewTCE();
01271 $tce->start(Array(),$cmd_data);
01272 $tce->process_cmdmap();
01273 }
01274 #debug($cmd_data,'$cmd_data');
01275 }
01276
01284 function writeRecords_records($pid) {
01285 global $TCA;
01286
01287 // Write the rest of the records
01288 $this->import_data = array();
01289 if (is_array($this->dat['header']['records'])) {
01290 reset($this->dat['header']['records']);
01291 while(list($table,$recs) = each($this->dat['header']['records'])) {
01292 if ($table!='pages') {
01293 reset($recs);
01294 while(list($uid,$thisRec)=each($recs)) {
01295 // PID: Set the main $pid, unless a NEW-id is found
01296 $setPid = isset($this->import_mapId['pages'][$thisRec['pid']]) ? $this->import_mapId['pages'][$thisRec['pid']] : $pid;
01297 if (is_array($TCA[$table]) && $TCA[$table]['ctrl']['rootLevel']) {
01298 $setPid = 0;
01299 }
01300
01301 // Add record:
01302 $this->addSingle($table,$uid,$setPid);
01303 }
01304 }
01305 }
01306 } else $this->error('Error: No records defined in internal data array.');
01307
01308 // Now write to database:
01309 $tce = $this->getNewTCE();
01310 $tce->suggestedInsertUids = $this->suggestedInsertUids;
01311 $tce->reverseOrder=1; // Because all records are being submitted in their correct order with positive pid numbers - and so we should reverse submission order internally.
01312 $tce->start($this->import_data,Array());
01313 $tce->process_datamap();
01314 #debug($this->import_data,'RECORDS');
01315
01316 // post-processing: Removing files and registering new ids (end all tcemain sessions with this)
01317 $this->addToMapId($tce->substNEWwithIDs);
01318
01319 // In case of an update, order pages from the page tree correctly:
01320 if ($this->update) {
01321 $this->writeRecords_records_order($pid);
01322 }
01323 }
01324
01334 function writeRecords_records_order($mainPid) {
01335 $cmd_data = array();
01336
01337 if (is_array($this->dat['header']['pagetree'])) {
01338 $pagesFromTree = $this->flatInversePageTree($this->dat['header']['pagetree']);
01339 } else $pagesFromTree = array();
01340
01341 #debug($this->dat['header']['pid_lookup'],'pid_lookup');
01342 if (is_array($this->dat['header']['pid_lookup'])) {
01343 foreach($this->dat['header']['pid_lookup'] as $pid => $recList) {
01344 $newPid = isset($this->import_mapId['pages'][$pid]) ? $this->import_mapId['pages'][$pid] : $mainPid;
01345 #debug(array($pid,$newPid),'$pid / $newPid');
01346
01347 if (t3lib_div::testInt($newPid)) {
01348 foreach($recList as $tableName => $uidList) {
01349