Fixed final details around Import/Export. Unless important bugs surface this is it...
authorKasper Skårhøj <kasper@typo3.org>
Sat, 15 Jan 2005 19:23:15 +0000 (19:23 +0000)
committerKasper Skårhøj <kasper@typo3.org>
Sat, 15 Jan 2005 19:23:15 +0000 (19:23 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@533 709f56b5-9817-0410-a4d7-c38de5d9e867

t3lib/class.t3lib_befunc.php
t3lib/class.t3lib_softrefproc.php
t3lib/class.t3lib_tceforms.php
typo3/sysext/impexp/class.tx_impexp.php
typo3/sysext/impexp/doc/TODO.txt
typo3/sysext/impexp/locallang_csh.xml

index 87047f0..6c0dfa1 100755 (executable)
@@ -1773,9 +1773,10 @@ class t3lib_BEfunc       {
         * @param       string          $value is the value of that field from a selected record
         * @param       integer         $fixed_lgd_chars is the max amount of characters the value may occupy
         * @param       boolean         $defaultPassthrough flag means that values for columns that has no conversion will just be pass through directly (otherwise cropped to 200 chars or returned as "N/A")
+        * @param       boolean         If set, no records will be looked up, UIDs are just shown.
         * @return      string
         */
-       function getProcessedValue($table,$col,$value,$fixed_lgd_chars=0,$defaultPassthrough=0) {
+       function getProcessedValue($table,$col,$value,$fixed_lgd_chars=0,$defaultPassthrough=0,$noRecordLookup=FALSE)   {
                global $TCA;
                        // Load full TCA for $table
                t3lib_div::loadTCA($table);
@@ -1792,26 +1793,30 @@ class t3lib_BEfunc      {
                                        if ($theColConf['MM'])  {
                                                $l='N/A';
                                        } else {
-                                               $l=t3lib_BEfunc::getLabelFromItemlist($table,$col,$value);
-                                               $l=$GLOBALS['LANG']->sL($l);
+                                               $l = t3lib_BEfunc::getLabelFromItemlist($table,$col,$value);
+                                               $l = $GLOBALS['LANG']->sL($l);
                                                if ($theColConf['foreign_table'] && !$l && $TCA[$theColConf['foreign_table']])  {
-                                                       $rParts = t3lib_div::trimExplode(',',$value,1);
-                                                       reset($rParts);
-                                                       $lA=array();
-                                                       while(list(,$rVal)=each($rParts))       {
-                                                               $rVal = intval($rVal);
-                                                               if ($rVal>0) {
-                                                                       $r=t3lib_BEfunc::getRecord($theColConf['foreign_table'],$rVal);
-                                                               } else {
-                                                                       $r=t3lib_BEfunc::getRecord($theColConf['neg_foreign_table'],-$rVal);
-                                                               }
-                                                               if (is_array($r))       {
-                                                                       $lA[]=$GLOBALS['LANG']->sL($rVal>0?$theColConf['foreign_table_prefix']:$theColConf['neg_foreign_table_prefix']).t3lib_BEfunc::getRecordTitle($rVal>0?$theColConf['foreign_table']:$theColConf['neg_foreign_table'],$r);
-                                                               } else {
-                                                                       $lA[]=$rVal?'['.$rVal.'!]':'';
+                                                       if ($noRecordLookup)    {
+                                                               $l = $value;
+                                                       } else {
+                                                               $rParts = t3lib_div::trimExplode(',',$value,1);
+                                                               reset($rParts);
+                                                               $lA = array();
+                                                               while(list(,$rVal)=each($rParts))       {
+                                                                       $rVal = intval($rVal);
+                                                                       if ($rVal>0) {
+                                                                               $r=t3lib_BEfunc::getRecord($theColConf['foreign_table'],$rVal);
+                                                                       } else {
+                                                                               $r=t3lib_BEfunc::getRecord($theColConf['neg_foreign_table'],-$rVal);
+                                                                       }
+                                                                       if (is_array($r))       {
+                                                                               $lA[]=$GLOBALS['LANG']->sL($rVal>0?$theColConf['foreign_table_prefix']:$theColConf['neg_foreign_table_prefix']).t3lib_BEfunc::getRecordTitle($rVal>0?$theColConf['foreign_table']:$theColConf['neg_foreign_table'],$r);
+                                                                       } else {
+                                                                               $lA[]=$rVal?'['.$rVal.'!]':'';
+                                                                       }
                                                                }
+                                                               $l = implode(',',$lA);
                                                        }
-                                                       $l=implode(',',$lA);
                                                }
                                        }
                                break;
index 8c7f15a..ccaf443 100755 (executable)
@@ -588,7 +588,7 @@ class t3lib_softrefproc {
        function fileadminReferences($content, &$elements)      {
 
                        // Fileadmin files are found
-               $parts = preg_split("/([^[:alnum:]]+)(".$this->fileAdminDir."\/[^[:space:]\"']*)/", ' '.$content.' ',10000, PREG_SPLIT_DELIM_CAPTURE);
+               $parts = preg_split("/([^[:alnum:]]+)(".$this->fileAdminDir."\/[^[:space:]\"'<>]*)/", ' '.$content.' ',10000, PREG_SPLIT_DELIM_CAPTURE);
 
                        // Traverse files:
                foreach($parts as $idx => $value)       {
index 3f89f0b..9325bb4 100755 (executable)
@@ -3959,7 +3959,7 @@ class t3lib_TCEforms      {
                                                $fDat['details']||$fDat['syntax']||$fDat['image_descr']||$fDat['image']||$fDat['seeAlso']
                                        ).
                                        '</td><td valign="top"><span class="typo3-TCEforms-helpText">'.
-                                       $GLOBALS['LANG']->hscAndCharConv($fDat['description'],1).
+                                       $GLOBALS['LANG']->hscAndCharConv(strip_tags($fDat['description']),1).
                                        '</span></td></tr></table>';
                }
        }
index e4a4bce..b35ce35 100755 (executable)
@@ -239,6 +239,7 @@ class tx_impexp {
        var $import_data = array();                     // Internal data accumulation for writing records during import
        var $errorLog = array();                        // Error log.
        var $cache_getRecordPath = array();     // Cache for record paths
+       var $checkPID_cache = array();          // Cache of checkPID values.
 
        var $compress = 0;                                      // Set internally if the gzcompress function exists
        var $dat = array();                                     // Internal import/export memory
@@ -486,40 +487,42 @@ class tx_impexp {
         */
        function export_addRecord($table,$row,$relationLevel=0) {
                if (strcmp($table,'') && is_array($row) && $row['uid']>0 && !$this->excludeMap[$table.':'.$row['uid']]) {
-                       if (!isset($this->dat['records'][$table.':'.$row['uid']]))      {
-
-                                       // Prepare header info:
-                               $headerInfo = array();
-                               $headerInfo['uid'] = $row['uid'];
-                               $headerInfo['pid'] = $row['pid'];
-                               $headerInfo['title'] = t3lib_div::fixed_lgd_cs(t3lib_BEfunc::getRecordTitle($table,$row),40);
-                               $headerInfo['size'] = strlen(serialize($row));
-                               if ($relationLevel)     {
-                                       $headerInfo['relationLevel'] = $relationLevel;
-                               }
+                       if ($this->checkPID($table==='pages' ? $row['uid'] : $row['pid']))      {
+                               if (!isset($this->dat['records'][$table.':'.$row['uid']]))      {
+
+                                               // Prepare header info:
+                                       $headerInfo = array();
+                                       $headerInfo['uid'] = $row['uid'];
+                                       $headerInfo['pid'] = $row['pid'];
+                                       $headerInfo['title'] = t3lib_div::fixed_lgd_cs(t3lib_BEfunc::getRecordTitle($table,$row),40);
+                                       $headerInfo['size'] = strlen(serialize($row));
+                                       if ($relationLevel)     {
+                                               $headerInfo['relationLevel'] = $relationLevel;
+                                       }
 
-                                       // If record content is not too large in size, set the header content and add the rest:
-                               if ($headerInfo['size']<$this->maxRecordSize)   {
+                                               // If record content is not too large in size, set the header content and add the rest:
+                                       if ($headerInfo['size']<$this->maxRecordSize)   {
 
-                                               // Set the header summary:
-                                       $this->dat['header']['records'][$table][$row['uid']] = $headerInfo;
+                                                       // Set the header summary:
+                                               $this->dat['header']['records'][$table][$row['uid']] = $headerInfo;
 
-                                               // Create entry in the PID lookup:
-                                       $this->dat['header']['pid_lookup'][$row['pid']][$table][$row['uid']]=1;
+                                                       // Create entry in the PID lookup:
+                                               $this->dat['header']['pid_lookup'][$row['pid']][$table][$row['uid']]=1;
 
-                                               // Data:
-                                       $this->dat['records'][$table.':'.$row['uid']] = array();
-                                       $this->dat['records'][$table.':'.$row['uid']]['data'] = $row;
-                                       $this->dat['records'][$table.':'.$row['uid']]['rels'] = $this->getRelations($table,$row);
+                                                       // Data:
+                                               $this->dat['records'][$table.':'.$row['uid']] = array();
+                                               $this->dat['records'][$table.':'.$row['uid']]['data'] = $row;
+                                               $this->dat['records'][$table.':'.$row['uid']]['rels'] = $this->getRelations($table,$row);
 
-                                               // Add information about the relations in the record in the header:
-                                       $this->dat['header']['records'][$table][$row['uid']]['rels'] = $this->flatDBrels($this->dat['records'][$table.':'.$row['uid']]['rels']);
+                                                       // Add information about the relations in the record in the header:
+                                               $this->dat['header']['records'][$table][$row['uid']]['rels'] = $this->flatDBrels($this->dat['records'][$table.':'.$row['uid']]['rels']);
 
-                                               // Add information about the softrefs to header:
-                                       $this->dat['header']['records'][$table][$row['uid']]['softrefs'] = $this->flatSoftRefs($this->dat['records'][$table.':'.$row['uid']]['rels']);
+                                                       // Add information about the softrefs to header:
+                                               $this->dat['header']['records'][$table][$row['uid']]['softrefs'] = $this->flatSoftRefs($this->dat['records'][$table.':'.$row['uid']]['rels']);
 
-                               } else $this->error('Record '.$table.':'.$row['uid'].' was larger than maxRecordSize ('.t3lib_div::formatSize($this->maxRecordSize).')');
-                       } else $this->error('Record '.$table.':'.$row['uid'].' already added.');
+                                       } else $this->error('Record '.$table.':'.$row['uid'].' was larger than maxRecordSize ('.t3lib_div::formatSize($this->maxRecordSize).')');
+                               } else $this->error('Record '.$table.':'.$row['uid'].' already added.');
+                       } else $this->error('Record '.$table.':'.$row['uid'].' was outside your DB mounts!');
                }
        }
 
@@ -1624,8 +1627,23 @@ class tx_impexp {
                                $this->import_newId[$table.':'.$ID] = array('table' => $table, 'uid' => $uid);
                                if ($table=='pages')    $this->import_newId_pids[$uid] = $ID;
 
+                                       // Set main record data:
                                $this->import_data[$table][$ID] = $record;
                                $this->import_data[$table][$ID]['tx_impexp_origuid'] = $this->import_data[$table][$ID]['uid'];
+
+                                       // Reset permission data:
+                               if ($table==='pages')   {
+                                               // Have to reset the user/group IDs so pages are owned by importing user. Otherwise strange things may happen for non-admins!
+                                       unset($this->import_data[$table][$ID]['perms_userid']);
+                                       unset($this->import_data[$table][$ID]['perms_groupid']);
+
+                                               // user/group/everybody settings is kept - but these might still conflict with possibilities for writing the content!"
+                                       #unset($this->import_data[$table][$ID]['perms_user']);
+                                       #unset($this->import_data[$table][$ID]['perms_group']);
+                                       #unset($this->import_data[$table][$ID]['perms_everybody']);
+                               }
+
+                                       // PID and UID:
                                unset($this->import_data[$table][$ID]['uid']);
                                if (t3lib_div::testInt($ID))    {       // Updates:
                                        unset($this->import_data[$table][$ID]['pid']);
@@ -1639,6 +1657,7 @@ class tx_impexp {
                                        }
                                }
 
+                                       // Setting db/file blank:
                                reset($this->dat['records'][$table.':'.$uid]['rels']);
                                while(list($field,$config) = each($this->dat['records'][$table.':'.$uid]['rels']))      {
                                        switch((string)$config['type']) {
@@ -1650,8 +1669,8 @@ class tx_impexp {
                                                break;
                                                case 'flex':
                                                                // Fixed later in setFlexFormRelations()
-                                                               // In the meantime we set NO value for flexforms:
-                                               #       $this->import_data[$table][$ID][$field] = '';
+                                                               // 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!)
+                                                       $this->import_data[$table][$ID][$field] = '';
                                                break;
                                        }
                                }
@@ -1802,7 +1821,7 @@ class tx_impexp {
 
                                #debug('FOUND: '.$relDat['table'].':'.$relDat['id'],1);
                                $valArray[] = $relDat['table'].'_'.$this->import_mapId[$relDat['table']][$relDat['id']];
-                       } elseif ($this->isTableStatic($relDat['table']) || $this->isExcluded($relDat['table'], $relDat['id'])) {
+                       } 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.
 
                                #debug('STATIC: '.$relDat['table'].':'.$relDat['id'],1);
                                $valArray[] = $relDat['table'].'_'.$relDat['id'];
@@ -2425,7 +2444,6 @@ class tx_impexp {
         */
        function loadFile($filename,$all=0)     {
                if (@is_file($filename))        {
-
                        $fI = pathinfo($filename);
                        if (strtolower($fI['extension'])=='xml')        {
                                        // XML:
@@ -2837,7 +2855,9 @@ class tx_impexp {
                                if ($TCA[$table]['ctrl']['is_static'])  {$pInfo['msg'].="TABLE '".$table."' is a STATIC TABLE! ";}
                                if ($TCA[$table]['ctrl']['rootLevel'])  {$pInfo['msg'].="TABLE '".$table."' will be inserted on ROOT LEVEL! ";}
 
+                               $diffInverse = FALSE;
                                if ($this->update)      {
+                                       $diffInverse = TRUE;    // In case of update-PREVIEW we swap the diff-sources.
                                        $recInf = $this->doesRecordExist($table, $uid, $this->showDiff ? '*' : '');
                                        $pInfo['updatePath']= $recInf ? htmlspecialchars($this->getRecordPath($recInf['pid'])) : '<b>NEW!</b>';
 
@@ -2862,10 +2882,11 @@ class tx_impexp {
                                if ($this->showDiff)    {
                                                // For IMPORTS, get new id:
                                        if ($newUid = $this->import_mapId[$table][$uid])        {
+                                               $diffInverse = FALSE;
                                                $recInf = $this->doesRecordExist($table, $newUid, '*');
                                        }
                                        if (is_array($recInf))  {
-                                               $pInfo['showDiffContent'] = $this->compareRecords($this->dat['records'][$table.':'.$uid]['data'], $recInf, $table);
+                                               $pInfo['showDiffContent'] = $this->compareRecords($recInf, $this->dat['records'][$table.':'.$uid]['data'], $table, $diffInverse);
                                        }
                                }
                        }
@@ -3313,6 +3334,22 @@ class tx_impexp {
        }
 
        /**
+        * Checking if a PID is in the webmounts of the user
+        *
+        * @param       integer         Page ID to check
+        * @return      boolean         True if OK
+        */
+       function checkPID($pid) {
+               global $BE_USER;
+
+               if (!isset($this->checkPID_cache[$pid]))        {
+                       $this->checkPID_cache[$pid] = (boolean)$BE_USER->isInWebMount($pid);
+               }
+
+               return $this->checkPID_cache[$pid];
+       }
+
+       /**
         * Checks if the position of an updated record is configured to be corrected. This can be disabled globally and changed for elements individually.
         *
         * @param       string          Table name
@@ -3377,12 +3414,13 @@ class tx_impexp {
        /**
         * Compares two records, the current database record and the one from the import memory. Will return HTML code to show any differences between them!
         *
-        * @param       array           Database record, all fields
-        * @param       array           Import memorys record for the same table/uid, all fields
+        * @param       array           Database record, all fields (new values)
+        * @param       array           Import memorys record for the same table/uid, all fields (old values)
         * @param       string          The table name of the record
+        * @param       boolean         Inverse the diff view (switch red/green, needed for pre-update difference view)
         * @return      string          HTML
         */
-       function compareRecords($databaseRecord, $importRecord, $table) {
+       function compareRecords($databaseRecord, $importRecord, $table, $inverseDiff=FALSE)     {
                global $TCA, $LANG;
 
                        // Initialize:
@@ -3400,13 +3438,14 @@ class tx_impexp {
 
                                                                // Create diff-result:
                                                        $output[$fN] = $t3lib_diff_Obj->makeDiffDisplay(
-                                                               t3lib_BEfunc::getProcessedValue($table,$fN,$databaseRecord[$fN],0,1),
-                                                               t3lib_BEfunc::getProcessedValue($table,$fN,$importRecord[$fN],0,1)
+                                                               t3lib_BEfunc::getProcessedValue($table,$fN,!$inverseDiff ? $importRecord[$fN] : $databaseRecord[$fN] ,0,1,1),
+                                                               t3lib_BEfunc::getProcessedValue($table,$fN,!$inverseDiff ? $databaseRecord[$fN] : $importRecord[$fN] ,0,1,1)
                                                        );
                                                }
                                                unset($importRecord[$fN]);
                                        } else {
-                                               $output[$fN] = '<b>Field missing</b> in import file';
+                                                       // 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!)?
+                                               #$output[$fN] = '<b>Field missing</b> in import file';
                                        }
                                }
                        }
@@ -3435,7 +3474,7 @@ class tx_impexp {
                                $output = 'Match';
                        }
 
-                       return '<b class="nobr">['.htmlspecialchars($table.':'.$databaseRecord['uid'].' => '.$importRecord['uid']).']:</b> '.$output;
+                       return '<b class="nobr">['.htmlspecialchars($table.':'.$importRecord['uid'].' => '.$databaseRecord['uid']).']:</b> '.$output;
                }
 
 
index 0fa8c15..2ae7a4a 100755 (executable)
@@ -36,3 +36,6 @@ Input Charset conversion NOTE:
        - XML/PHP5: May be converted automatically without we can do anything.
                - May break encapsulated text files which are not base64 encoded
                - May break serialized strings
+
+Size limit:
+- The import/export module may die (without warnings!) if the amounts of data becomes too large. For instance a file of 12Mb could not be handled with 32 MB ram configured for PHP. Of course the max_exec_time may also expire during a large import/export.
index 176a2ee..781f66c 100755 (executable)
@@ -26,7 +26,9 @@
 
 The export format observes all TYPO3s methods for relations between the records in the export file. But you will have to configure how these relations are maintained, at least to some degree. Sometimes you would want to include records referred to, at other times you surely want to keep the original mapping. That depends on your objectives with the export.
 
-Regardless of your configuration for export you will always see a complete reflection of all chosen records and their internal relations in the preview display found in the bottom of the export module page</label>
+Regardless of your configuration for export you will always see a complete reflection of all chosen records and their internal relations in the preview display found in the bottom of the export module page.
+
+&lt;b&gt;Error messages:&lt;/b&gt; Remember to consult the Message-tab before exporting if there are any error messages there!</label>
                        <label index="_export.seeAlso">xMOD_tx_impexp:import</label>
                        <label index="_export.image">EXT:impexp/cshimages/export.png, 
 EXT:impexp/cshimages/export1.png, 
@@ -125,6 +127,10 @@ Entering a file name to save to makes it possible to write your export directly
                        <label index="_fileFormat.image">EXT:impexp/cshimages/fileformat.png</label>
                        <label index="import.alttitle">Importing TYPO3 records</label>
                        <label index="import.description">To import TYPO3 T3D/XML files into the page tree you click any page in the page tree (including the root page!), select &quot;More options&quot; (requires the extensions &quot;extra_page_cm_options&quot; to be installed) and then &quot;Import from .t3d&quot;. This will bring up the import interface where you can select a file to import or upload a new one.</label>
+                       <label index="import.details">&lt;b&gt;Tip: Import into a Sys Folder&lt;/b&gt;
+To make sure that no records are lost during the import, you can make yourself safe by importing into a SysFolder you create first. After the import you can move all records to the final destinations. An example of such a scenario is if you configured the export to include relations; In that case a number of records may follow the export outside the page tree structure you are exporting. To make sure that all of these external records are written to the database, importing into a SysFolder is a good idea.
+
+&lt;b&gt;Error messages:&lt;/b&gt; Remember to consult the Message-tab before/after importing to see if there are any error messages there!</label>
                        <label index="_import.seeAlso">xMOD_tx_impexp:export</label>
                        <label index="_import.image">EXT:impexp/cshimages/import.png</label>
                        <label index="importFile.alttitle">Select file to import</label>