Documentation TYPO3 par Ameos

class.tx_impexp.php

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->dontCo