More workspace stuff for beta.
[Packages/TYPO3.CMS.git] / typo3 / sysext / impexp / class.tx_impexp.php
index e4a4bce..abcceea 100755 (executable)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2004 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
  *
  *
  *
- *  201: class tx_impexp
+ *  202: class tx_impexp
  *
  *              SECTION: Initialize
- *  260:     function init($dontCompress=0,$mode='')
+ *  265:     function init($dontCompress=0,$mode='')
  *
  *              SECTION: Export / Init + Meta Data
- *  291:     function setHeaderBasics()
- *  315:     function setCharset($charset)
- *  330:     function setMetaData($title,$description,$notes,$packager_username,$packager_name,$packager_email)
- *  350:     function addThumbnail($imgFilepath)
+ *  296:     function setHeaderBasics()
+ *  320:     function setCharset($charset)
+ *  335:     function setMetaData($title,$description,$notes,$packager_username,$packager_name,$packager_email)
+ *  355:     function addThumbnail($imgFilepath)
  *
  *              SECTION: Export / Init Page tree
- *  388:     function setPageTree($idH)
- *  401:     function unsetExcludedSections($idH)
- *  423:     function flatInversePageTree($idH,$a=array())
- *  446:     function flatInversePageTree_pid($idH,$a=array(),$pid=-1)
+ *  393:     function setPageTree($idH)
+ *  406:     function unsetExcludedSections($idH)
+ *  428:     function flatInversePageTree($idH,$a=array())
+ *  451:     function flatInversePageTree_pid($idH,$a=array(),$pid=-1)
  *
  *              SECTION: Export
- *  485:     function export_addRecord($table,$row,$relationLevel=0)
- *  533:     function export_addDBRelations($relationLevel=0)
- *  637:     function export_addDBRelations_registerRelation($fI, &$addR, $tokenID='')
- *  661:     function export_addFilesFromRelations()
- *  762:     function export_addFile($fI, $recordRef='', $fieldname='')
- *  882:     function getRelations($table,$row)
- *  989:     function getRelations_flexFormCallBack($pParams, $dsConf, $dataValue, $dataValue_ext1, $dataValue_ext2, $structurePath)
- * 1038:     function getRelations_procFiles($value, $conf, $uid)
- * 1088:     function getRelations_procDB($value, $conf, $uid)
- * 1109:     function flatDBrels($dbrels)
- * 1135:     function flatSoftRefs($dbrels)
- * 1183:     function destPathFromUploadFolder($folder)
+ *  490:     function export_addRecord($table,$row,$relationLevel=0)
+ *  540:     function export_addDBRelations($relationLevel=0)
+ *  644:     function export_addDBRelations_registerRelation($fI, &$addR, $tokenID='')
+ *  668:     function export_addFilesFromRelations()
+ *  769:     function export_addFile($fI, $recordRef='', $fieldname='')
+ *  897:     function getRelations($table,$row)
+ * 1004:     function getRelations_flexFormCallBack($pParams, $dsConf, $dataValue, $dataValue_ext1, $dataValue_ext2, $structurePath)
+ * 1053:     function getRelations_procFiles($value, $conf, $uid)
+ * 1103:     function getRelations_procDB($value, $conf, $uid)
+ * 1124:     function flatDBrels($dbrels)
+ * 1150:     function flatSoftRefs($dbrels)
+ * 1198:     function destPathFromUploadFolder($folder)
  *
  *              SECTION: File Output
- * 1208:     function compileMemoryToFileContent($type='')
- * 1234:     function createXML()
- * 1326:     function doOutputCompress()
- * 1337:     function addFilePart($data, $compress=FALSE)
+ * 1223:     function compileMemoryToFileContent($type='')
+ * 1249:     function createXML()
+ * 1341:     function doOutputCompress()
+ * 1352:     function addFilePart($data, $compress=FALSE)
  *
  *              SECTION: Import
- * 1370:     function importData($pid)
- * 1408:     function writeRecords_pages($pid)
- * 1463:     function writeRecords_pages_order($pid)
- * 1501:     function writeRecords_records($pid)
- * 1551:     function writeRecords_records_order($mainPid)
- * 1600:     function addSingle($table,$uid,$pid)
- * 1658:     function addToMapId($substNEWwithIDs)
- * 1678:     function getNewTCE()
- * 1692:     function unlinkTempFiles()
+ * 1385:     function importData($pid)
+ * 1426:     function writeRecords_pages($pid)
+ * 1481:     function writeRecords_pages_order($pid)
+ * 1519:     function writeRecords_records($pid)
+ * 1569:     function writeRecords_records_order($mainPid)
+ * 1618:     function addSingle($table,$uid,$pid)
+ * 1692:     function addToMapId($substNEWwithIDs)
+ * 1712:     function getNewTCE()
+ * 1726:     function unlinkTempFiles()
  *
  *              SECTION: Import / Relations setting
- * 1730:     function setRelations()
- * 1784:     function setRelations_db($itemArray)
- * 1811:     function import_addFileNameToBeCopied($fI)
- * 1834:     function setFlexFormRelations()
- * 1917:     function remapListedDBRecords_flexFormCallBack($pParams, $dsConf, $dataValue, $dataValue_ext1, $dataValue_ext2, $path)
+ * 1764:     function setRelations()
+ * 1818:     function setRelations_db($itemArray)
+ * 1845:     function import_addFileNameToBeCopied($fI)
+ * 1868:     function setFlexFormRelations()
+ * 1951:     function remapListedDBRecords_flexFormCallBack($pParams, $dsConf, $dataValue, $dataValue_ext1, $dataValue_ext2, $path)
  *
  *              SECTION: Import / Soft References
- * 1959:     function processSoftReferences()
- * 2060:     function processSoftReferences_flexFormCallBack($pParams, $dsConf, $dataValue, $dataValue_ext1, $dataValue_ext2, $path)
- * 2097:     function processSoftReferences_substTokens($tokenizedContent, $softRefCfgs)
- * 2160:     function processSoftReferences_saveFile($relFileName,$cfg)
- * 2219:     function processSoftReferences_saveFile_createRelFile($dirPrefix,$fileName,$fileID)
- * 2276:     function writeFileVerify($fileName, $fileID)
- * 2303:     function checkOrCreateDir($dirPrefix)
- * 2335:     function verifyFolderAccess($dirPrefix)
+ * 1993:     function processSoftReferences()
+ * 2084:     function processSoftReferences_flexFormCallBack($pParams, $dsConf, $dataValue, $dataValue_ext1, $dataValue_ext2, $path)
+ * 2123:     function processSoftReferences_substTokens($tokenizedContent, $softRefCfgs, $table, $uid)
+ * 2187:     function processSoftReferences_saveFile($relFileName, $cfg, $table, $uid)
+ * 2248:     function processSoftReferences_saveFile_createRelFile($origDirPrefix, $fileName, $fileID, $table, $uid)
+ * 2337:     function writeFileVerify($fileName, $fileID, $bypassMountCheck=FALSE)
+ * 2364:     function checkOrCreateDir($dirPrefix)
+ * 2397:     function verifyFolderAccess($dirPrefix, $noAlternative=FALSE)
  *
  *              SECTION: File Input
- * 2384:     function loadFile($filename,$all=0)
- * 2428:     function getNextFilePart($fd,$unserialize=0,$name='')
- * 2455:     function loadContent($filecontent)
- * 2473:     function getNextContentPart($filecontent,&$pointer,$unserialize=0,$name='')
- * 2498:     function loadInit()
- * 2514:     function fixCharsets()
+ * 2447:     function loadFile($filename,$all=0)
+ * 2490:     function getNextFilePart($fd,$unserialize=0,$name='')
+ * 2517:     function loadContent($filecontent)
+ * 2535:     function getNextContentPart($filecontent,&$pointer,$unserialize=0,$name='')
+ * 2560:     function loadInit()
+ * 2576:     function fixCharsets()
  *
  *              SECTION: Visual rendering of import/export memory, $this->dat
- * 2569:     function displayContentOverview()
- * 2676:     function traversePageTree($pT,&$lines,$preCode='')
- * 2711:     function traversePageRecords($pT,&$lines)
- * 2738:     function traverseAllRecords($pT,&$lines)
- * 2760:     function singleRecordLines($table,$uid,&$lines,$preCode,$checkImportInPidRecord=0)
- * 2906:     function addRelations($rels,&$lines,$preCode,$recurCheck=array(),$htmlColor='')
- * 2964:     function addFiles($rels,&$lines,$preCode,$htmlColor='',$tokenID='')
- * 3064:     function checkDokType($checkTable,$doktype)
- * 3080:     function renderControls($r)
- * 3106:     function softrefSelector($cfg)
+ * 2631:     function displayContentOverview()
+ * 2739:     function traversePageTree($pT,&$lines,$preCode='')
+ * 2774:     function traversePageRecords($pT,&$lines)
+ * 2801:     function traverseAllRecords($pT,&$lines)
+ * 2823:     function singleRecordLines($table,$uid,&$lines,$preCode,$checkImportInPidRecord=0)
+ * 2980:     function addRelations($rels,&$lines,$preCode,$recurCheck=array(),$htmlColorClass='')
+ * 3045:     function addFiles($rels,&$lines,$preCode,$htmlColorClass='',$tokenID='')
+ * 3163:     function checkDokType($checkTable,$doktype)
+ * 3179:     function renderControls($r)
+ * 3207:     function softrefSelector($cfg)
  *
  *              SECTION: Helper functions of kinds
- * 3180:     function isTableStatic($table)
- * 3194:     function inclRelation($table)
- * 3209:     function isExcluded($table,$uid)
- * 3221:     function includeSoftref($tokenID)
- * 3231:     function isReferenceField($conf)
- * 3242:     function dontIgnorePid($table, $uid)
- * 3255:     function doesRecordExist($table,$uid,$fields='')
- * 3265:     function getRecordPath($pid)
- * 3282:     function renderSelectBox($prefix,$value,$optValues)
- * 3305:     function compareRecords($databaseRecord, $importRecord, $table)
- * 3371:     function getRTEoriginalFilename($string)
- * 3388:     function &getFileProcObj()
+ * 3283:     function isTableStatic($table)
+ * 3297:     function inclRelation($table)
+ * 3312:     function isExcluded($table,$uid)
+ * 3324:     function includeSoftref($tokenID)
+ * 3334:     function isReferenceField($conf)
+ * 3344:     function checkPID($pid)
+ * 3361:     function dontIgnorePid($table, $uid)
+ * 3374:     function doesRecordExist($table,$uid,$fields='')
+ * 3384:     function getRecordPath($pid)
+ * 3401:     function renderSelectBox($prefix,$value,$optValues)
+ * 3425:     function compareRecords($databaseRecord, $importRecord, $table, $inverseDiff=FALSE)
+ * 3492:     function getRTEoriginalFilename($string)
+ * 3509:     function &getFileProcObj()
  *
  *              SECTION: Error handling
- * 3421:     function error($msg)
- * 3430:     function printErrorLog()
+ * 3542:     function error($msg)
+ * 3551:     function printErrorLog()
  *
- * TOTAL FUNCTIONS: 77
+ * TOTAL FUNCTIONS: 78
  * (This index is automatically created/updated by the extension "extdeveval")
  *
  */
@@ -213,6 +214,7 @@ class tx_impexp {
        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.
        var $import_mode = array();                             // Setting import modes during update state: as_new, exclude, force_uid
        var $global_ignore_pid = FALSE;                 // If set, PID correct is ignored globally
+       var $force_all_UIDS = FALSE;                    // If set, all UID values are forced! (update or import)
        var $showDiff = FALSE;                                  // If set, a diff-view column is added to the overview.
        var $allowPHPScripts = FALSE;                   // If set, and if the user is admin, allow the writing of PHP scripts to fileadmin/ area.
        var $enableLogging = FALSE;                             // Disable logging when importing
@@ -239,6 +241,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
@@ -485,41 +488,46 @@ class tx_impexp {
         * @return      void
         */
        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;
-                               }
+               t3lib_BEfunc::workspaceOL($table,$row);
+
+               if (strcmp($table,'') && is_array($row) && $row['uid']>0 && !$this->excludeMap[$table.':'.$row['uid']]) {
+                       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,21 +1632,37 @@ 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']);
                                } else {        // Inserts:
                                        $this->import_data[$table][$ID]['pid'] = $pid;
 
-                                       if ($this->import_mode[$table.':'.$uid]==='force_uid' && $GLOBALS['BE_USER']->isAdmin())        {
+                                       if ((($this->import_mode[$table.':'.$uid]==='force_uid' && $this->update) || $this->force_all_UIDS) && $GLOBALS['BE_USER']->isAdmin())  {
 #debug($this->import_mode[$table.':'.$uid],$table.':'.$uid);
                                                $this->import_data[$table][$ID]['uid'] = $uid;
                                                $this->suggestedInsertUids[$table.':'.$uid] = 'DELETE';
                                        }
                                }
 
+                                       // 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 +1674,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;
                                        }
                                }
@@ -1753,7 +1777,8 @@ class tx_impexp {
 
                                // If the record has been written and received a new id, then proceed:
                        if (is_array($this->import_mapId[$table]) && isset($this->import_mapId[$table][$uid]))  {
-                               $thisNewUid = $this->import_mapId[$table][$uid];
+                               $thisNewUid = t3lib_BEfunc::wsMapId($table,$this->import_mapId[$table][$uid]);
+
                                if (is_array($this->dat['records'][$table.':'.$uid]['rels']))   {
                                        reset($this->dat['records'][$table.':'.$uid]['rels']);
 
@@ -1802,7 +1827,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'];
@@ -1857,7 +1882,8 @@ class tx_impexp {
 
                                // If the record has been written and received a new id, then proceed:
                        if (is_array($this->import_mapId[$table]) && isset($this->import_mapId[$table][$uid]))  {
-                               $thisNewUid = $this->import_mapId[$table][$uid];
+                               $thisNewUid = t3lib_BEfunc::wsMapId($table,$this->import_mapId[$table][$uid]);
+
                                if (is_array($this->dat['records'][$table.':'.$uid]['rels']))   {
                                        reset($this->dat['records'][$table.':'.$uid]['rels']);
                                        t3lib_div::loadTCA($table);
@@ -1923,7 +1949,7 @@ class tx_impexp {
         * @param       string          Field value (from FlexForm XML)
         * @param       string          Not used
         * @param       string          Not used
-        * @param       string          Path of where the the data structure the element is found
+        * @param       string          Path of where the data structure of the element is found
         * @return      array           Array where the "value" key carries the value.
         * @see setFlexFormRelations()
         */
@@ -1995,7 +2021,7 @@ class tx_impexp {
                                                }
 
                                                        // The new id:
-                                               $thisNewUid = $this->import_mapId[$table][$uid];
+                                               $thisNewUid = t3lib_BEfunc::wsMapId($table,$this->import_mapId[$table][$uid]);
 
                                                        // Now, if there are any fields that require substitution to be done, lets go for that:
                                                foreach($fieldsIndex as $field => $softRefCfgs) {
@@ -2056,7 +2082,7 @@ class tx_impexp {
         * @param       string          Field value (from FlexForm XML)
         * @param       string          Not used
         * @param       string          Not used
-        * @param       string          Path of where the the data structure the element is found
+        * @param       string          Path of where the data structure where the element is found
         * @return      array           Array where the "value" key carries the value.
         * @see setFlexFormRelations()
         */
@@ -2127,7 +2153,7 @@ class tx_impexp {
                                                                        // Trying to map database element if found in the mapID array:
                                                                list($tempTable,$tempUid) = explode(':',$cfg['subst']['recordRef']);
                                                                if (isset($this->import_mapId[$tempTable][$tempUid]))   {
-                                                                       $insertValue = $this->import_mapId[$tempTable][$tempUid];
+                                                                       $insertValue = t3lib_BEfunc::wsMapId($tempTable,$this->import_mapId[$tempTable][$tempUid]);
 
                                                                                // Look if reference is to a page and the original token value was NOT an integer - then we assume is was an alias and try to look up the new one!
                                                                        if ($tempTable==='pages' && !t3lib_div::testInt($cfg['subst']['tokenValue']))   {
@@ -2425,7 +2451,6 @@ class tx_impexp {
         */
        function loadFile($filename,$all=0)     {
                if (@is_file($filename))        {
-
                        $fI = pathinfo($filename);
                        if (strtolower($fI['extension'])=='xml')        {
                                        // XML:
@@ -2837,7 +2862,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 +2889,12 @@ 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, '*');
+                                               t3lib_BEfunc::workspaceOL($table,$recInf);
                                        }
                                        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 +3342,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 +3422,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 +3446,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 +3482,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;
                }
 
 
@@ -3485,7 +3532,6 @@ class tx_impexp {
 
 
 
-
        /*****************************
         *
         * Error handling