Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00180 require_once(PATH_t3lib.'class.t3lib_tcemain.php'); 00181 require_once (PATH_t3lib.'class.t3lib_diff.php'); 00182 require_once (PATH_t3lib.'class.t3lib_parsehtml.php'); 00183 00184 require_once (PATH_t3lib.'class.t3lib_basicfilefunc.php'); 00185 require_once (PATH_t3lib.'class.t3lib_extfilefunc.php'); 00186 00187 00188 00189 00190 00191 00192 00193 00194 00202 class tx_impexp { 00203 00204 // Configuration, general 00205 var $showStaticRelations = FALSE; // If set, static relations (not exported) will be shown in overview as well 00206 var $fileadminFolderName = 'fileadmin'; // Name of the "fileadmin" folder where files for export/import should be located 00207 00208 var $mode = ''; // Whether "import" or "export" mode of object. Set through init() function 00209 var $update = FALSE; // Updates all records that has same UID instead of creating new! 00210 var $doesImport = FALSE; // Is set by importData() when an import has been done. 00211 00212 // Configuration, import 00213 var $display_import_pid_record = ''; // If set to a page-record, then the preview display of the content will expect this page-record to be the target for the import and accordingly display validation information. This triggers the visual view of the import/export memory to validate if import is possible 00214 var $suggestedInsertUids = array(); // Used to register the forged UID values for imported records that we want to create with the same UIDs as in the import file. Admin-only feature. 00215 var $import_mode = array(); // Setting import modes during update state: as_new, exclude, force_uid 00216 var $global_ignore_pid = FALSE; // If set, PID correct is ignored globally 00217 var $force_all_UIDS = FALSE; // If set, all UID values are forced! (update or import) 00218 var $showDiff = FALSE; // If set, a diff-view column is added to the overview. 00219 var $allowPHPScripts = FALSE; // If set, and if the user is admin, allow the writing of PHP scripts to fileadmin/ area. 00220 var $enableLogging = FALSE; // Disable logging when importing 00221 var $softrefInputValues = array(); // Array of values to substitute in editable softreferences. 00222 var $fileIDMap = array(); // Mapping between the fileID from import memory and the final filenames they are written to. 00223 00224 // Configuration, export 00225 var $maxFileSize = 1000000; // 1MB max file size 00226 var $maxRecordSize = 1000000; // 1MB max record size 00227 var $maxExportSize = 10000000; // 10MB max export size 00228 var $relOnlyTables = array(); // add table names here which are THE ONLY ones which will be included into export if found as relations. '_ALL' will allow all tables. 00229 var $relStaticTables = array(); // add tables names here which should not be exported with the file. (Where relations should be mapped to same UIDs in target system). 00230 var $excludeMap = array(); // Exclude map. Keys are table:uid pairs and if set, records are not added to the export. 00231 var $softrefCfg = array(); // Soft Reference Token ID modes. 00232 var $extensionDependencies = array(); // Listing extension dependencies. 00233 var $dontCompress = 0; // Set by user: If set, compression in t3d files is disabled 00234 var $includeExtFileResources = 0; // Boolean, if set, HTML file resources are included. 00235 var $extFileResourceExtensions = 'html,htm,css'; // Files with external media (HTML/css style references inside) 00236 00237 // Internal, dynamic: 00238 var $import_mapId = array(); // After records are written this array is filled with [table][original_uid] = [new_uid] 00239 var $import_newId = array(); // Keys are [tablename]:[new NEWxxx ids (or when updating it is uids)] while values are arrays with table/uid of the original record it is based on. By the array keys the new ids can be looked up inside tcemain 00240 var $import_newId_pids = array(); // Page id map for page tree (import) 00241 var $import_data = array(); // Internal data accumulation for writing records during import 00242 var $errorLog = array(); // Error log. 00243 var $cache_getRecordPath = array(); // Cache for record paths 00244 var $checkPID_cache = array(); // Cache of checkPID values. 00245 00246 var $compress = 0; // Set internally if the gzcompress function exists 00247 var $dat = array(); // Internal import/export memory 00248 var $fileProcObj = ''; // File processing object 00249 00250 00251 00252 /************************** 00253 * 00254 * Initialize 00255 * 00256 *************************/ 00257 00265 function init($dontCompress=0,$mode='') { 00266 $this->compress = function_exists('gzcompress'); 00267 $this->dontCompress = $dontCompress; 00268 00269 $this->mode = $mode; 00270 } 00271 00272 00273 00274 00275 00276 00277 00278 00279 00280 00281 00282 00283 00284 00285 /************************** 00286 * 00287 * Export / Init + Meta Data 00288 * 00289 *************************/ 00290 00296 function setHeaderBasics() { 00297 00298 // Initializing: 00299 if (is_array($this->softrefCfg)) { 00300 foreach($this->softrefCfg as $key => $value) { 00301 if (!strlen($value['mode'])) unset($this->softrefCfg[$key]); 00302 } 00303 } 00304 00305 // Setting in header memory: 00306 $this->dat['header']['XMLversion'] = '1.0'; // Version of file format 00307 $this->dat['header']['meta'] = array(); // Initialize meta data array (to put it in top of file) 00308 $this->dat['header']['relStaticTables'] = $this->relStaticTables; // Add list of tables to consider static 00309 $this->dat['header']['excludeMap'] = $this->excludeMap; // The list of excluded records 00310 $this->dat['header']['softrefCfg'] = $this->softrefCfg; // Soft Reference mode for elements 00311 $this->dat['header']['extensionDependencies'] = $this->extensionDependencies; // List of extensions the import depends on. 00312 } 00313 00320 function setCharset($charset) { 00321 $this->dat['header']['charset'] = $charset; 00322 } 00323 00335 function setMetaData($title,$description,$notes,$packager_username,$packager_name,$packager_email) { 00336 $this->dat['header']['meta'] = array( 00337 'title' => $title, 00338 'description' => $description, 00339 'notes' => $notes, 00340 'packager_username' => $packager_username, 00341 'packager_name' => $packager_name, 00342 'packager_email' => $packager_email, 00343 'TYPO3_version' => TYPO3_version, 00344 # 'loaded_extensions' => $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList'], 00345 'created' => strftime('%A %e. %B %Y', time()) 00346 ); 00347 } 00348 00355 function addThumbnail($imgFilepath) { 00356 if (@is_file($imgFilepath)) { 00357 $imgInfo = @getimagesize($imgFilepath); 00358 if (is_array($imgInfo)) { 00359 $fileContent = t3lib_div::getUrl($imgFilepath); 00360 $this->dat['header']['thumbnail'] = array( 00361 'imgInfo' => $imgInfo, 00362 'content' => $fileContent, 00363 'filesize' => strlen($fileContent), 00364 'filemtime' => filemtime($imgFilepath), 00365 'filename' => basename($imgFilepath) 00366 ); 00367 } 00368 } 00369 } 00370 00371 00372 00373 00374 00375 00376 00377 00378 00379 00380 00381 /************************** 00382 * 00383 * Export / Init Page tree 00384 * 00385 *************************/ 00386 00393 function setPageTree($idH) { 00394 $this->dat['header']['pagetree'] = $this->unsetExcludedSections($idH); 00395 return $this->flatInversePageTree($this->dat['header']['pagetree']); 00396 } 00397 00406 function unsetExcludedSections($idH) { 00407 if (is_array($idH)) { 00408 reset($idH); 00409 while(list($k,$v) = each($idH)) { 00410 if ($this->excludeMap['pages:'.$idH[$k]['uid']]) { 00411 unset($idH[$k]); 00412 } elseif (is_array($idH[$k]['subrow'])) { 00413 $idH[$k]['subrow'] = $this->unsetExcludedSections($idH[$k]['subrow']); 00414 } 00415 } 00416 } 00417 return $idH; 00418 } 00419 00428 function flatInversePageTree($idH,$a=array()) { 00429 if (is_array($idH)) { 00430 $idH = array_reverse($idH); 00431 reset($idH); 00432 while(list($k,$v) = each($idH)) { 00433 $a[$v['uid']] = $v['uid']; 00434 if (is_array($v['subrow'])) { 00435 $a = $this->flatInversePageTree($v['subrow'],$a); 00436 } 00437 } 00438 } 00439 return $a; 00440 } 00441 00451 function flatInversePageTree_pid($idH,$a=array(),$pid=-1) { 00452 if (is_array($idH)) { 00453 $idH = array_reverse($idH); 00454 reset($idH); 00455 while(list($k,$v) = each($idH)) { 00456 $a[$v['uid']] = $pid; 00457 if (is_array($v['subrow'])) { 00458 $a = $this->flatInversePageTree_pid($v['subrow'],$a,$v['uid']); 00459 } 00460 } 00461 } 00462 return $a; 00463 } 00464 00465 00466 00467 00468 00469 00470 00471 00472 00473 00474 00475 /************************** 00476 * 00477 * Export 00478 * 00479 *************************/ 00480 00490 function export_addRecord($table,$row,$relationLevel=0) { 00491 if (strcmp($table,'') && is_array($row) && $row['uid']>0 && !$this->excludeMap[$table.':'.$row['uid']]) { 00492 if ($this->checkPID($table==='pages' ? $row['uid'] : $row['pid'])) { 00493 if (!isset($this->dat['records'][$table.':'.$row['uid']])) { 00494 00495 // Prepare header info: 00496 $headerInfo = array(); 00497 $headerInfo['uid'] = $row['uid']; 00498 $headerInfo['pid'] = $row['pid']; 00499 $headerInfo['title'] = t3lib_div::fixed_lgd_cs(t3lib_BEfunc::getRecordTitle($table,$row),40); 00500 $headerInfo['size'] = strlen(serialize($row)); 00501 if ($relationLevel) { 00502 $headerInfo['relationLevel'] = $relationLevel; 00503 } 00504 00505 // If record content is not too large in size, set the header content and add the rest: 00506 if ($headerInfo['size']<$this->maxRecordSize) { 00507 00508 // Set the header summary: 00509 $this->dat['header']['records'][$table][$row['uid']] = $headerInfo; 00510 00511 // Create entry in the PID lookup: 00512 $this->dat['header']['pid_lookup'][$row['pid']][$table][$row['uid']]=1; 00513 00514 // Data: 00515 $this->dat['records'][$table.':'.$row['uid']] = array(); 00516 $this->dat['records'][$table.':'.$row['uid']]['data'] = $row; 00517 $this->dat['records'][$table.':'.$row['uid']]['rels'] = $this->getRelations($table,$row); 00518 00519 // Add information about the relations in the record in the header: 00520 $this->dat['header']['records'][$table][$row['uid']]['rels'] = $this->flatDBrels($this->dat['records'][$table.':'.$row['uid']]['rels']); 00521 00522 // Add information about the softrefs to header: 00523 $this->dat['header']['records'][$table][$row['uid']]['softrefs'] = $this->flatSoftRefs($this->dat['records'][$table.':'.$row['uid']]['rels']); 00524 00525 } else $this->error('Record '.$table.':'.$row['uid'].' was larger than maxRecordSize ('.t3lib_div::formatSize($this->maxRecordSize).')'); 00526 } else $this->error('Record '.$table.':'.$row['uid'].' already added.'); 00527 } else $this->error('Record '.$table.':'.$row['uid'].' was outside your DB mounts!'); 00528 } 00529 } 00530 00540 function export_addDBRelations($relationLevel=0) { 00541 global $TCA; 00542 00543 // Initialize: 00544 $addR = array(); 00545 00546 // Traverse all "rels" registered for "records" 00547 if (is_array($this->dat['records'])) { 00548 reset($this->dat['records']); 00549 while(list($k) = each($this->dat['records'])) { 00550 if (is_array($this->dat['records'][$k])) { 00551 reset($this->dat['records'][$k]['rels']); 00552 while(list($fieldname,$vR) = each($this->dat['records'][$k]['rels'])) { 00553 #debug($vR); 00554 // For all DB types of relations: 00555 if ($vR['type']=='db') { 00556 foreach($vR['itemArray'] as $fI) { 00557 $this->export_addDBRelations_registerRelation($fI, $addR); 00558 } 00559 } 00560 00561 // For all flex/db types of relations: 00562 if ($vR['type']=='flex') { 00563 // DB relations in flex form fields: 00564 if (is_array($vR['flexFormRels']['db'])) { 00565 foreach($vR['flexFormRels']['db'] as $subList) { 00566 foreach($subList as $fI) { 00567 $this->export_addDBRelations_registerRelation($fI, $addR); 00568 } 00569 } 00570 } 00571 // DB oriented soft references in flex form fields: 00572 if (is_array($vR['flexFormRels']['softrefs'])) { 00573 foreach($vR['flexFormRels']['softrefs'] as $subList) { 00574 foreach($subList['keys'] as $spKey => $elements) { 00575 foreach($elements as $el) { 00576 if ($el['subst']['type'] === 'db' && $this->includeSoftref($el['subst']['tokenID'])) { 00577 list($tempTable, $tempUid) = explode(':', $el['subst']['recordRef']); 00578 $fI = array( 00579 'table' => $tempTable, 00580 'id' => $tempUid 00581 ); 00582 $this->export_addDBRelations_registerRelation($fI, $addR, $el['subst']['tokenID']); 00583 } 00584 } 00585 } 00586 } 00587 } 00588 } 00589 00590 // In any case, if there are soft refs: 00591 if (is_array($vR['softrefs']['keys'])) { 00592 foreach($vR['softrefs']['keys'] as $spKey => $elements) { 00593 foreach($elements as $el) { 00594 if ($el['subst']['type'] === 'db' && $this->includeSoftref($el['subst']['tokenID'])) { 00595 list($tempTable, $tempUid) = explode(':', $el['subst']['recordRef']); 00596 $fI = array( 00597 'table' => $tempTable, 00598 'id' => $tempUid 00599 ); 00600 $this->export_addDBRelations_registerRelation($fI, $addR, $el['subst']['tokenID']); 00601 } 00602 } 00603 } 00604 } 00605 } 00606 } 00607 } 00608 } else $this->error('There were no records available.'); 00609 00610 // Now, if there were new records to add, do so: 00611 if (count($addR)) { 00612 foreach($addR as $fI) { 00613 00614 // Get and set record: 00615 $row = t3lib_BEfunc::getRecord($fI['table'],$fI['id']); 00616 if (is_array($row)) { 00617 $this->export_addRecord($fI['table'],$row,$relationLevel+1); 00618 } 00619 00620 // Set status message 00621 if ($fI['id']>0) { // Relation pointers always larger than zero except certain "select" types with negative values pointing to uids - but that is not supported here. 00622 $rId = $fI['table'].':'.$fI['id']; 00623 if (!isset($this->dat['records'][$rId])) { 00624 $this->dat['records'][$rId] = 'NOT_FOUND'; 00625 $this->error('Relation record '.$rId.' was not found!'); 00626 } 00627 } 00628 } 00629 } 00630 00631 // Return overview of relations found and added 00632 return $addR; 00633 } 00634 00644 function export_addDBRelations_registerRelation($fI, &$addR, $tokenID='') { 00645 global $TCA; 00646 00647 $rId = $fI['table'].':'.$fI['id']; 00648 if (isset($TCA[$fI['table']]) 00649 && !$this->isTableStatic($fI['table']) 00650 && !$this->isExcluded($fI['table'],$fI['id']) 00651 && (!$tokenID || $this->includeSoftref($tokenID)) 00652 && $this->inclRelation($fI['table']) 00653 ) { 00654 if (!isset($this->dat['records'][$rId])) { 00655 // Set this record to be included since it is not already. 00656 $addR[$rId] = $fI; 00657 } 00658 } 00659 } 00660 00668 function export_addFilesFromRelations() { 00669 00670 // Traverse all "rels" registered for "records" 00671 if (is_array($this->dat['records'])) { 00672 reset($this->dat['records']); 00673 while(list($k)=each($this->dat['records'])) { 00674 if (is_array($this->dat['records'][$k]['rels'])) { 00675 reset($this->dat['records'][$k]['rels']); 00676 while(list($fieldname,$vR)=each($this->dat['records'][$k]['rels'])) { 00677 00678 // For all file type relations: 00679 if ($vR['type']=='file') { 00680 foreach($vR['newValueFiles'] as $key => $fI) { 00681 $this->export_addFile($fI, $k, $fieldname); 00682 // Remove the absolute reference to the file so it doesn't expose absolute paths from source server: 00683 unset($this->dat['records'][$k]['rels'][$fieldname]['newValueFiles'][$key]['ID_absFile']); 00684 } 00685 } 00686 00687 // For all flex type relations: 00688 if ($vR['type']=='flex') { 00689 if (is_array($vR['flexFormRels']['file'])) { 00690 foreach($vR['flexFormRels']['file'] as $key => $subList) { 00691 foreach($subList as $subKey => $fI) { 00692 $this->export_addFile($fI, $k, $fieldname); 00693 // Remove the absolute reference to the file so it doesn't expose absolute paths from source server: 00694 unset($this->dat['records'][$k]['rels'][$fieldname]['flexFormRels']['file'][$key][$subKey]['ID_absFile']); 00695 } 00696 } 00697 } 00698 00699 // DB oriented soft references in flex form fields: 00700 if (is_array($vR['flexFormRels']['softrefs'])) { 00701 foreach($vR['flexFormRels']['softrefs'] as $key => $subList) { 00702 foreach($subList['keys'] as $spKey => $elements) { 00703 foreach($elements as $subKey => $el) { 00704 if ($el['subst']['type'] === 'file' && $this->includeSoftref($el['subst']['tokenID'])) { 00705 00706 // Create abs path and ID for file: 00707 $ID_absFile = t3lib_div::getFileAbsFileName(PATH_site.$el['subst']['relFileName']); 00708 $ID = md5($ID_absFile); 00709 00710 if ($ID_absFile) { 00711 if (!$this->dat['files'][$ID]) { 00712 $fI = array( 00713 'filename' => basename($ID_absFile), 00714 'ID_absFile' => $ID_absFile, 00715 'ID' => $ID, 00716 'relFileName' => $el['subst']['relFileName'] 00717 ); 00718 $this->export_addFile($fI, '_SOFTREF_'); 00719 } 00720 $this->dat['records'][$k]['rels'][$fieldname]['flexFormRels']['softrefs'][$key]['keys'][$spKey][$subKey]['file_ID'] = $ID; 00721 } 00722 } 00723 } 00724 } 00725 } 00726 } 00727 } 00728 00729 // In any case, if there are soft refs: 00730 if (is_array($vR['softrefs']['keys'])) { 00731 foreach($vR['softrefs']['keys'] as $spKey => $elements) { 00732 foreach($elements as $subKey => $el) { 00733 if ($el['subst']['type'] === 'file' && $this->includeSoftref($el['subst']['tokenID'])) { 00734 00735 // Create abs path and ID for file: 00736 $ID_absFile = t3lib_div::getFileAbsFileName(PATH_site.$el['subst']['relFileName']); 00737 $ID = md5($ID_absFile); 00738 00739 if ($ID_absFile) { 00740 if (!$this->dat['files'][$ID]) { 00741 $fI = array( 00742 'filename' => basename($ID_absFile), 00743 'ID_absFile' => $ID_absFile, 00744 'ID' => $ID, 00745 'relFileName' => $el['subst']['relFileName'] 00746 ); 00747 $this->export_addFile($fI, '_SOFTREF_'); 00748 } 00749 $this->dat['records'][$k]['rels'][$fieldname]['softrefs']['keys'][$spKey][$subKey]['file_ID'] = $ID; 00750 } 00751 } 00752 } 00753 } 00754 } 00755 } 00756 } 00757 } 00758 } else $this->error('There were no records available.'); 00759 } 00760 00769 function export_addFile($fI, $recordRef='', $fieldname='') { 00770 if (@is_file($fI['ID_absFile'])) { 00771 if (filesize($fI['ID_absFile']) < $this->maxFileSize) { 00772 $fileRec = array(); 00773 $fileRec['filesize'] = filesize($fI['ID_absFile']); 00774 $fileRec['filename'] = basename($fI['ID_absFile']); 00775 $fileRec['filemtime'] = filemtime($fI['ID_absFile']); 00776 if ($recordRef) { 00777 $fileRec['record_ref'] = $recordRef.'/'.$fieldname; 00778 } 00779 if ($fI['relFileName']) { 00780 $fileRec['relFileName'] = $fI['relFileName']; 00781 } 00782 00783 // Setting this data in the header 00784 $this->dat['header']['files'][$fI['ID']] = $fileRec; 00785 00786 // ... and for the recordlisting, why not let us know WHICH relations there was... 00787 if ($recordRef && $recordRef!=='_SOFTREF_') { 00788 $refParts = explode(':',$recordRef,2); 00789 if (!is_array($this->dat['header']['records'][$refParts[0]][$refParts[1]]['filerefs'])) { 00790 $this->dat['header']['records'][$refParts[0]][$refParts[1]]['filerefs'] = array(); 00791 } 00792 $this->dat['header']['records'][$refParts[0]][$refParts[1]]['filerefs'][] = $fI['ID']; 00793 } 00794 00795 // ... and finally add the heavy stuff: 00796 $fileRec['content'] = t3lib_div::getUrl($fI['ID_absFile']); 00797 $fileRec['content_md5'] = md5($fileRec['content']); 00798 $this->dat['files'][$fI['ID']] = $fileRec; 00799 00800 00801 // For soft references, do further processing: 00802 if ($recordRef === '_SOFTREF_') { 00803 00804 // RTE files? 00805 if ($RTEoriginal = $this->getRTEoriginalFilename(basename($fI['ID_absFile']))) { 00806 $RTEoriginal_absPath = dirname($fI['ID_absFile']).'/'.$RTEoriginal; 00807 if (@is_file($RTEoriginal_absPath)) { 00808 00809 $RTEoriginal_ID = md5($RTEoriginal_absPath); 00810 00811 $fileRec = array(); 00812 $fileRec['filesize'] = filesize($RTEoriginal_absPath); 00813 $fileRec['filename'] = basename($RTEoriginal_absPath); 00814 $fileRec['filemtime'] = filemtime($RTEoriginal_absPath); 00815 $fileRec['record_ref'] = '_RTE_COPY_ID:'.$fI['ID']; 00816 $this->dat['header']['files'][$fI['ID']]['RTE_ORIG_ID'] = $RTEoriginal_ID; 00817 00818 // Setting this data in the header 00819 $this->dat['header']['files'][$RTEoriginal_ID] = $fileRec; 00820 00821 // ... and finally add the heavy stuff: 00822 $fileRec['content'] = t3lib_div::getUrl($RTEoriginal_absPath); 00823 $fileRec['content_md5'] = md5($fileRec['content']); 00824 $this->dat['files'][$RTEoriginal_ID] = $fileRec; 00825 } else { 00826 $this->error('RTE original file "'.substr($RTEoriginal_absPath,strlen(PATH_site)).'" was not found!'); 00827 } 00828 } 00829 00830 // Files with external media? 00831 // This is only done with files grabbed by a softreference parser since it is deemed improbable that hard-referenced files should undergo this treatment. 00832 $html_fI = pathinfo(basename($fI['ID_absFile'])); 00833 if ($this->includeExtFileResources && t3lib_div::inList($this->extFileResourceExtensions,strtolower($html_fI['extension']))) { 00834 $uniquePrefix = '###'.md5(time()).'###'; 00835 00836 if (strtolower($html_fI['extension'])==='css') { 00837 $prefixedMedias = explode($uniquePrefix, eregi_replace('(url[[:space:]]*\([[:space:]]*["\']?)([^"\')]*)(["\']?[[:space:]]*\))', '\1'.$uniquePrefix.'\2'.$uniquePrefix.'\3', $fileRec['content'])); 00838 } else { // html, htm: 00839 $htmlParser = t3lib_div::makeInstance('t3lib_parsehtml'); 00840 $prefixedMedias = explode($uniquePrefix, $htmlParser->prefixResourcePath($uniquePrefix,$fileRec['content'],array(),$uniquePrefix)); 00841 } 00842 00843 $htmlResourceCaptured = FALSE; 00844 foreach($prefixedMedias as $k => $v) { 00845 if ($k%2) { 00846 $EXTres_absPath = t3lib_div::resolveBackPath(dirname($fI['ID_absFile']).'/'.$v); 00847 $EXTres_absPath = t3lib_div::getFileAbsFileName($EXTres_absPath); 00848 if ($EXTres_absPath && t3lib_div::isFirstPartOfStr($EXTres_absPath,PATH_site.$this->fileadminFolderName.'/') && @is_file($EXTres_absPath)) { 00849 00850 $htmlResourceCaptured = TRUE; 00851 $EXTres_ID = md5($EXTres_absPath); 00852 $this->dat['header']['files'][$fI['ID']]['EXT_RES_ID'][] = $EXTres_ID; 00853 $prefixedMedias[$k] = '{EXT_RES_ID:'.$EXTres_ID.'}'; 00854 00855 // Add file to memory if it is not set already: 00856 if (!isset($this->dat['header']['files'][$EXTres_ID])) { 00857 $fileRec = array(); 00858 $fileRec['filesize'] = filesize($EXTres_absPath); 00859 $fileRec['filename'] = basename($EXTres_absPath); 00860 $fileRec['filemtime'] = filemtime($EXTres_absPath); 00861 $fileRec['record_ref'] = '_EXT_PARENT_:'.$fI['ID']; 00862 00863 $fileRec['parentRelFileName'] = $v; // Media relative to the HTML file. 00864 00865 // Setting this data in the header 00866 $this->dat['header']['files'][$EXTres_ID] = $fileRec; 00867 00868 // ... and finally add the heavy stuff: 00869 $fileRec['content'] = t3lib_div::getUrl($EXTres_absPath); 00870 $fileRec['content_md5'] = md5($fileRec['content']); 00871 $this->dat['files'][$EXTres_ID] = $fileRec; 00872 } 00873 } 00874 } 00875 } 00876 00877 if ($htmlResourceCaptured) { 00878 $this->dat['files'][$fI['ID']]['tokenizedContent'] = implode('', $prefixedMedias); 00879 } 00880 } 00881 } 00882 00883 } else $this->error($fI['ID_absFile'].' was larger ('.t3lib_div::formatSize(filesize($fI['ID_absFile'])).') than the maxFileSize ('.t3lib_div::formatSize($this->maxFileSize).')! Skipping.'); 00884 } else $this->error($fI['ID_absFile'].' was not a file! Skipping.'); 00885 } 00886 00897 function getRelations($table,$row) { 00898 global $TCA; 00899 00900 // Load full table description 00901 t3lib_div::loadTCA($table); 00902 00903 // Initialize: 00904 $uid = $row['uid']; 00905 $nonFields = explode(',','uid,perms_userid,perms_groupid,perms_user,perms_group,perms_everybody,pid'); 00906 00907 $outRow = array(); 00908 foreach($row as $field => $value) { 00909 if (!in_array($field,$nonFields) && is_array($TCA[$table]['columns'][$field])) { 00910 $conf = $TCA[$table]['columns'][$field]['config']; 00911 00912 // Add files 00913 if ($result = $this->getRelations_procFiles($value, $conf, $uid)) { 00914 // Creates an entry for the field with all the files: 00915 $outRow[$field] = array( 00916 'type' => 'file', 00917 'newValueFiles' => $result, 00918 ); 00919 } 00920 00921 // Add DB: 00922 if ($result = $this->getRelations_procDB($value, $conf, $uid)) { 00923 // Create an entry for the field with all DB relations: 00924 $outRow[$field] = array( 00925 'type' => 'db', 00926 'itemArray' => $result, 00927 ); 00928 } 00929 00930 // For "flex" fieldtypes we need to traverse the structure looking for file and db references of course! 00931 if ($conf['type']=='flex') { 00932 00933 // Get current value array: 00934 $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $row, $table); 00935 $currentValueArray = t3lib_div::xml2array($value); 00936 00937 // Traversing the XML structure, processing files: 00938 if (is_array($currentValueArray)) { 00939 $this->temp_flexRelations = array( 00940 'db' => array(), 00941 'file' => array(), 00942 'softrefs' => array() 00943 ); 00944 00945 $iteratorObj = t3lib_div::makeInstance('t3lib_TCEmain'); 00946 $iteratorObj->callBackObj = &$this; 00947 $iteratorObj->checkValue_flex_procInData( 00948 $currentValueArray['data'], 00949 array(), // Not used. 00950 array(), // Not used. 00951 $dataStructArray, 00952 array($table,$uid,$field), // Parameters. 00953 'getRelations_flexFormCallBack' 00954 ); 00955 00956 // Create an entry for the field: 00957 $outRow[$field] = array( 00958 'type' => 'flex', 00959 'flexFormRels' => $this->temp_flexRelations, 00960 ); 00961 #debug($outRow[$field]); 00962 } 00963 } 00964 00965 // Soft References: 00966 if (strlen($value) && $softRefs = t3lib_BEfunc::explodeSoftRefParserList($conf['softref'], $table, $field)) { 00967 $softRefValue = $value; 00968 foreach($softRefs as $spKey => $spParams) { 00969 $softRefObj = &t3lib_BEfunc::softRefParserObj($spKey); 00970 if (is_object($softRefObj)) { 00971 $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams); 00972 if (is_array($resultArray)) { 00973 $outRow[$field]['softrefs']['keys'][$spKey] = $resultArray['elements']; 00974 if (strlen($resultArray['content'])) { 00975 $softRefValue = $resultArray['content']; 00976 } 00977 } 00978 } 00979 } 00980 00981 if (is_array($outRow[$field]['softrefs']) && count($outRow[$field]['softrefs']) && strcmp($value,$softRefValue) && strstr($softRefValue,'{softref:')) { 00982 #debug($softRefValue,'tokenizedContent'); 00983 $outRow[$field]['softrefs']['tokenizedContent'] = $softRefValue; 00984 } 00985 } 00986 } 00987 } 00988 00989 return $outRow; 00990 } 00991 01004 function getRelations_flexFormCallBack($pParams, $dsConf, $dataValue, $dataValue_ext1, $dataValue_ext2, $structurePath) { 01005 01006 // Implode parameter values: 01007 list($table, $uid, $field) = $pParams; 01008 01009 // Add files 01010 if ($result = $this->getRelations_procFiles($dataValue, $dsConf, $uid)) { 01011 01012 // Creates an entry for the field with all the files: 01013 $this->temp_flexRelations['file'][$structurePath] = $result; 01014 } 01015 01016 // Add DB: 01017 if ($result = $this->getRelations_procDB($dataValue, $dsConf, $uid)) { 01018 01019 // Create an entry for the field with all DB relations: 01020 $this->temp_flexRelations['db'][$structurePath] = $result; 01021 } 01022 01023 // Soft References: 01024 if (strlen($dataValue) && $softRefs = t3lib_BEfunc::explodeSoftRefParserList($dsConf['softref'], $table, $field)) { 01025 #debug($softRefs); 01026 $softRefValue = $dataValue; 01027 foreach($softRefs as $spKey => $spParams) { 01028 $softRefObj = &t3lib_BEfunc::softRefParserObj($spKey); 01029 if (is_object($softRefObj)) { 01030 $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams, $structurePath); 01031 if (is_array($resultArray) && is_array($resultArray['elements'])) { 01032 $this->temp_flexRelations['softrefs'][$structurePath]['keys'][$spKey] = $resultArray['elements']; 01033 if (strlen($resultArray['content'])) $softRefValue = $resultArray['content']; 01034 } 01035 } 01036 } 01037 01038 if (count($this->temp_flexRelations['softrefs']) && strcmp($dataValue,$softRefValue)) { 01039 $this->temp_flexRelations['softrefs'][$structurePath]['tokenizedContent'] = $softRefValue; 01040 #debug($this->temp_flexRelations['softrefs'][$structurePath], $structurePath); 01041 } 01042 } 01043 } 01044 01053 function getRelations_procFiles($value, $conf, $uid) { 01054 // Take care of files... 01055 if ($conf['type']=='group' && $conf['internal_type']=='file') { 01056 01057 // Collect file values in array: 01058 if ($conf['MM']) { 01059 $theFileValues = array(); 01060 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup'); 01061 $dbAnalysis->start('', 'files', $conf['MM'], $uid); 01062 01063 foreach($dbAnalysis->itemArray as $somekey => $someval) { 01064 if ($someval['id']) { 01065 $theFileValues[] = $someval['id']; 01066 } 01067 } 01068 } else { 01069 $theFileValues = explode(',',$value); 01070 } 01071 01072 // Traverse the files and add them: 01073 $uploadFolder = $conf['uploadfolder']; 01074 $dest = $this->destPathFromUploadFolder($uploadFolder); 01075 $newValue = array(); 01076 $newValueFiles = array(); 01077 01078 foreach($theFileValues as $file) { 01079 if (trim($file)) { 01080 $realFile = $dest.'/'.trim($file); 01081 if (@is_file($realFile)) { 01082 $newValueFiles[] = array( 01083 'filename' => $file, 01084 'ID' => md5($realFile), 01085 'ID_absFile' => $realFile 01086 ); // the order should be preserved here because.. (?) 01087 } else $this->error('Missing file: '.$realFile); 01088 } 01089 } 01090 01091 return $newValueFiles; 01092 } 01093 } 01094 01103 function getRelations_procDB($value, $conf, $uid) { 01104 01105 // DB record lists: 01106 if ($this->isReferenceField($conf)) { 01107 $allowedTables = $conf['type']=='group' ? $conf['allowed'] : $conf['foreign_table'].','.$conf['neg_foreign_table']; 01108 $prependName = $conf['type']=='group' ? $conf['prepend_tname'] : $conf['neg_foreign_table']; 01109 01110 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup'); 01111 $dbAnalysis->start($value,$allowedTables,$conf['MM'],$uid); 01112 01113 return $dbAnalysis->itemArray; 01114 } 01115 } 01116 01124 function flatDBrels($dbrels) { 01125 $list = array(); 01126 01127 foreach($dbrels as $dat) { 01128 if ($dat['type']=='db') { 01129 foreach($dat['itemArray'] as $i) { 01130 $list[$i['table'].':'.$i['id']] = $i; 01131 } 01132 } 01133 if ($dat['type']=='flex' && is_array($dat['flexFormRels']['db'])) { 01134 foreach($dat['flexFormRels']['db'] as $subList) { 01135 foreach($subList as $i) { 01136 $list[$i['table'].':'.$i['id']] = $i; 01137 } 01138 } 01139 } 01140 } 01141 return $list; 01142 } 01143 01150 function flatSoftRefs($dbrels) { 01151 $list = array(); 01152 #debug($dbrels); 01153 foreach($dbrels as $field => $dat) { 01154 if (is_array($dat['softrefs']['keys'])) { 01155 foreach($dat['softrefs']['keys'] as $spKey => $elements) { 01156 if (is_array($elements)) { 01157 foreach($elements as $subKey => $el) { 01158 $lKey = $field.':'.$spKey.':'.$subKey; 01159 $list[$lKey] = array_merge(array('field' => $field, 'spKey' => $spKey),$el); 01160 01161 // 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! 01162 if ($el['subst'] && $el['subst']['relFileName']) { 01163 $list[$lKey]['file_ID'] = md5(PATH_site.$el['subst']['relFileName']); 01164 } 01165 } 01166 } 01167 } 01168 } 01169 if ($dat['type']=='flex' && is_array($dat['flexFormRels']['softrefs'])) { 01170 foreach($dat['flexFormRels']['softrefs'] as $structurePath => $subSoftrefs) { 01171 if (is_array($subSoftrefs['keys'])) { 01172 foreach($subSoftrefs['keys'] as $spKey => $elements) { 01173 foreach($elements as $subKey => $el) { 01174 $lKey = $field.':'.$structurePath.':'.$spKey.':'.$subKey; 01175 $list[$lKey] = array_merge(array('field' => $field, 'spKey' => $spKey, 'structurePath' => $structurePath),$el); 01176 01177 // 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! 01178 if ($el['subst'] && $el['subst']['relFileName']) { 01179 $list[$lKey]['file_ID'] = md5(PATH_site.$el['subst']['relFileName']); 01180 } 01181 } 01182 } 01183 } 01184 } 01185 } 01186 } 01187 01188 #debug($list); 01189 return $list; 01190 } 01191 01198 function destPathFromUploadFolder($folder) { 01199 return PATH_site.$folder; 01200 } 01201 01202 01203 01204 01205 01206 01207 01208 01209 01210 01211 /************************** 01212 * 01213 * File Output 01214 * 01215 *************************/ 01216 01223 function compileMemoryToFileContent($type='') { 01224 01225 if ($type=='xml') { 01226 $out = $this->createXML(); 01227 } else { 01228 $compress = $this->doOutputCompress(); 01229 $out = ''; 01230 01231 // adding header: 01232 $out.= $this->addFilePart(serialize($this->dat['header']),$compress); 01233 01234 // adding records: 01235 $out.= $this->addFilePart(serialize($this->dat['records']),$compress); 01236 01237 // adding files: 01238 $out.= $this->addFilePart(serialize($this->dat['files']),$compress); 01239 } 01240 01241 return $out; 01242 } 01243 01249 function createXML() { 01250 01251 // Options: 01252 $options = array( 01253 'alt_options' => array( 01254 '/header' => array( 01255 'disableTypeAttrib' => TRUE, 01256 'clearStackPath' => TRUE, 01257 'parentTagMap' => array( 01258 'files' => 'file', 01259 'records' => 'table', 01260 'table' => 'rec', 01261 'rec:rels' => 'relations', 01262 'relations' => 'element', 01263 'filerefs' => 'file', 01264 'pid_lookup' => 'page_contents', 01265 'header:relStaticTables' => 'static_tables', 01266 'static_tables' => 'tablename', 01267 'excludeMap' => 'item', 01268 'softrefCfg' => 'softrefExportMode', 01269 'extensionDependencies' => 'extkey', 01270 'softrefs' => 'softref_element', 01271 ), 01272 'alt_options' => array( 01273 '/pagetree' => array( 01274 'disableTypeAttrib' => TRUE, 01275 'useIndexTagForNum' => 'node', 01276 'parentTagMap' => array( 01277 'node:subrow' => 'node' 01278 ) 01279 ), 01280 '/pid_lookup/page_contents' => array( 01281 'disableTypeAttrib' => TRUE, 01282 'parentTagMap' => array( 01283 'page_contents' => 'table' 01284 ), 01285 'grandParentTagMap' => array( 01286 'page_contents/table' => 'item' 01287 ) 01288 ) 01289 ) 01290 ), 01291 '/records' => array( 01292 'disableTypeAttrib' => TRUE, 01293 'parentTagMap' => array( 01294 'records' => 'tablerow', 01295 'tablerow:data' => 'fieldlist', 01296 'tablerow:rels' => 'related', 01297 'related' => 'field', 01298 'field:itemArray' => 'relations', 01299 'field:newValueFiles' => 'filerefs', 01300 'field:flexFormRels' => 'flexform', 01301 'relations' => 'element', 01302 'filerefs' => 'file', 01303 'flexform:db' => 'db_relations', 01304 'flexform:file' => 'file_relations', 01305 'flexform:softrefs' => 'softref_relations', 01306 'softref_relations' => 'structurePath', 01307 'db_relations' => 'path', 01308 'file_relations' => 'path', 01309 'path' => 'element', 01310 'keys' => 'softref_key', 01311 'softref_key' => 'softref_element', 01312 ), 01313 'alt_options' => array( 01314 '/records/tablerow/fieldlist' => array( 01315 'useIndexTagForAssoc' => 'field', 01316 ) 01317 ) 01318 ), 01319 '/files' => array( 01320 'disableTypeAttrib' => TRUE, 01321 'parentTagMap' => array( 01322 'files' => 'file', 01323 ), 01324 ), 01325 ) 01326 ); 01327 01328 // Creating XML file from $outputArray: 01329 $charset = $this->dat['header']['charset'] ? $this->dat['header']['charset'] : 'iso-8859-1'; 01330 $XML = '<?xml version="1.0" encoding="'.$charset.'" standalone="yes" ?>'.chr(10); 01331 $XML.= t3lib_div::array2xml($this->dat,'',0,'T3RecordDocument',0,$options); 01332 01333 return $XML; 01334 } 01335 01341 function doOutputCompress() { 01342 return $this->compress && !$this->dontCompress; 01343 } 01344 01352 function addFilePart($data, $compress=FALSE) { 01353 if ($compress) $data = gzcompress($data); 01354 return md5($data).':'. 01355 ($compress?'1':'0').':'. 01356 str_pad(strlen($data),10,'0',STR_PAD_LEFT).':'. 01357 $data.':'; 01358 } 01359 01360 01361 01362 01363 01364 01365 01366 01367 01368 01369 01370 01371 01372 01373 /*********************** 01374 * 01375 * Import 01376 * 01377 ***********************/ 01378 01385 function importData($pid) { 01386 01387 // Set this flag to indicate that an import is being/has been done. 01388 $this->doesImport = 1; 01389 01390 // Initialize: 01391 // 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. 01392 $this->import_mapId = array(); 01393 $this->import_newId = array(); 01394 $this->import_newId_pids = array(); 01395 01396 // Temporary files stack initialized: 01397 $this->unlinkFiles = array(); 01398 $this->alternativeFileName = array(); 01399 01400 // Write records, first pages, then the rest 01401 // Fields with "hard" relations to database, files and flexform fields are kept empty during this run 01402 $this->writeRecords_pages($pid); 01403 $this->writeRecords_records($pid); 01404 01405 // Finally all the file and DB record references must be fixed. This is done after all records have supposedly been written to database: 01406 // $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. 01407 $this->setRelations(); 01408 01409 // 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): 01410 $this->setFlexFormRelations(); 01411 01412 // Unlink temporary files: 01413 $this->unlinkTempFiles(); 01414 01415 // Finally, traverse all records and process softreferences with substitution attributes. 01416 $this->processSoftReferences(); 01417 } 01418 01426 function writeRecords_pages($pid) { 01427 01428 // First, write page structure if any: 01429 if (is_array($this->dat['header']['records']['pages'])) { 01430 01431 // $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. 01432 $pageRecords = $this->dat['header']['records']['pages']; 01433 $this->import_data = array(); 01434 #debug($pageRecords); 01435 // First add page tree if any 01436 if (is_array($this->dat['header']['pagetree'])) { 01437 $pagesFromTree = $this->flatInversePageTree($this->dat['header']['pagetree']); 01438 foreach($pagesFromTree as $uid) { 01439 $thisRec = $this->dat['header']['records']['pages'][$uid]; 01440 // PID: Set the main $pid, unless a NEW-id is found 01441 $setPid = isset($this->import_newId_pids[$thisRec['pid']]) ? $this->import_newId_pids[$thisRec['pid']] : $pid; 01442 $this->addSingle('pages',$uid,$setPid); 01443 unset($pageRecords[$uid]); 01444 } 01445 } 01446 #debug($pageRecords); 01447 // Then add all remaining pages not in tree on root level: 01448 if (count($pageRecords)) { 01449 $remainingPageUids = array_keys($pageRecords); 01450 foreach($remainingPageUids as $pUid) { 01451 $this->addSingle('pages',$pUid,$pid); 01452 } 01453 } 01454 01455 // Now write to database: 01456 $tce = $this->getNewTCE(); 01457 $tce->suggestedInsertUids = $this->suggestedInsertUids; 01458 $tce->start($this->import_data,Array()); 01459 $tce->process_datamap(); 01460 #debug($this->import_data,'PAGES'); 01461 01462 // post-processing: Registering new ids (end all tcemain sessions with this) 01463 $this->addToMapId($tce->substNEWwithIDs); 01464 01465 // In case of an update, order pages from the page tree correctly: 01466 if ($this->update && is_array($this->dat['header']['pagetree'])) { 01467 $this->writeRecords_pages_order($pid); 01468 } 01469 } 01470 } 01471 01481 function writeRecords_pages_order($pid) { 01482 $cmd_data = array(); 01483 01484 // Get uid-pid relations and traverse them in order to map to possible new IDs 01485 $pidsFromTree = $this->flatInversePageTree_pid($this->dat['header']['pagetree']); 01486 #debug($this->dat['header']['pagetree'],'pagetree'); 01487 #debug($pidsFromTree,'$pidsFromTree'); 01488 #debug($this->import_newId_pids,'import_newId_pids'); 01489 foreach($pidsFromTree as $origPid => $newPid) { 01490 if ($newPid>=0 && $this->dontIgnorePid('pages', $origPid)) { 01491 if (substr($this->import_newId_pids[$origPid],0,3)==='NEW') { // If the page had a new id (because it was created) use that instead! 01492 01493 if ($this->import_mapId['pages'][$origPid]) { 01494 $mappedPid = $this->import_mapId['pages'][$origPid]; 01495 $cmd_data['pages'][$mappedPid]['move'] = $newPid; 01496 } 01497 } else { 01498 $cmd_data['pages'][$origPid]['move'] = $newPid; 01499 } 01500 } 01501 } 01502 01503 // Execute the move commands if any: 01504 if (count($cmd_data)) { 01505 $tce = $this->getNewTCE(); 01506 $tce->start(Array(),$cmd_data); 01507 $tce->process_cmdmap(); 01508 } 01509 #debug($cmd_data,'$cmd_data'); 01510 } 01511 01519 function writeRecords_records($pid) { 01520 global $TCA; 01521 01522 // Write the rest of the records 01523 $this->import_data = array(); 01524 if (is_array($this->dat['header']['records'])) { 01525 reset($this->dat['header']['records']); 01526 while(list($table,$recs) = each($this->dat['header']['records'])) { 01527 if ($table!='pages') { 01528 reset($recs); 01529 while(list($uid,$thisRec)=each($recs)) { 01530 // PID: Set the main $pid, unless a NEW-id is found 01531 $setPid = isset($this->import_mapId['pages'][$thisRec['pid']]) ? $this->import_mapId['pages'][$thisRec['pid']] : $pid; 01532 if (is_array($TCA[$table]) && $TCA[$table]['ctrl']['rootLevel']) { 01533 $setPid = 0; 01534 } 01535 01536 // Add record: 01537 $this->addSingle($table,$uid,$setPid); 01538 } 01539 } 01540 } 01541 } else $this->error('Error: No records defined in internal data array.'); 01542 01543 // Now write to database: 01544 $tce = $this->getNewTCE(); 01545 $tce->suggestedInsertUids = $this->suggestedInsertUids; 01546 $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. 01547 $tce->start($this->import_data,Array()); 01548 $tce->process_datamap(); 01549 #debug($this->import_data,'RECORDS'); 01550 01551 // post-processing: Removing files and registering new ids (end all tcemain sessions with this) 01552 $this->addToMapId($tce->substNEWwithIDs); 01553 01554 // In case of an update, order pages from the page tree correctly: 01555 if ($this->update) { 01556 $this->writeRecords_records_order($pid); 01557 } 01558 } 01559 01569 function writeRecords_records_order($mainPid) { 01570 $cmd_data = array(); 01571 01572 if (is_array($this->dat['header']['pagetree'])) { 01573 $pagesFromTree = $this->flatInversePageTree($this->dat['header']['pagetree']); 01574 } else $pagesFromTree = array(); 01575 01576 #debug($this->dat['header']['pid_lookup'],'pid_lookup'); 01577 if (is_array($this->dat['header']['pid_lookup'])) { 01578 foreach($this->dat['header']['pid_lookup'] as $pid => $recList) { 01579 $newPid = isset($this->import_mapId['pages'][$pid]) ? $this->import_mapId['pages'][$pid] : $mainPid; 01580 #debug(array($pid,$newPid),'$pid / $newPid'); 01581 01582 if (t3lib_div::testInt($newPid)) { 01583 foreach($recList as $tableName => $uidList) { 01584 if (($tableName!='pages' || !$pagesFromTree[$pid]) && is_array($uidList)) { // If $mainPid===$newPid then we are on root level and we can consider to move pages as well! (they will not be in the page tree!) 01585 $uidList = array_reverse(array_keys($uidList)); 01586 foreach($uidList as $uid) { 01587 if ($this->dontIgnorePid($tableName, $uid)) { 01588 $cmd_data[$tableName][$uid]['move'] = $newPid; 01589 } else { 01590 #debug($tableName.':'.$uid,'removed'); 01591 } 01592 } 01593 } 01594 } 01595 } 01596 } 01597 } 01598 01599 // Execute the move commands if any: 01600 if (count($cmd_data)) { 01601 $tce = $this->getNewTCE(); 01602 $tce->start(Array(),$cmd_data); 01603 $tce->process_cmdmap(); 01604 } 01605 #debug($cmd_data,'$cmd_data'); 01606 } 01607 01618 function addSingle($table,$uid,$pid) { 01619 if ($this->import_mode[$table.':'.$uid]!=='exclude') { 01620 $record = $this->dat['records'][$table.':'.$uid]['data']; 01621 if (is_array($record)) { 01622 01623 if ($this->update && $this->doesRecordExist($table,$uid) && $this->import_mode[$table.':'.$uid]!=='as_new') { 01624 $ID = $uid; 01625 } else { 01626 #debug($this->import_mode[$table.':'.$uid],$table.':'.$uid); 01627 $ID = uniqid('NEW'); 01628 } 01629 $this->import_newId[$table.':'.$ID] = array('table' => $table, 'uid' => $uid); 01630 if ($table=='pages') $this->import_newId_pids[$uid] = $ID; 01631 01632 // Set main record data: 01633 $this->import_data[$table][$ID] = $record; 01634 $this->import_data[$table][$ID]['tx_impexp_origuid'] = $this->import_data[$table][$ID]['uid']; 01635 01636 // Reset permission data: 01637 if ($table==='pages') { 01638 // Have to reset the user/group IDs so pages are owned by importing user. Otherwise strange things may happen for non-admins! 01639 unset($this->import_data[$table][$ID]['perms_userid']); 01640 unset($this->import_data[$table][$ID]['perms_groupid']); 01641 01642 // user/group/everybody settings is kept - but these might still conflict with possibilities for writing the content!" 01643 #unset($this->import_data[$table][$ID]['perms_user']); 01644 #unset($this->import_data[$table][$ID]['perms_group']); 01645 #unset($this->import_data[$table][$ID]['perms_everybody']); 01646 } 01647 01648 // PID and UID: 01649 unset($this->import_data[$table][$ID]['uid']); 01650 if (t3lib_div::testInt($ID)) { // Updates: 01651 unset($this->import_data[$table][$ID]['pid']); 01652 } else { // Inserts: 01653 $this->import_data[$table][$ID]['pid'] = $pid; 01654 01655 if ((($this->import_mode[$table.':'.$uid]==='force_uid' && $this->update) || $this->force_all_UIDS) && $GLOBALS['BE_USER']->isAdmin()) { 01656 #debug($this->import_mode[$table.':'.$uid],$table.':'.$uid); 01657 $this->import_data[$table][$ID]['uid'] = $uid; 01658 $this->suggestedInsertUids[$table.':'.$uid] = 'DELETE'; 01659 } 01660 } 01661 01662 // Setting db/file blank: 01663 reset($this->dat['records'][$table.':'.$uid]['rels']); 01664 while(list($field,$config) = each($this->dat['records'][$table.':'.$uid]['rels'])) { 01665 switch((string)$config['type']) { 01666 case 'db': 01667 case 'file': 01668 // Fixed later in ->setRelations() [because we need to know ALL newly created IDs before we can map relations!] 01669 // In the meantime we set NO values for relations: 01670 $this->import_data[$table][$ID][$field] = ''; 01671 break; 01672 case 'flex': 01673 // Fixed later in setFlexFormRelations() 01674 // In the meantime we set NO value for flexforms - this is mainly because file references inside will not be processed properly; In fact references will point to no file or existing files (in which case there will be double-references which is a big problem of course!) 01675 $this->import_data[$table][$ID][$field] = ''; 01676 break; 01677 } 01678 } 01679 } elseif ($table.':'.$uid != 'pages:0') { // On root level we don't want this error message. 01680 $this->error('Error: no record was found in data array!',1); 01681 } 01682 } 01683 } 01684 01692 function addToMapId($substNEWwithIDs) { 01693 reset($this->import_data); 01694 while(list($table,$recs)=each($this->import_data)) { 01695 reset($recs); 01696 while(list($id)=each($recs)) { 01697 $old_uid = $this->import_newId[$table.':'.$id]['uid']; 01698 if (isset($substNEWwithIDs[$id])) { 01699 $this->import_mapId[$table][$old_uid] = $substNEWwithIDs[$id]; 01700 } elseif ($this->update) { 01701 $this->import_mapId[$table][$old_uid] = $id; // Map same ID to same ID.... 01702 } else $this->error('Possible error: '.$table.':'.$old_uid.' had no new id assigned to it. This indicates that the record was not added to database during import. Please check changelog!',1); 01703 } 01704 } 01705 } 01706 01712 function getNewTCE() { 01713 $tce = t3lib_div::makeInstance('t3lib_TCEmain'); 01714 $tce->stripslashes_values = 0; 01715 $tce->dontProcessTransformations = 1; 01716 $tce->enableLogging = $this->enableLogging; 01717 $tce->alternativeFileName = $this->alternativeFileName; 01718 return $tce; 01719 } 01720 01726 function unlinkTempFiles() { 01727 foreach($this->unlinkFiles as $fileName) { 01728 if (t3lib_div::isFirstPartOfStr($fileName, PATH_site.'typo3temp/')) { 01729 t3lib_div::unlink_tempfile($fileName); 01730 clearstatcache(); 01731 if (is_file($fileName)) { 01732 $this->error('Error: '.$fileName.' was NOT unlinked as it should have been!',1); 01733 } 01734 } else $this->error('Error: '.$fileName.' was not in temp-path. Not removed!',1); 01735 } 01736 $this->unlinkFiles = array(); 01737 } 01738 01739 01740 01741 01742 01743 01744 01745 01746 01747 01748 01749 01750 01751 /*************************** 01752 * 01753 * Import / Relations setting 01754 * 01755 ***************************/ 01756 01764 function setRelations() { 01765 global $TCA; 01766 01767 $updateData = array(); 01768 01769 // import_newId contains a register of all records that was in the import memorys "records" key 01770 reset($this->import_newId); 01771 while(list($nId,$dat) = each($this->import_newId)) { 01772 $table = $dat['table']; 01773 $uid = $dat['uid']; // original UID - NOT the new one! 01774 01775 // If the record has been written and received a new id, then proceed: 01776 if (is_array($this->import_mapId[$table]) && isset($this->import_mapId[$table][$uid])) { 01777 $thisNewUid = $this->import_mapId[$table][$uid]; 01778 if (is_array($this->dat['records'][$table.':'.$uid]['rels'])) { 01779 reset($this->dat['records'][$table.':'.$uid]['rels']); 01780 01781 // Traverse relation fields of each record 01782 while(list($field,$config) = each($this->dat['records'][$table.':'.$uid]['rels'])) { 01783 switch((string)$config['type']) { 01784 case 'db': 01785 if (is_array($config['itemArray']) && count($config['itemArray'])) { 01786 $valArray = $this->setRelations_db($config['itemArray']); 01787 $updateData[$table][$thisNewUid][$field] = implode(',',$valArray); // List of [table]_[uid] 01788 } 01789 break; 01790 case 'file': 01791 if (is_array($config['newValueFiles']) && count($config['newValueFiles'])) { 01792 $valArr = array(); 01793 foreach($config['newValueFiles'] as $fI) { 01794 $valArr[] = $this->import_addFileNameToBeCopied($fI); 01795 } 01796 $updateData[$table][$thisNewUid][$field] = implode(',',$valArr); // List of absolute files 01797 } 01798 break; 01799 } 01800 } 01801 } else $this->error('Error: no record was found in data array!',1); 01802 } else $this->error('Error: this records is NOT created it seems! ('.$table.':'.$uid.')',1); 01803 } 01804 if (count($updateData)) { 01805 $tce = $this->getNewTCE(); 01806 $tce->start($updateData,Array()); 01807 $tce->process_datamap(); 01808 #debug($updateData,'setRelations()'); 01809 } 01810 } 01811 01818 function setRelations_db($itemArray) { 01819 $valArray = array(); 01820 01821 foreach($itemArray as $relDat) { 01822 if (is_array($this->import_mapId[$relDat['table']]) && isset($this->import_mapId[$relDat['table']][$relDat['id']])) { 01823 01824 #debug('FOUND: '.$relDat['table'].':'.$relDat['id'],1); 01825 $valArray[] = $relDat['table'].'_'.$this->import_mapId[$relDat['table']][$relDat['id']]; 01826 } elseif ($this->isTableStatic($relDat['table']) || $this->isExcluded($relDat['table'], $relDat['id']) || $relDat['id']<0) { // Checking for less than zero because some select types could contain negative values, eg. fe_groups (-1, -2) and sys_language (-1 = ALL languages). This must be handled on both export and import. 01827 01828 #debug('STATIC: '.$relDat['table'].':'.$relDat['id'],1); 01829 $valArray[] = $relDat['table'].'_'.$relDat['id']; 01830 } else { 01831 01832 $this->error('Lost relation: '.$relDat['table'].':'.$relDat['id'],1); 01833 } 01834 } 01835 01836 return $valArray; 01837 } 01838 01845 function import_addFileNameToBeCopied($fI) { 01846 if (is_array($this->dat['files'][$fI['ID']])) { 01847 $tmpFile = t3lib_div::tempnam('import_temp_'); 01848 t3lib_div::writeFile($tmpFile,$this->dat['files'][$fI['ID']]['content']); 01849 clearstatcache(); 01850 if (@is_file($tmpFile)) { 01851 $this->unlinkFiles[] = $tmpFile; 01852 if (filesize($tmpFile)==$this->dat['files'][$fI['ID']]['filesize']) { 01853 $this->alternativeFileName[$tmpFile] = $fI['filename']; 01854 01855 return $tmpFile; 01856 } else $this->error('Error: temporary file '.$tmpFile.' had a size ('.filesize($tmpFile).') different from the original ('.$this->dat['files'][$fI['ID']]['filesize'].')',1); 01857 } else $this->error('Error: temporary file '.$tmpFile.' was not written as it should have been!',1); 01858 } else $this->error('Error: No file found for ID '.$fI['ID'],1); 01859 } 01860 01868 function setFlexFormRelations() { 01869 global $TCA; 01870 01871 $updateData = array(); 01872 #debug($this->import_newId); 01873 // import_newId contains a register of all records that was in the import memorys "records" key 01874 reset($this->import_newId); 01875 while(list($nId,$dat) = each($this->import_newId)) { 01876 $table = $dat['table']; 01877 $uid = $dat['uid']; // original UID - NOT the new one! 01878 01879 // If the record has been written and received a new id, then proceed: 01880 if (is_array($this->import_mapId[$table]) && isset($this->import_mapId[$table][$uid])) { 01881 $thisNewUid = $this->import_mapId[$table][$uid]; 01882 if (is_array($this->dat['records'][$table.':'.$uid]['rels'])) { 01883 reset($this->dat['records'][$table.':'.$uid]['rels']); 01884 t3lib_div::loadTCA($table); 01885 01886 // Traverse relation fields of each record 01887 while(list($field,$config) = each($this->dat['records'][$table.':'.$uid]['rels'])) { 01888 switch((string)$config['type']) { 01889 case 'flex': 01890 // Get XML content and set as default value (string, non-processed): 01891 $updateData[$table][$thisNewUid][$field] = $this->dat['records'][$table.':'.$uid]['data'][$field]; 01892 01893 // If there has been registered relations inside the flex form field, run processing on the content: 01894 if (count($config['flexFormRels']['db']) || count($config['flexFormRels']['file'])) { 01895 $origRecordRow = t3lib_BEfunc::getRecord($table,$thisNewUid,'*'); // This will fetch the new row for the element (which should be updated with any references to data structures etc.) 01896 #debug(array($updateData[$table][$thisNewUid][$field]),'flexXML'); 01897 $conf = $TCA[$table]['columns'][$field]['config']; 01898 if (is_array($origRecordRow) && is_array($conf) && $conf['type']==='flex') { 01899 #debug($conf,'***'); 01900 // Get current data structure and value array: 01901 $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $origRecordRow, $table); 01902 $currentValueArray = t3lib_div::xml2array($updateData[$table][$thisNewUid][$field]); 01903 #debug($dataStructArray); 01904 #debug($currentValueArray);remapListedDBRecords_flexFormCallBack 01905 #debug($origRecordRow); 01906 #debug($currentValueArray['data'],'BE'); 01907 // Do recursive processing of the XML data: 01908 $iteratorObj = t3lib_div::makeInstance('t3lib_TCEmain'); 01909 $iteratorObj->callBackObj = &$this; 01910 $currentValueArray['data'] = $iteratorObj->checkValue_flex_procInData( 01911 $currentValueArray['data'], 01912 array(), // Not used. 01913 array(), // Not used. 01914 $dataStructArray, 01915 array($table,$thisNewUid,$field,$config), // Parameters. 01916 'remapListedDBRecords_flexFormCallBack' 01917 ); 01918 #debug($currentValueArray['data'],'AF'); 01919 // The return value is set as an array which means it will be processed by tcemain for file and DB references! 01920 if (is_array($currentValueArray['data'])) { 01921 $updateData[$table][$thisNewUid][$field] = $currentValueArray; 01922 } 01923 } 01924 } 01925 break; 01926 } 01927 } 01928 } else $this->error('Error: no record was found in data array!',1); 01929 } else $this->error('Error: this records is NOT created it seems! ('.$table.':'.$uid.')',1); 01930 } 01931 if (count($updateData)) { 01932 $tce = $this->getNewTCE(); 01933 $tce->start($updateData,Array()); 01934 $tce->process_datamap(); 01935 #debug($updateData,'setFlexFormRelations()'); 01936 } 01937 } 01938 01951 function remapListedDBRecords_flexFormCallBack($pParams, $dsConf, $dataValue, $dataValue_ext1, $dataValue_ext2, $path) { 01952 01953 // Extract parameters: 01954 list($table,$uid,$field,$config) = $pParams; 01955 01956 if (is_array($config['flexFormRels']['db'][$path])) { 01957 $valArray = $this->setRelations_db($config['flexFormRels']['db'][$path]); 01958 $dataValue = implode(',',$valArray); 01959 } 01960 01961 if (is_array($config['flexFormRels']['file'][$path])) { 01962 foreach($config['flexFormRels']['file'][$path] as $fI) { 01963 $valArr[] = $this->import_addFileNameToBeCopied($fI); 01964 } 01965 $dataValue = implode(',',$valArr); 01966 } 01967 01968 // Return 01969 return array('value' => $dataValue); 01970 } 01971 01972 01973 01974 01975 01976 01977 01978 01979 01980 01981 01982 /************************** 01983 * 01984 * Import / Soft References 01985 * 01986 *************************/ 01987 01993 function processSoftReferences() { 01994 global $TCA; 01995 01996 // Initialize: 01997 $inData = array(); 01998 01999 // Traverse records: 02000 if (is_array($this->dat['header']['records'])) { 02001 foreach($this->dat['header']['records'] as $table => $recs) { 02002 foreach($recs as $uid => $thisRec) { 02003 02004 // If there are soft references defined, traverse those: 02005 if (isset($TCA[$table]) && is_array($thisRec['softrefs'])) { 02006 t3lib_div::loadTCA($table); 02007 02008 // First traversal is to collect softref configuration and split them up based on fields. This could probably also have been done with the "records" key instead of the header. 02009 $fieldsIndex = array(); 02010 foreach($thisRec['softrefs'] as $softrefDef) { 02011 02012 // If a substitution token is set: 02013 if ($softrefDef['field'] && is_array($softrefDef['subst']) && $softrefDef['subst']['tokenID']) { 02014 $fieldsIndex[$softrefDef['field']][$softrefDef['subst']['tokenID']] = $softrefDef; 02015 } 02016 } 02017 02018 // The new id: 02019 $thisNewUid = $this->import_mapId[$table][$uid]; 02020 02021 // Now, if there are any fields that require substitution to be done, lets go for that: 02022 foreach($fieldsIndex as $field => $softRefCfgs) { 02023 if (is_array($TCA[$table]['columns'][$field])) { 02024 $conf = $TCA[$table]['columns'][$field]['config']; 02025 if ($conf['type']==='flex') { 02026 02027 $origRecordRow = t3lib_BEfunc::getRecord($table,$thisNewUid,'*'); // This will fetch the new row for the element (which should be updated with any references to data structures etc.) 02028 if (is_array($origRecordRow)) { 02029 02030 // Get current data structure and value array: 02031 $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $origRecordRow, $table); 02032 $currentValueArray = t3lib_div::xml2array($origRecordRow[$field]); 02033 02034 // Do recursive processing of the XML data: 02035 $iteratorObj = t3lib_div::makeInstance('t3lib_TCEmain'); 02036 $iteratorObj->callBackObj = &$this; 02037 $currentValueArray['data'] = $iteratorObj->checkValue_flex_procInData( 02038 $currentValueArray['data'], 02039 array(), // Not used. 02040 array(), // Not used. 02041 $dataStructArray, 02042 array($table,$uid,$field,$softRefCfgs), // Parameters (using old UID on purpose!) 02043 'processSoftReferences_flexFormCallBack' 02044 ); 02045 02046 // The return value is set as an array which means it will be processed by tcemain for file and DB references! 02047 if (is_array($currentValueArray['data'])) { 02048 $inData[$table][$thisNewUid][$field] = $currentValueArray; 02049 } 02050 } 02051 } else { 02052 // Get tokenizedContent string and proceed only if that is not blank: 02053 $tokenizedContent = $this->dat['records'][$table.':'.$uid]['rels'][$field]['softrefs']['tokenizedContent']; 02054 if (strlen($tokenizedContent) && is_array($softRefCfgs)) { 02055 $inData[$table][$thisNewUid][$field] = $this->processSoftReferences_substTokens($tokenizedContent, $softRefCfgs, $table, $uid); 02056 } 02057 } 02058 } 02059 } 02060 } 02061 } 02062 } 02063 } 02064 02065 // Now write to database: 02066 $tce = $this->getNewTCE(); 02067 $tce->enableLogging = TRUE; 02068 $tce->start($inData, Array()); 02069 $tce->process_datamap(); 02070 } 02071 02084 function processSoftReferences_flexFormCallBack($pParams, $dsConf, $dataValue, $dataValue_ext1, $dataValue_ext2, $path) { 02085 02086 // Extract parameters: 02087 list($table,$origUid,$field,$softRefCfgs) = $pParams; 02088 02089 if (is_array($softRefCfgs)) { 02090 02091 // First, find all soft reference configurations for this structure path (they are listed flat in the header): 02092 $thisSoftRefCfgList = array(); 02093 foreach($softRefCfgs as $sK => $sV) { 02094 if ($sV['structurePath']===$path) { 02095 $thisSoftRefCfgList[$sK] = $sV; 02096 } 02097 } 02098 02099 // If any was found, do processing: 02100 if (count($thisSoftRefCfgList)) { 02101 02102 // Get tokenizedContent string and proceed only if that is not blank: 02103 $tokenizedContent = $this->dat['records'][$table.':'.$origUid]['rels'][$field]['flexFormRels']['softrefs'][$path]['tokenizedContent']; 02104 if (strlen($tokenizedContent)) { 02105 $dataValue = $this->processSoftReferences_substTokens($tokenizedContent, $thisSoftRefCfgList, $table, $origUid); 02106 } 02107 } 02108 } 02109 02110 // Return 02111 return array('value' => $dataValue); 02112 } 02113 02123 function processSoftReferences_substTokens($tokenizedContent, $softRefCfgs, $table, $uid) { 02124 02125 // traverse each softref type for this field: 02126 foreach($softRefCfgs as $cfg) { 02127 02128 // Get token ID: 02129 $tokenID = $cfg['subst']['tokenID']; 02130 02131 // Default is current token value: 02132 $insertValue = $cfg['subst']['tokenValue']; 02133 02134 // Based on mode: 02135 switch((string)$this->softrefCfg[$tokenID]['mode']) { 02136 case 'exclude': 02137 // Exclude is a simple passthrough of the value 02138 break; 02139 case 'editable': 02140 // Editable always picks up the value from this input array: 02141 $insertValue = $this->softrefInputValues[$tokenID]; 02142 break; 02143 default: 02144 // Mapping IDs/creating files: Based on type, look up new value: 02145 switch((string)$cfg['subst']['type']) { 02146 case 'db': 02147 default: 02148 // Trying to map database element if found in the mapID array: 02149 list($tempTable,$tempUid) = explode(':',$cfg['subst']['recordRef']); 02150 if (isset($this->import_mapId[$tempTable][$tempUid])) { 02151 $insertValue = $this->import_mapId[$tempTable][$tempUid]; 02152 02153 // Look if reference is to a page and the original token value was NOT an integer - then we assume is was an alias and try to look up the new one! 02154 if ($tempTable==='pages' && !t3lib_div::testInt($cfg['subst']['tokenValue'])) { 02155 $recWithUniqueValue = t3lib_BEfunc::getRecord($tempTable,$insertValue, 'alias'); 02156 if ($recWithUniqueValue['alias']) { 02157 $insertValue = $recWithUniqueValue['alias']; 02158 } 02159 } 02160 } 02161 break; 02162 break; 02163 case 'file': 02164 // Create / Overwrite file: 02165 $insertValue = $this->processSoftReferences_saveFile($cfg['subst']['relFileName'], $cfg, $table, $uid); 02166 break; 02167 } 02168 break; 02169 } 02170 02171 // Finally, swap the soft reference token in tokenized content with the insert value: 02172 $tokenizedContent = str_replace('{softref:'.$tokenID.'}', $insertValue, $tokenizedContent); 02173 } 02174 02175 return $tokenizedContent; 02176 } 02177 02187 function processSoftReferences_saveFile($relFileName, $cfg, $table, $uid) { 02188 02189 if ($fileHeaderInfo = $this->dat['header']['files'][$cfg['file_ID']]) { 02190 // Initialize; Get directory prefix for file and find possible RTE filename 02191 $dirPrefix = dirname($relFileName).'/'; 02192 $rteOrigName = $this->getRTEoriginalFilename(basename($relFileName)); 02193 02194 // If filename looks like an RTE file, and the directory is in "uploads/", then process as a RTE file! 02195 if ($rteOrigName && t3lib_div::isFirstPartOfStr($dirPrefix,'uploads/')) { // RTE: 02196 02197 // First, find unique RTE file name: 02198 if (@is_dir(PATH_site.$dirPrefix)) { 02199 02200 // From the "original" RTE filename, produce a new "original" destination filename which is unused. Even if updated, the image should be unique. Currently the problem with this is that it leaves a lot of unused RTE images... 02201 $fileProcObj = &$this->getFileProcObj(); 02202 $origDestName = $fileProcObj->getUniqueName($rteOrigName, PATH_site.$dirPrefix); 02203 02204 // Create copy file name: 02205 $pI = pathinfo($relFileName); 02206 $copyDestName = dirname($origDestName).'/RTEmagicC_'.substr(basename($origDestName),10).'.'.$pI['extension']; 02207 if (!@is_file($copyDestName) && !@is_file($origDestName) 02208 && $origDestName===t3lib_div::getFileAbsFileName($origDestName) && $copyDestName===t3lib_div::getFileAbsFileName($copyDestName)) { 02209 02210 if ($this->dat['header']['files'][$fileHeaderInfo['RTE_ORIG_ID']]) { 02211 02212 // Write the copy and original RTE file to the respective filenames: 02213 $this->writeFileVerify($copyDestName, $cfg['file_ID'], TRUE); 02214 $this->writeFileVerify($origDestName, $fileHeaderInfo['RTE_ORIG_ID'], TRUE); 02215 02216 // Return the relative path of the copy file name: 02217 return substr($copyDestName, strlen(PATH_site)); 02218 } else $this->error('ERROR: Could not find original file ID'); 02219 } else $this->error('ERROR: The destination filenames "'.$copyDestName.'" and "'.$origDestName.'" either existed or have non-valid names'); 02220 } else $this->error('ERROR: "'.PATH_site.$dirPrefix.'" was not a directory, so could not process file "'.$relFileName.'"'); 02221 02222 02223 } elseif (t3lib_div::isFirstPartOfStr($dirPrefix, $this->fileadminFolderName.'/')) { // File in fileadmin/ folder: 02224 02225 // Create file (and possible resources) 02226 $newFileName = $this->processSoftReferences_saveFile_createRelFile($dirPrefix,basename($relFileName),$cfg['file_ID'], $table, $uid); 02227 02228 if (strlen($newFileName)) { 02229 $relFileName = $newFileName; 02230 } else $this->error('ERROR: No new file created for "'.$relFileName.'"'); 02231 } else $this->error('ERROR: Sorry, cannot operate on non-RTE files which are outside the fileadmin folder.'); 02232 } else $this->error('ERROR: Could not find file ID in header.'); 02233 02234 // Return (new) filename relative to PATH_site: 02235 return $relFileName; 02236 } 02237 02248 function processSoftReferences_saveFile_createRelFile($origDirPrefix, $fileName, $fileID, $table, $uid) { 02249 02250 // If the fileID map contains an entry for this fileID then just return the relative filename of that entry; we don't want to write another unique filename for this one! 02251 if ($this->fileIDMap[$fileID]) { 02252 return substr($this->fileIDMap[$fileID],strlen(PATH_site)); 02253 } 02254 02255 // Verify FileMount access to dir-prefix. Returns the best alternative relative path if any 02256 $dirPrefix = $this->verifyFolderAccess($origDirPrefix); 02257 02258 if ($dirPrefix && (!$this->update || $origDirPrefix===$dirPrefix) && $this->checkOrCreateDir($dirPrefix)) { 02259 $fileHeaderInfo = $this->dat['header']['files'][$fileID]; 02260 $updMode = $this->update && $this->import_mapId[$table][$uid]===$uid && $this->import_mode[$table.':'.$uid]!=='as_new'; 02261 // Create new name for file: 02262 if ($updMode) { // Must have same ID in map array (just for security, is not really needed) and NOT be set "as_new". 02263 $newName = PATH_site.$dirPrefix.$fileName; 02264 } else { 02265 // Create unique filename: 02266 $fileProcObj = &$this->getFileProcObj(); 02267 $newName = $fileProcObj->getUniqueName($fileName, PATH_site.$dirPrefix); 02268 } 02269 #debug($newName,'$newName'); 02270 02271 // Write main file: 02272 if ($this->writeFileVerify($newName, $fileID)) { 02273 02274 // If the resource was an HTML/CSS file with resources attached, we will write those as well! 02275 if (is_array($fileHeaderInfo['EXT_RES_ID'])) { 02276 #debug($fileHeaderInfo['EXT_RES_ID']); 02277 $tokenizedContent = $this->dat['files'][$fileID]['tokenizedContent']; 02278 $tokenSubstituted = FALSE; 02279 02280 $fileProcObj = &$this->getFileProcObj(); 02281 02282 if ($updMode) { 02283 foreach($fileHeaderInfo['EXT_RES_ID'] as $res_fileID) { 02284 if ($this->dat['files'][$res_fileID]['filename']) { 02285 02286 // Resolve original filename: 02287 $relResourceFileName = $this->dat['files'][$res_fileID]['parentRelFileName']; 02288 $absResourceFileName = t3lib_div::resolveBackPath(PATH_site.$origDirPrefix.$relResourceFileName); 02289 $absResourceFileName = t3lib_div::getFileAbsFileName($absResourceFileName); 02290 if ($absResourceFileName && t3lib_div::isFirstPartOfStr($absResourceFileName,PATH_site.$this->fileadminFolderName.'/')) { 02291 $destDir = substr(dirname($absResourceFileName).'/',strlen(PATH_site)); 02292 if ($this->verifyFolderAccess($destDir, TRUE) && $this->checkOrCreateDir($destDir)) { 02293 $this->writeFileVerify($absResourceFileName, $res_fileID); 02294 } else $this->error('ERROR: Could not create file in directory "'.$destDir.'"'); 02295 } else $this->error('ERROR: Could not resolve path for "'.$relResourceFileName.'"'); 02296 02297 $tokenizedContent = str_replace('{EXT_RES_ID:'.$res_fileID.'}', $relResourceFileName, $tokenizedContent); 02298 $tokenSubstituted = TRUE; 02299 } 02300 } 02301 } else { 02302 // Create the resouces directory name (filename without extension, suffixed "_FILES") 02303 $resourceDir = dirname($newName).'/'.ereg_replace('\.[^.]*$','',basename($newName)).'_FILES'; 02304 if (t3lib_div::mkdir($resourceDir)) { 02305 foreach($fileHeaderInfo['EXT_RES_ID'] as $res_fileID) { 02306 if ($this->dat['files'][$res_fileID]['filename']) { 02307 $absResourceFileName = $fileProcObj->getUniqueName($this->dat['files'][$res_fileID]['filename'], $resourceDir); 02308 $relResourceFileName = substr($absResourceFileName, strlen(dirname($resourceDir))+1); 02309 $this->writeFileVerify($absResourceFileName, $res_fileID); 02310 02311 $tokenizedContent = str_replace('{EXT_RES_ID:'.$res_fileID.'}', $relResourceFileName, $tokenizedContent); 02312 $tokenSubstituted = TRUE; 02313 } 02314 } 02315 } 02316 } 02317 02318 // If substitutions has been made, write the content to the file again: 02319 if ($tokenSubstituted) { 02320 t3lib_div::writeFile($newName, $tokenizedContent); 02321 } 02322 } 02323 02324 return substr($newName, strlen(PATH_site)); 02325 } 02326 } 02327 } 02328 02337 function writeFileVerify($fileName, $fileID, $bypassMountCheck=FALSE) { 02338 $fileProcObj = &$this->getFileProcObj(); 02339 02340 if ($fileProcObj->actionPerms['newFile']) { 02341 if ($fileProcObj->checkPathAgainstMounts($fileName) || $bypassMountCheck) { // Just for security, check again. Should actually not be necessary. 02342 $fI = t3lib_div::split_fileref($fileName); 02343 if ($fileProcObj->checkIfAllowed($fI['fileext'], $fI['path'], $fI['file']) || ($this->allowPHPScripts && $GLOBALS['BE_USER']->isAdmin())) { 02344 if (t3lib_div::getFileAbsFileName($fileName)) { 02345 if ($this->dat['files'][$fileID]) { 02346 t3lib_div::writeFile($fileName,$this->dat['files'][$fileID]['content']); 02347 $this->fileIDMap[$fileID] = $fileName; 02348 if (md5(t3lib_div::getUrl($fileName))==$this->dat['files'][$fileID]['content_md5']) { 02349 return TRUE; 02350 } else $this->error('ERROR: File content "'.$fileName.'" was corrupted'); 02351 } else $this->error('ERROR: File ID "'.$fileID.'" could not be found'); 02352 } else $this->error('ERROR: Filename "'.$fileName.'" was not a valid relative file path!'); 02353 } else $this->error('ERROR: Filename "'.$fileName.'" failed against extension check or deny-pattern!'); 02354 } else $this->error('ERROR: Filename "'.$fileName.'" was not allowed in destination path!'); 02355 } else $this->error('ERROR: You did not have sufficient permissions to write the file "'.$fileName.'"'); 02356 } 02357 02364 function checkOrCreateDir($dirPrefix) { 02365 02366 // Split dir path and remove first directory (which should be "fileadmin") 02367 $filePathParts = explode('/', $dirPrefix); 02368 $firstDir = array_shift($filePathParts); 02369 02370 if ($firstDir===$this->fileadminFolderName && t3lib_div::getFileAbsFileName($dirPrefix)) { 02371 02372 $pathAcc = ''; 02373 foreach($filePathParts as $dirname) { 02374 $pathAcc.='/'.$dirname; 02375 if (strlen($dirname)) { 02376 if (!@is_dir(PATH_site.$this->fileadminFolderName.$pathAcc)) { 02377 if (!t3lib_div::mkdir(PATH_site.$this->fileadminFolderName.$pathAcc)) { 02378 $this->error('ERROR: Directory could not be created....B'); 02379 return FALSE; 02380 } 02381 } 02382 } elseif ($dirPrefix===$this->fileadminFolderName.$pathAcc) { 02383 return TRUE; 02384 } else $this->error('ERROR: Directory could not be created....A'); 02385 } 02386 } 02387 } 02388 02397 function verifyFolderAccess($dirPrefix, $noAlternative=FALSE) { 02398 $fileProcObj = &$this->getFileProcObj(); 02399 02400 #$fileProcObj->mounts['1f390e42e1dc46f125310ead30c7bd9d']['path'] = '/var/www/typo3/dev/testsite-3.6.0/fileadmin/user_upload/'; 02401 02402 // Check, if dirPrefix is inside a valid Filemount for user: 02403 $result = $fileProcObj->checkPathAgainstMounts(PATH_site.$dirPrefix); 02404 02405 // If not, try to find another relative filemount and use that instead: 02406 if (!$result) { 02407 if ($noAlternative) return FALSE; 02408 02409 // Find first web folder: 02410 $result = $fileProcObj->findFirstWebFolder(); 02411 02412 // If that succeeded, return the path to it: 02413 if ($result) { 02414 // Remove the "fileadmin/" prefix of input path - and append the rest to the return value: 02415 if (t3lib_div::isFirstPartOfStr($dirPrefix,$this->fileadminFolderName.'/')) { 02416 $dirPrefix = substr($dirPrefix,strlen($this->fileadminFolderName.'/')); 02417 } 02418 return substr($fileProcObj->mounts[$result]['path'].$dirPrefix,strlen(PATH_site)); 02419 } 02420 } else { 02421 return $dirPrefix; 02422 } 02423 } 02424 02425 02426 02427 02428 02429 02430 02431 02432 02433 02434 /************************** 02435 * 02436 * File Input 02437 * 02438 *************************/ 02439 02447 function loadFile($filename,$all=0) { 02448 if (@is_file($filename)) { 02449 $fI = pathinfo($filename); 02450 if (strtolower($fI['extension'])=='xml') { 02451 // XML: 02452 $xmlContent = t3lib_div::getUrl($filename); 02453 if (strlen($xmlContent)) { 02454 $this->dat = t3lib_div::xml2array($xmlContent,'',TRUE); 02455 if (is_array($this->dat)) { 02456 if ($this->dat['_DOCUMENT_TAG']==='T3RecordDocument' && is_array($this->dat['header']) && is_array($this->dat['records'])) { 02457 $this->loadInit(); 02458 return TRUE; 02459 } else $this->error('XML file did not contain proper XML for TYPO3 Import'); 02460 } else $this->error('XML could not be parsed: '.$this->dat); 02461 } else $this->error('Error opening file: '.$filename); 02462 } else { 02463 // T3D 02464 if($fd = fopen($filename,'rb')) { 02465 $this->dat['header'] = $this->getNextFilePart($fd,1,'header'); 02466 if ($all) { 02467 $this->dat['records'] = $this->getNextFilePart($fd,1,'records'); 02468 $this->dat['files'] = $this->getNextFilePart($fd,1,'files'); 02469 } 02470 $this->loadInit(); 02471 return TRUE; 02472 } else $this->error('Error opening file: '.$filename); 02473 fclose($fd); 02474 } 02475 } else $this->error('Filename not found: '.$filename); 02476 02477 return FALSE; 02478 } 02479 02490 function getNextFilePart($fd,$unserialize=0,$name='') { 02491 $initStrLen = 32+1+1+1+10+1; 02492 02493 // getting header data 02494 $initStr = fread($fd, $initStrLen); 02495 $initStrDat = explode(':',$initStr); 02496 if (!strcmp($initStrDat[3],'')) { 02497 $datString = fread($fd,intval($initStrDat[2])); 02498 fread($fd,1); 02499 if (!strcmp(md5($datString), $initStrDat[0])) { 02500 if ($initStrDat[1]) { 02501 if ($this->compress) { 02502 $datString = gzuncompress($datString); 02503 } else $this->error('Content read error: This file requires decompression, but this server does not offer gzcompress()/gzuncompress() functions.',1); 02504 } 02505 return $unserialize ? unserialize($datString) : $datString; 02506 } else $this->error('MD5 check failed ('.$name.')'); 02507 } else $this->error('File read error: InitString had a wrong length. ('.$name.')'); 02508 } 02509 02517 function loadContent($filecontent) { 02518 $pointer = 0; 02519 02520 $this->dat['header'] = $this->getNextContentPart($filecontent,$pointer,1,'header'); 02521 $this->dat['records'] = $this->getNextContentPart($filecontent,$pointer,1,'records'); 02522 $this->dat['files'] = $this->getNextContentPart($filecontent,$pointer,1,'files'); 02523 $this->loadInit(); 02524 } 02525 02535 function getNextContentPart($filecontent,&$pointer,$unserialize=0,$name='') { 02536 $initStrLen = 32+1+1+1+10+1; 02537 // getting header data 02538 $initStr = substr($filecontent,$pointer,$initStrLen); 02539 $pointer+= $initStrLen; 02540 $initStrDat = explode(':',$initStr); 02541 if (!strcmp($initStrDat[3],'')) { 02542 $datString = substr($filecontent,$pointer,intval($initStrDat[2])); 02543 $pointer+= intval($initStrDat[2])+1; 02544 if (!strcmp(md5($datString),$initStrDat[0])) { 02545 if ($initStrDat[1]) { 02546 if ($this->compress) { 02547 $datString = gzuncompress($datString); 02548 } else $this->error('Content read error: This file requires decompression, but this server does not offer gzcompress()/gzuncompress() functions.',1); 02549 } 02550 return $unserialize ? unserialize($datString) : $datString; 02551 } else $this->error('MD5 check failed ('.$name.')'); 02552 } else $this->error('Content read error: InitString had a wrong length. ('.$name.')'); 02553 } 02554 02560 function loadInit() { 02561 $this->relStaticTables = (array)$this->dat['header']['relStaticTables']; 02562 $this->excludeMap = (array)$this->dat['header']['excludeMap']; 02563 02564 $this->softrefCfg = (array)$this->dat['header']['softrefCfg']; 02565 $this->extensionDependencies = (array)$this->dat['header']['extensionDependencies']; 02566 02567 $this->fixCharsets(); 02568 } 02569 02576 function fixCharsets() { 02577 global $LANG; 02578 02579 $importCharset = $this->dat['header']['charset']; 02580 if ($importCharset) { 02581 if ($importCharset!==$LANG->charSet) { 02582 $this->error('CHARSET: Converting charset of input file ('.$importCharset.') to the system charset ('.$LANG->charSet.')'); 02583 02584 // convert meta data: 02585 if (is_array($this->dat['header']['meta'])) { 02586 $LANG->csConvObj->convArray($this->dat['header']['meta'],$importCharset,$LANG->charSet); 02587 } 02588 // convert record headers: 02589 if (is_array($this->dat['header']['records'])) { 02590 $LANG->csConvObj->convArray($this->dat['header']['records'],$importCharset,$LANG->charSet); 02591 } 02592 // convert records themselves: 02593 if (is_array($this->dat['records'])) { 02594 $LANG->csConvObj->convArray($this->dat['records'],$importCharset,$LANG->charSet); 02595 } 02596 } 02597 } else { 02598 $this->error('CHARSET: No charset found in import file!'); 02599 } 02600 } 02601 02602 02603 02604 02605 02606 02607 02608 02609 02610 02611 02612 02613 02614 02615 02616 02617 02618 02619 02620 /******************************************************** 02621 * 02622 * Visual rendering of import/export memory, $this->dat 02623 * 02624 ********************************************************/ 02625 02631 function displayContentOverview() { 02632 global $LANG; 02633 02634 // Check extension dependencies: 02635 if (is_array($this->dat['header']['extensionDependencies'])) { 02636 foreach($this->dat['header']['extensionDependencies'] as $extKey) { 02637 if (!t3lib_extMgm::isLoaded($extKey)) { 02638 $this->error('DEPENDENCY: The extension with key "'.$extKey.'" must be installed!'); 02639 } 02640 } 02641 } 02642 02643 // Probably this is done to save memory space? 02644 unset($this->dat['files']); 02645 02646 // Traverse header: 02647 $this->remainHeader = $this->dat['header']; 02648 if (is_array($this->remainHeader)) { 02649 02650 // If there is a page tree set, show that: 02651 if (is_array($this->dat['header']['pagetree'])) { 02652 reset($this->dat['header']['pagetree']); 02653 $lines = array(); 02654 $this->traversePageTree($this->dat['header']['pagetree'],$lines); 02655 02656 $rows = array(); 02657 $rows[] = ' 02658 <tr class="bgColor5 tableheader"> 02659 <td>'.$LANG->getLL('impexpcore_displaycon_controls',1).'</td> 02660 <td>'.$LANG->getLL('impexpcore_displaycon_title',1).'</td> 02661 <td>'.$LANG->getLL('impexpcore_displaycon_size',1).'</td> 02662 <td>'.$LANG->getLL('impexpcore_displaycon_message',1).'</td> 02663 '.($this->update ? '<td>'.$LANG->getLL('impexpcore_displaycon_updateMode',1).'</td>' : '').' 02664 '.($this->update ? '<td>'.$LANG->getLL('impexpcore_displaycon_currentPath',1).'</td>' : '').' 02665 '.($this->showDiff ? '<td>'.$LANG->getLL('impexpcore_displaycon_result',1).'</td>' : '').' 02666 </tr>'; 02667 02668 foreach($lines as $r) { 02669 $rows[] = ' 02670 <tr class="'.$r['class'].'"> 02671 <td>'.$this->renderControls($r).'</td> 02672 <td nowrap="nowrap">'.$r['preCode'].$r['title'].'</td> 02673 <td nowrap="nowrap">'.t3lib_div::formatSize($r['size']).'</td> 02674 <td nowrap="nowrap">'.($r['msg'] && !$this->doesImport ? '<span class="typo3-red">'.htmlspecialchars($r['msg']).'</span>' : '').'</td> 02675 '.($this->update ? '<td nowrap="nowrap">'.$r['updateMode'].'</td>' : '').' 02676 '.($this->update ? '<td nowrap="nowrap">'.$r['updatePath'].'</td>' : '').' 02677 '.($this->showDiff ? '<td>'.$r['showDiffContent'].'</td>' : '').' 02678 </tr>'; 02679 } 02680 02681 $out = ' 02682 <strong>'.$LANG->getLL('impexpcore_displaycon_insidePagetree',1).'</strong> 02683 <br /><br /> 02684 <table border="0" cellpadding="0" cellspacing="1">'.implode('',$rows).'</table> 02685 <br /><br />'; 02686 } 02687 02688 // Print remaining records that were not contained inside the page tree: 02689 $lines = array(); 02690 if (is_array($this->remainHeader['records'])) { 02691 if (is_array($this->remainHeader['records']['pages'])) { 02692 $this->traversePageRecords($this->remainHeader['records']['pages'], $lines); 02693 } 02694 $this->traverseAllRecords($this->remainHeader['records'], $lines); 02695 02696 if (count($lines)) { 02697 $rows = array(); 02698 $rows[] = ' 02699 <tr class="bgColor5 tableheader"> 02700 <td>'.$LANG->getLL('impexpcore_displaycon_controls',1).'</td> 02701 <td>'.$LANG->getLL('impexpcore_displaycon_title',1).'</td> 02702 <td>'.$LANG->getLL('impexpcore_displaycon_size',1).'</td> 02703 <td>'.$LANG->getLL('impexpcore_displaycon_message',1).'</td> 02704 '.($this->update ? '<td>'.$LANG->getLL('impexpcore_displaycon_updateMode',1).'</td>' : '').' 02705 '.($this->update ? '<td>'.$LANG->getLL('impexpcore_displaycon_currentPath',1).'</td>' : '').' 02706 '.($this->showDiff ? '<td>'.$LANG->getLL('impexpcore_displaycon_result',1).'</td>' : '').' 02707 </tr>'; 02708 02709 foreach($lines as $r) { 02710 $rows[] = '<tr class="'.$r['class'].'"> 02711 <td>'.$this->renderControls($r).'</td> 02712 <td nowrap="nowrap">'.$r['preCode'].$r['title'].'</td> 02713 <td nowrap="nowrap">'.t3lib_div::formatSize($r['size']).'</td> 02714 <td nowrap="nowrap">'.($r['msg'] && !$this->doesImport ? '<span class="typo3-red">'.htmlspecialchars($r['msg']).'</span>' : '').'</td> 02715 '.($this->update ? '<td nowrap="nowrap">'.$r['updateMode'].'</td>' : '').' 02716 '.($this->update ? '<td nowrap="nowrap">'.$r['updatePath'].'</td>' : '').' 02717 '.($this->showDiff ? '<td>'.$r['showDiffContent'].'</td>' : '').' 02718 </tr>'; 02719 } 02720 02721 $out.= ' 02722 <strong>'.$LANG->getLL('impexpcore_singlereco_outsidePagetree',1).'</strong> 02723 <br /><br /> 02724 <table border="0" cellpadding="0" cellspacing="1">'.implode('',$rows).'</table>'; 02725 } 02726 } 02727 } 02728 return $out; 02729 } 02730 02739 function traversePageTree($pT,&$lines,$preCode='') { 02740 reset($pT); 02741 while(list($k,$v) = each($pT)) { 02742 02743 // Add this page: 02744 $this->singleRecordLines('pages',$k,$lines,$preCode); 02745 02746 // Subrecords: 02747 if (is_array($this->dat['header']['pid_lookup'][$k])) { 02748 reset($this->dat['header']['pid_lookup'][$k]); 02749 while(list($t,$recUidArr)=each($this->dat['header']['pid_lookup'][$k])) { 02750 if ($t!='pages') { 02751 reset($recUidArr); 02752 while(list($ruid)=each($recUidArr)) { 02753 $this->singleRecordLines($t,$ruid,$lines,$preCode.' '); 02754 } 02755 } 02756 } 02757 unset($this->remainHeader['pid_lookup'][$k]); 02758 } 02759 02760 // Subpages, called recursively: 02761 if (is_array($v['subrow'])) { 02762 $this->traversePageTree($v['subrow'],$lines,$preCode.' '); 02763 } 02764 } 02765 } 02766 02774 function traversePageRecords($pT,&$lines) { 02775 reset($pT); 02776 while(list($k,$rHeader)=each($pT)) { 02777 $this->singleRecordLines('pages',$k,$lines,'',1); 02778 // Subrecords: 02779 if (is_array($this->dat['header']['pid_lookup'][$k])) { 02780 reset($this->dat['header']['pid_lookup'][$k]); 02781 while(list($t,$recUidArr)=each($this->dat['header']['pid_lookup'][$k])) { 02782 if ($t!='pages') { 02783 reset($recUidArr); 02784 while(list($ruid)=each($recUidArr)) { 02785 $this->singleRecordLines($t,$ruid,$lines,' '); 02786 } 02787 } 02788 } 02789 unset($this->remainHeader['pid_lookup'][$k]); 02790 } 02791 } 02792 } 02793 02801 function traverseAllRecords($pT,&$lines) { 02802 reset($pT); 02803 while(list($t,$recUidArr)=each($pT)) { 02804 if ($t!='pages') { 02805 reset($recUidArr); 02806 while(list($ruid)=each($recUidArr)) { 02807 $this->singleRecordLines($t,$ruid,$lines,$preCode,1); 02808 } 02809 } 02810 } 02811 } 02812 02823 function singleRecordLines($table,$uid,&$lines,$preCode,$checkImportInPidRecord=0) { 02824 global $TCA,$BE_USER,$LANG; 02825 02826 // Get record: 02827 $record = $this->dat['header']['records'][$table][$uid]; 02828 unset($this->remainHeader['records'][$table][$uid]); 02829 if (!is_array($record) && !($table==='pages' && !$uid)) $this->error('MISSING RECORD: '.$table.':'.$uid,1); 02830 02831 // Begin to create the line arrays information record, pInfo: 02832 $pInfo = array(); 02833 $pInfo['ref'] = $table.':'.$uid; 02834 if ($table==='_SOFTREF_') { // Unknown table name: 02835 $pInfo['preCode'] = $preCode; 02836 $pInfo['title'] = '<em>'.$LANG->getLL('impexpcore_singlereco_softReferencesFiles',1).'</em>'; 02837 } elseif (!isset($TCA[$table])) { // Unknown table name: 02838 $pInfo['preCode'] = $preCode; 02839 $pInfo['msg'] = "UNKNOWN TABLE '".$pInfo['ref']."'"; 02840 $pInfo['title'] = '<em>'.htmlspecialchars($record['title']).'</em>'; 02841 } else { // Otherwise, set table icon and title. 02842 02843 // Import Validation (triggered by $this->display_import_pid_record) will show messages if import is not possible of various items. 02844 if (is_array($this->display_import_pid_record)) { 02845 if ($checkImportInPidRecord) { 02846 if (!$BE_USER->doesUserHaveAccess($this->display_import_pid_record, $table=='pages'?8:16)) { 02847 $pInfo['msg'].="'".$pInfo['ref']."' cannot be INSERTED on this page! "; 02848 } 02849 if (!$this->checkDokType($table, $this->display_import_pid_record['doktype']) && !$TCA[$table]['ctrl']['rootLevel']) { 02850 $pInfo['msg'].="'".$table."' cannot be INSERTED on this page type (change to 'sysFolder'!) "; 02851 } 02852 } 02853 if (!$BE_USER->check('tables_modify',$table)) {$pInfo['msg'].="You are not allowed to CREATE '".$table."' tables! ";} 02854 02855 if ($TCA[$table]['ctrl']['readOnly']) {$pInfo['msg'].="TABLE '".$table."' is READ ONLY! ";} 02856 if ($TCA[$table]['ctrl']['adminOnly'] && !$BE_USER->isAdmin()) {$pInfo['msg'].="TABLE '".$table."' is ADMIN ONLY! ";} 02857 if ($TCA[$table]['ctrl']['is_static']) {$pInfo['msg'].="TABLE '".$table."' is a STATIC TABLE! ";} 02858 if ($TCA[$table]['ctrl']['rootLevel']) {$pInfo['msg'].="TABLE '".$table."' will be inserted on ROOT LEVEL! ";} 02859 02860 $diffInverse = FALSE; 02861 if ($this->update) { 02862 $diffInverse = TRUE; // In case of update-PREVIEW we swap the diff-sources. 02863 $recInf = $this->doesRecordExist($table, $uid, $this->showDiff ? '*' : ''); 02864 $pInfo['updatePath']= $recInf ? htmlspecialchars($this->getRecordPath($recInf['pid'])) : '<b>NEW!</b>'; 02865 02866 // Mode selector: 02867 $optValues = array(); 02868 $optValues[] = $recInf ? $LANG->getLL('impexpcore_singlereco_update') : $LANG->getLL('impexpcore_singlereco_insert'); 02869 if ($recInf) $optValues['as_new'] = $LANG->getLL('impexpcore_singlereco_importAsNew'); 02870 if ($recInf) { 02871 if (!$this->global_ignore_pid) { 02872 $optValues['ignore_pid'] = $LANG->getLL('impexpcore_singlereco_ignorePid'); 02873 } else { 02874 $optValues['respect_pid'] = $LANG->getLL('impexpcore_singlereco_respectPid'); 02875 } 02876 } 02877 if (!$recInf && $GLOBALS['BE_USER']->isAdmin()) $optValues['force_uid'] = sprintf($LANG->getLL('impexpcore_singlereco_forceUidSAdmin'),$uid); 02878 $optValues['exclude'] = $LANG->getLL('impexpcore_singlereco_exclude'); 02879 02880 $pInfo['updateMode'] = $this->renderSelectBox('tx_impexp[import_mode]['.$table.':'.$uid.']',$this->import_mode[$table.':'.$uid],$optValues); 02881 } 02882 02883 // Diff vieiw: 02884 if ($this->showDiff) { 02885 // For IMPORTS, get new id: 02886 if ($newUid = $this->import_mapId[$table][$uid]) { 02887 $diffInverse = FALSE; 02888 $recInf = $this->doesRecordExist($table, $newUid, '*'); 02889 } 02890 if (is_array($recInf)) { 02891 $pInfo['showDiffContent'] = $this->compareRecords($recInf, $this->dat['records'][$table.':'.$uid]['data'], $table, $diffInverse); 02892 } 02893 } 02894 } 02895 02896 $pInfo['preCode'] = $preCode.t3lib_iconworks::getIconImage($table,$this->dat['records'][$table.':'.$uid]['data'],$GLOBALS['BACK_PATH'],'align="top" title="'.htmlspecialchars($table.':'.$uid).'"'); 02897 $pInfo['title'] = htmlspecialchars($record['title']); 02898 02899 // View page: 02900 if ($table==='pages') { 02901 $viewID = $this->mode === 'export' ? $uid : ($this->doesImport ? $this->import_mapId['pages'][$uid] : 0); 02902 if ($viewID) { 02903 $pInfo['title'] = '<a href="#" onclick="'.htmlspecialchars(t3lib_BEfunc::viewOnClick($viewID, $GLOBALS['BACK_PATH'])).'return false;">'.$pInfo['title'].'</a>'; 02904 } 02905 } 02906 } 02907 $pInfo['class'] = $table=='pages' ? 'bgColor4-20' : 'bgColor4'; 02908 $pInfo['type'] = 'record'; 02909 $pInfo['size'] = $record['size']; 02910 $lines[] = $pInfo; 02911 02912 // File relations: 02913 if (is_array($record['filerefs'])) { 02914 $this->addFiles($record['filerefs'],$lines,$preCode); 02915 } 02916 02917 // DB relations 02918 if (is_array($record['rels'])) { 02919 $this->addRelations($record['rels'],$lines,$preCode); 02920 } 02921 02922 // Soft ref 02923 if (count($record['softrefs'])) { 02924 $preCode_A = $preCode.' '; 02925 $preCode_B = $preCode.' '; 02926 foreach($record['softrefs'] as $info) { 02927 $pInfo = array(); 02928 $pInfo['preCode'] = $preCode_A.'<img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'t3lib/gfx/rel_softref.png','width="13" height="12"').' align="top" alt="" />'; 02929 $pInfo['title'] = '<em>'.$info['field'].', "'.$info['spKey'].'" </em>: <span title="'.htmlspecialchars($info['matchString']).'">'.htmlspecialchars(t3lib_div::fixed_lgd_cs($info['matchString'],60)).'</span>'; 02930 if ($info['subst']['type']) { 02931 if (strlen($info['subst']['title'])) { 02932 $pInfo['title'].= '<br/>'.$preCode_B.'<b>'.$LANG->getLL('impexpcore_singlereco_title',1).'</b> '.htmlspecialchars(t3lib_div::fixed_lgd_cs($info['subst']['title'],60)); 02933 } 02934 if (strlen($info['subst']['description'])) { 02935 $pInfo['title'].= '<br/>'.$preCode_B.'<b>'.$LANG->getLL('impexpcore_singlereco_descr',1).'</b> '.htmlspecialchars(t3lib_div::fixed_lgd_cs($info['subst']['description'],60)); 02936 } 02937 $pInfo['title'].= '<br/>'.$preCode_B. 02938 ($info['subst']['type'] == 'file' ? $LANG->getLL('impexpcore_singlereco_filename',1).' <b>'.$info['subst']['relFileName'].'</b>' : ''). 02939 ($info['subst']['type'] == 'string' ? $LANG->getLL('impexpcore_singlereco_value',1).' <b>'.$info['subst']['tokenValue'].'</b>' : ''). 02940 ($info['subst']['type'] == 'db' ? $LANG->getLL('impexpcore_softrefsel_record',1).' <b>'.$info['subst']['recordRef'].'</b>' : ''); 02941 } 02942 $pInfo['ref'] = 'SOFTREF'; 02943 $pInfo['size'] = ''; 02944 $pInfo['class'] = 'bgColor3'; 02945 $pInfo['type'] = 'softref'; 02946 $pInfo['_softRefInfo'] = $info; 02947 $pInfo['type'] = 'softref'; 02948 if ($info['error'] && !t3lib_div::inList('editable,exclude',$this->softrefCfg[$info['subst']['tokenID']]['mode'])) { 02949 $pInfo['msg'].= $info['error']; 02950 } 02951 $lines[] = $pInfo; 02952 02953 // Add relations: 02954 if ($info['subst']['type'] == 'db') { 02955 list($tempTable, $tempUid) = explode(':', $info['subst']['recordRef']); 02956 $this->addRelations(array(array('table' => $tempTable, 'id' => $tempUid, 'tokenID' => $info['subst']['tokenID'])),$lines,$preCode_B,array(), ''); 02957 } 02958 02959 // Add files: 02960 if ($info['subst']['type'] == 'file') { 02961 #debug($info); 02962 $this->addFiles(array($info['file_ID']),$lines,$preCode_B, '', $info['subst']['tokenID']); 02963 } 02964 } 02965 } 02966 } 02967 02980 function addRelations($rels,&$lines,$preCode,$recurCheck=array(),$htmlColorClass='') { 02981 02982 foreach($rels as $dat) { 02983 $table = $dat['table']; 02984 $uid = $dat['id']; 02985 $pInfo = array(); 02986 $Iprepend = ''; 02987 $staticFixed = FALSE; 02988 $pInfo['ref'] = $table.':'.$uid; 02989 if (!in_array($pInfo['ref'],$recurCheck)) { 02990 if ($uid > 0) { 02991 $record = $this->dat['header']['records'][$table][$uid]; 02992 if (!is_array($record)) { 02993 if ($this->isTableStatic($table) || $this->isExcluded($table, $uid) || ($dat['tokenID'] && !$this->includeSoftref($dat['tokenID']))) { 02994 $pInfo['title'] = htmlspecialchars('STATIC: '.$pInfo['ref']); 02995 $Iprepend = '_static'; 02996 $staticFixed = TRUE; 02997 } else { 02998 $doesRE = $this->doesRecordExist($table,$uid); 02999 $lostPath = $this->getRecordPath($table==='pages' ? $doesRE['uid'] : $doesRE['pid']); 03000 03001 $pInfo['title'] = htmlspecialchars($pInfo['ref']); 03002 $pInfo['title'] = '<span title="'.htmlspecialchars($lostPath).'">'.$pInfo['title'].'</span>'; 03003 03004 $pInfo['msg'] = 'LOST RELATION'.(!$doesRE ? ' (Record not found!)' : ' (Path: '.$lostPath.')'); 03005 $Iprepend = '_lost'; 03006 # debug('MISSING relation: '.$table.':'.$uid,1); 03007 } 03008 } else { 03009 $pInfo['title'] = htmlspecialchars($record['title']); 03010 $pInfo['title'] = '<span title="'.htmlspecialchars($this->getRecordPath($table==='pages' ? $record['uid'] : $record['pid'])).'">'.$pInfo['title'].'</span>'; 03011 03012 # $pInfo['size'] = $record['size']; 03013 } 03014 } else { // Negative values in relation fields. This is typically sys_language fields, fe_users fields etc. They are static values. They CAN theoretically be negative pointers to uids in other tables but this is so rarely used that it is not supported 03015 $pInfo['title'] = htmlspecialchars('FIXED: '.$pInfo['ref']); 03016 $staticFixed = TRUE; 03017 } 03018 03019 $pInfo['preCode'] = $preCode.' <img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'t3lib/gfx/rel_db'.$Iprepend.'.gif','width="13" height="12"').' align="top" title="'.htmlspecialchars($pInfo['ref']).'" alt="" />'; 03020 $pInfo['class'] = $htmlColorClass ? $htmlColorClass : 'bgColor3'; 03021 $pInfo['type'] = 'rel'; 03022 03023 if (!$staticFixed || $this->showStaticRelations) { 03024 $lines[] = $pInfo; 03025 if (is_array($record) && is_array($record['rels'])) { 03026 $this->addRelations($record['rels'], $lines, $preCode.' ', array_merge($recurCheck,array($pInfo['ref'])), $htmlColorClass); 03027 } 03028 } 03029 } else $this->error($pInfo['ref'].' was recursive...'); 03030 } 03031 } 03032 03045 function addFiles($rels,&$lines,$preCode,$htmlColorClass='',$tokenID='') { 03046 03047 foreach($rels as $ID) { 03048 03049 // Process file: 03050 $pInfo = array(); 03051 $fI = $this->dat['header']['files'][$ID]; 03052 if (!is_array($fI)) { 03053 if (!$tokenID || $this->includeSoftref($tokenID)) { 03054 $pInfo['msg'] = 'MISSING FILE: '.$ID; 03055 $this->error('MISSING FILE: '.$ID,1); 03056 } else { 03057 return; 03058 } 03059 } 03060 $pInfo['preCode'] = $preCode.' <img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'t3lib/gfx/rel_file.gif','width="13" height="12"').' align="top" alt="" />'; 03061 $pInfo['title'] = htmlspecialchars($fI['filename']); 03062 $pInfo['ref'] = 'FILE'; 03063 $pInfo['size'] = $fI['filesize']; 03064 $pInfo['class'] = $htmlColorClass ? $htmlColorClass : 'bgColor3'; 03065 $pInfo['type'] = 'file'; 03066 03067 // If import mode and there is a non-RTE softreference, check the destination directory: 03068 if ($this->mode==='import' && $tokenID && !$fI['RTE_ORIG_ID']) { 03069 if (isset($fI['parentRelFileName'])) { 03070 $pInfo['msg'] = 'Seems like this file is already referenced from within an HTML/CSS file. That takes precedence. '; 03071 } else { 03072 $testDirPrefix = dirname($fI['relFileName']).'/'; 03073 $testDirPrefix2 = $this->verifyFolderAccess($testDirPrefix); 03074 03075 if (!$testDirPrefix2) { 03076 $pInfo['msg'] = 'ERROR: There are no available filemounts to write file in! '; 03077 } elseif (strcmp($testDirPrefix,$testDirPrefix2)) { 03078 $pInfo['msg'] = 'File will be attempted written to "'.$testDirPrefix2.'". '; 03079 } 03080 } 03081 03082 03083 // Check if file exists: 03084 if (@file_exists(PATH_site.$fI['relFileName'])) { 03085 if ($this->update) { 03086 $pInfo['updatePath'].= 'File exists.'; 03087 } else { 03088 $pInfo['msg'].= 'File already exists! '; 03089 } 03090 } 03091 03092 // Check extension: 03093 $fileProcObj = &$this->getFileProcObj(); 03094 if ($fileProcObj->actionPerms['newFile']) { 03095 $testFI = t3lib_div::split_fileref(PATH_site.$fI['relFileName']); 03096 if (!$this->allowPHPScripts && !$fileProcObj->checkIfAllowed($testFI['fileext'], $testFI['path'], $testFI['file'])) { 03097 $pInfo['msg'].= 'File extension was not allowed!'; 03098 } 03099 } else $pInfo['msg'] = 'You user profile does not allow you to create files on the server!'; 03100 } 03101 03102 $pInfo['showDiffContent'] = substr($this->fileIDMap[$ID],strlen(PATH_site)); 03103 03104 $lines[] = $pInfo; 03105 unset($this->remainHeader['files'][$ID]); 03106 03107 // RTE originals: 03108 if ($fI['RTE_ORIG_ID']) { 03109 $ID = $fI['RTE_ORIG_ID']; 03110 $pInfo = array(); 03111 $fI = $this->dat['header']['files'][$ID]; 03112 if (!is_array($fI)) { 03113 $pInfo['msg'] = 'MISSING RTE original FILE: '.$ID; 03114 $this->error('MISSING RTE original FILE: '.$ID,1); 03115 } 03116 03117 $pInfo['showDiffContent'] = substr($this->fileIDMap[$ID],strlen(PATH_site)); 03118 03119 $pInfo['preCode'] = $preCode.' <img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'t3lib/gfx/rel_file.gif','width="13" height="12"').' align="top" alt="" />'; 03120 $pInfo['title'] = htmlspecialchars($fI['filename']).' <em>(Original)</em>'; 03121 $pInfo['ref'] = 'FILE'; 03122 $pInfo['size'] = $fI['filesize']; 03123 $pInfo['class'] = $htmlColorClass ? $htmlColorClass : 'bgColor3'; 03124 $pInfo['type'] = 'file'; 03125 $lines[] = $pInfo; 03126 unset($this->remainHeader['files'][$ID]); 03127 } 03128 03129 // External resources: 03130 if (is_array($fI['EXT_RES_ID'])) { 03131 foreach($fI['EXT_RES_ID'] as $ID) { 03132 $pInfo = array(); 03133 $fI = $this->dat['header']['files'][$ID]; 03134 if (!is_array($fI)) { 03135 $pInfo['msg'] = 'MISSING External Resource FILE: '.$ID; 03136 $this->error('MISSING External Resource FILE: '.$ID,1); 03137 } else { 03138 $pInfo['updatePath'] = $fI['parentRelFileName']; 03139 } 03140 03141 $pInfo['showDiffContent'] = substr($this->fileIDMap[$ID],strlen(PATH_site)); 03142 03143 $pInfo['preCode'] = $preCode.' <img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'t3lib/gfx/rel_file.gif','width="13" height="12"').' align="top" alt="" />'; 03144 $pInfo['title'] = htmlspecialchars($fI['filename']).' <em>(Resource)</em>'; 03145 $pInfo['ref'] = 'FILE'; 03146 $pInfo['size'] = $fI['filesize']; 03147 $pInfo['class'] = $htmlColorClass ? $htmlColorClass : 'bgColor3'; 03148 $pInfo['type'] = 'file'; 03149 $lines[] = $pInfo; 03150 unset($this->remainHeader['files'][$ID]); 03151 } 03152 } 03153 } 03154 } 03155 03163 function checkDokType($checkTable,$doktype) { 03164 global $PAGES_TYPES; 03165 $allowedTableList = isset($PAGES_TYPES[$doktype]['allowedTables']) ? $PAGES_TYPES[$doktype]['allowedTables'] : $PAGES_TYPES['default']['allowedTables']; 03166 $allowedArray = t3lib_div::trimExplode(',',$allowedTableList,1); 03167 if (strstr($allowedTableList,'*') || in_array($checkTable,$allowedArray)) { // If all tables or the table is listed as a allowed type, return true 03168 return true; 03169 } 03170 } 03171 03179 function renderControls($r) { 03180 global $LANG; 03181 03182 if ($this->mode==='export') { 03183 return ($r['type']=='record' ? '<input type="checkbox" name="tx_impexp[exclude]['.$r['ref'].']" value="1" /> '.$LANG->getLL('impexpcore_singlereco_exclude',1) : 03184 ($r['type']=='softref' ? $this->softrefSelector($r['_softRefInfo']) : '')); 03185 } else { // During import 03186 03187 // For softreferences with editable fields: 03188 if ($r['type']=='softref' && is_array($r['_softRefInfo']['subst']) && $r['_softRefInfo']['subst']['tokenID']) { 03189 $tokenID = $r['_softRefInfo']['subst']['tokenID']; 03190 $cfg = $this->softrefCfg[$tokenID]; 03191 if ($cfg['mode'] === 'editable') { 03192 return 03193 (strlen($cfg['title']) ? '<b>'.htmlspecialchars($cfg['title']).'</b><br/>' : ''). 03194 htmlspecialchars($cfg['description']).'<br/> 03195 <input type="text" name="tx_impexp[softrefInputValues]['.$tokenID.']" value="'.htmlspecialchars(isset($this->softrefInputValues[$tokenID]) ? $this->softrefInputValues[$tokenID] : $cfg['defValue']).'" />'; 03196 } 03197 } 03198 } 03199 } 03200 03207 function softrefSelector($cfg) { 03208 global $LANG; 03209 03210 // Looking for file ID if any: 03211 $fI = $cfg['file_ID'] ? $this->dat['header']['files'][$cfg['file_ID']] : array(); 03212 03213 // Substitution scheme has to be around and RTE images MUST be exported. 03214 if (is_array($cfg['subst']) && $cfg['subst']['tokenID'] && !$fI['RTE_ORIG_ID']) { 03215 03216 // Create options: 03217 $optValues = array(); 03218 $optValues[''] = ''; 03219 $optValues['editable'] = $LANG->getLL('impexpcore_softrefsel_editable'); 03220 $optValues['exclude'] = $LANG->getLL('impexpcore_softrefsel_exclude'); 03221 03222 // Get current value: 03223 $value = $this->softrefCfg[$cfg['subst']['tokenID']]['mode']; 03224 03225 // Render options selector: 03226 $selectorbox = $this->renderSelectBox('tx_impexp[softrefCfg]['.$cfg['subst']['tokenID'].'][mode]',$value,$optValues).'<br/>'; 03227 03228 if ($value === 'editable') { 03229 03230 $descriptionField = ''; 03231 03232 // Title: 03233 if (strlen($cfg['subst']['title'])) { 03234 $descriptionField.= ' 03235 <input type="hidden" name="tx_impexp[softrefCfg]['.$cfg['subst']['tokenID'].'][title]" value="'.htmlspecialchars($cfg['subst']['title']).'" /> 03236 <b>'.htmlspecialchars($cfg['subst']['title']).'</b><br/>'; 03237 } 03238 03239 // Description: 03240 if (!strlen($cfg['subst']['description'])) { 03241 $descriptionField.= ' 03242 '.$LANG->getLL('impexpcore_printerror_description',1).'<br/> 03243 <input type="text" name="tx_impexp[softrefCfg]['.$cfg['subst']['tokenID'].'][description]" value="'.htmlspecialchars($this->softrefCfg[$cfg['subst']['tokenID']]['description']).'" />'; 03244 } else { 03245 $descriptionField.= ' 03246 03247 <input type="hidden" name="tx_impexp[softrefCfg]['.$cfg['subst']['tokenID'].'][description]" value="'.htmlspecialchars($cfg['subst']['description']).'" />'. 03248 htmlspecialchars($cfg['subst']['description']); 03249 } 03250 03251 // Default Value: 03252 $descriptionField.= '<input type="hidden" name="tx_impexp[softrefCfg]['.$cfg['subst']['tokenID'].'][defValue]" value="'.htmlspecialchars($cfg['subst']['tokenValue']).'" />'; 03253 03254 } else $descriptionField = ''; 03255 03256 return $selectorbox.$descriptionField; 03257 } 03258 } 03259 03260 03261 03262 03263 03264 03265 03266 03267 03268 03269 03270 03271 /***************************** 03272 * 03273 * Helper functions of kinds 03274 * 03275 *****************************/ 03276 03283 function isTableStatic($table) { 03284 global $TCA; 03285 03286 if (is_array($TCA[$table])) { 03287 return $TCA[$table]['ctrl']['is_static'] || in_array($table, $this->relStaticTables) || in_array('_ALL', $this->relStaticTables); 03288 } 03289 } 03290 03297 function inclRelation($table) { 03298 global $TCA; 03299 03300 if (is_array($TCA[$table])) { 03301 return (in_array($table, $this->relOnlyTables) || in_array('_ALL', $this->relOnlyTables)) && $GLOBALS['BE_USER']->check('tables_select',$table); 03302 } 03303 } 03304 03312 function isExcluded($table,$uid) { 03313 global $TCA; 03314 03315 return $this->excludeMap[$table.':'.$uid] ? TRUE : FALSE; 03316 } 03317 03324 function includeSoftref($tokenID) { 03325 return $tokenID && !t3lib_div::inList('exclude,editable', $this->softrefCfg[$tokenID]['mode']); 03326 } 03327 03334 function isReferenceField($conf) { 03335 return ($conf['type']=='group' && $conf['internal_type']=='db') || ($conf['type']=='select' && $conf['foreign_table']); 03336 } 03337 03344 function checkPID($pid) { 03345 global $BE_USER; 03346 03347 if (!isset($this->checkPID_cache[$pid])) { 03348 $this->checkPID_cache[$pid] = (boolean)$BE_USER->isInWebMount($pid); 03349 } 03350 03351 return $this->checkPID_cache[$pid]; 03352 } 03353 03361 function dontIgnorePid($table, $uid) { 03362 return $this->import_mode[$table.':'.$uid]!=='ignore_pid' && 03363 (!$this->global_ignore_pid || $this->import_mode[$table.':'.$uid]==='respect_pid'); 03364 } 03365 03374 function doesRecordExist($table,$uid,$fields='') { 03375 return t3lib_BEfunc::getRecord($table, $uid, $fields ? $fields : 'uid,pid'); 03376 } 03377 03384 function getRecordPath($pid) { 03385 if (!isset($this->cache_getRecordPath[$pid])) { 03386 $clause = $GLOBALS['BE_USER']->getPagePermsClause(1); 03387 $this->cache_getRecordPath[$pid] = (string)t3lib_BEfunc::getRecordPath($pid, $clause, 20); 03388 } 03389 03390 return $this->cache_getRecordPath[$pid]; 03391 } 03392 03401 function renderSelectBox($prefix,$value,$optValues) { 03402 $opt = array(); 03403 $isSelFlag = 0; 03404 reset($optValues); 03405 while(list($k,$v) = each($optValues)) { 03406 $sel = (!strcmp($k,$value) ? ' selected="selected"' : ''); 03407 if ($sel) $isSelFlag++; 03408 $opt[] = '<option value="'.htmlspecialchars($k).'"'.$sel.'>'.htmlspecialchars($v).'</option>'; 03409 } 03410 if (!$isSelFlag && strcmp('',$value)) { 03411 $opt[] = '<option value="'.htmlspecialchars($value).'" selected="selected">'.htmlspecialchars("['".$value."']").'</option>'; 03412 } 03413 return '<select name="'.$prefix.'">'.implode('',$opt).'</select>'; 03414 } 03415 03425 function compareRecords($databaseRecord, $importRecord, $table, $inverseDiff=FALSE) { 03426 global $TCA, $LANG; 03427 03428 // Initialize: 03429 $output = array(); 03430 $t3lib_diff_Obj = t3lib_div::makeInstance('t3lib_diff'); 03431 03432 // Check if both inputs are records: 03433 if (is_array($databaseRecord) && is_array($importRecord)) { 03434 03435 // Traverse based on database record 03436 foreach($databaseRecord as $fN => $value) { 03437 if (is_array($TCA[$table]['columns'][$fN]) && $TCA[$table]['columns'][$fN]['config']['type']!='passthrough') { 03438 if (isset($importRecord[$fN])) { 03439 if (strcmp(trim($databaseRecord[$fN]), trim($importRecord[$fN]))) { 03440 03441 // Create diff-result: 03442 $output[$fN] = $t3lib_diff_Obj->makeDiffDisplay( 03443 t3lib_BEfunc::getProcessedValue($table,$fN,!$inverseDiff ? $importRecord[$fN] : $databaseRecord[$fN] ,0,1,1), 03444 t3lib_BEfunc::getProcessedValue($table,$fN,!$inverseDiff ? $databaseRecord[$fN] : $importRecord[$fN] ,0,1,1) 03445 ); 03446 } 03447 unset($importRecord[$fN]); 03448 } else { 03449 // This will tell us if the field is not in the import file, but who cares? It is totally ok that the database contains fields that are not in the import, isn't it (extensions could be installed that added these fields!)? 03450 #$output[$fN] = '<b>Field missing</b> in import file'; 03451 } 03452 } 03453 } 03454 03455 // Traverse remaining in import record: 03456 foreach($importRecord as $fN => $value) { 03457 if (is_array($TCA[$table]['columns'][$fN]) && $TCA[$table]['columns'][$fN]['config']['type']!='passthrough') { 03458 $output[$fN] = '<b>Field missing</b> in database'; 03459 } 03460 } 03461 03462 // Create output: 03463 if (count($output)) { 03464 $tRows = array(); 03465 foreach($output as $fN => $state) { 03466 $tRows[] = ' 03467 <tr> 03468 <td class="bgColor5">'.$LANG->sL($TCA[$table]['columns'][$fN]['label'],1).' ('.htmlspecialchars($fN).')</td> 03469 <td class="bgColor4">'.$state.'</td> 03470 </tr> 03471 '; 03472 } 03473 03474 $output = '<table border="0" cellpadding="0" cellspacing="1">'.implode('',$tRows).'</table>'; 03475 } else { 03476 $output = 'Match'; 03477 } 03478 03479 return '<b class="nobr">['.htmlspecialchars($table.':'.$importRecord['uid'].' => '.$databaseRecord['uid']).']:</b> '.$output; 03480 } 03481 03482 03483 return 'ERROR: One of the inputs were not an array!'; 03484 } 03485 03492 function getRTEoriginalFilename($string) { 03493 // If "magic image": 03494 if (t3lib_div::isFirstPartOfStr($string,'RTEmagicC_')) { 03495 // Find original file: 03496 $pI = pathinfo(substr($string,strlen('RTEmagicC_'))); 03497 $filename = substr($pI['basename'],0,-strlen('.'.$pI['extension'])); 03498 $origFilePath = 'RTEmagicP_'.$filename; 03499 03500 return $origFilePath; 03501 } 03502 } 03503 03509 function &getFileProcObj() { 03510 global $FILEMOUNTS, $TYPO3_CONF_VARS, $BE_USER; 03511 03512 if (!is_object($this->fileProcObj)) { 03513 $this->fileProcObj = t3lib_div::makeInstance('t3lib_extFileFunctions'); 03514 $this->fileProcObj->init($FILEMOUNTS, $TYPO3_CONF_VARS['BE']['fileExtensions']); 03515 $this->fileProcObj->init_actionPerms($BE_USER->user['fileoper_perms']); 03516 } 03517 03518 return $this->fileProcObj; 03519 } 03520 03521 03522 03523 03524 03525 03526 03527 03528 03529 03530 /***************************** 03531 * 03532 * Error handling 03533 * 03534 *****************************/ 03535 03542 function error($msg) { 03543 $this->errorLog[]=$msg; 03544 } 03545 03551 function printErrorLog() { 03552 return count($this->errorLog) ? t3lib_div::view_array($this->errorLog) : ''; 03553 } 03554 } 03555 03556 03557 03558 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/impexp/class.tx_impexp.php']) { 03559 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/impexp/class.tx_impexp.php']); 03560 } 03561 ?>