/src/typo3_src-4.2.0alpha1/t3lib/class.t3lib_tcemain.php

00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2007 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 ***************************************************************/
00208 // *******************************
00209 // Including necessary libraries
00210 // *******************************
00211 require_once (PATH_t3lib.'class.t3lib_loaddbgroup.php');
00212 require_once (PATH_t3lib.'class.t3lib_parsehtml_proc.php');
00213 require_once (PATH_t3lib.'class.t3lib_stdgraphic.php');
00214 require_once (PATH_t3lib.'class.t3lib_basicfilefunc.php');
00215 require_once (PATH_t3lib.'class.t3lib_refindex.php');
00216 require_once (PATH_t3lib.'class.t3lib_flexformtools.php');
00217 
00218 
00219 
00220 
00221 
00222 
00223 
00224 
00225 
00226 
00227 
00242 class t3lib_TCEmain     {
00243 
00244 
00245                 // *********************
00246                 // Public variables you can configure before using the class:
00247                 // *********************
00248 
00249         var $storeLogMessages = TRUE;                   // Boolean: If true, the default log-messages will be stored. This should not be necessary if the locallang-file for the log-display is properly configured. So disabling this will just save some database-space as the default messages are not saved.
00250         var $enableLogging = TRUE;                              // Boolean: If true, actions are logged to sys_log.
00251         var $reverseOrder = FALSE;                              // Boolean: If true, the datamap array is reversed in the order, which is a nice thing if you're creating a whole new bunch of records.
00252         var $checkSimilar = TRUE;                               // Boolean: If true, only fields which are different from the database values are saved! In fact, if a whole input array is similar, it's not saved then.
00253         var $stripslashes_values = TRUE;                // Boolean: If true, incoming values in the data-array have their slashes stripped. ALWAYS SET THIS TO ZERO and supply an unescaped data array instead. This switch may totally disappear in future versions of this class!
00254         var $checkStoredRecords = TRUE;                 // Boolean: This will read the record after having updated or inserted it. If anything is not properly submitted an error is written to the log. This feature consumes extra time by selecting records
00255         var $checkStoredRecords_loose = TRUE;   // Boolean: If set, values '' and 0 will equal each other when the stored records are checked.
00256         var $deleteTree = FALSE;                                // Boolean. If this is set, then a page is deleted by deleting the whole branch under it (user must have deletepermissions to it all). If not set, then the page is deleted ONLY if it has no branch
00257         var $neverHideAtCopy = FALSE;                   // Boolean. If set, then the 'hideAtCopy' flag for tables will be ignored.
00258         var $dontProcessTransformations = FALSE;        // Boolean: If set, then transformations are NOT performed on the input.
00259         var $bypassWorkspaceRestrictions = FALSE;       // Boolean: If true, workspace restrictions are bypassed on edit an create actions (process_datamap()). YOU MUST KNOW what you do if you use this feature!
00260         var $bypassFileHandling = FALSE;                        // Boolean: If true, file handling of attached files (addition, deletion etc) is bypassed - the value is saved straight away. YOU MUST KNOW what you are doing with this feature!
00261         var $bypassAccessCheckForRecords = FALSE;       // Boolean: If true, access check, check for deleted etc. for records is bypassed. YOU MUST KNOW what you are doing if you use this feature!
00262 
00263         var $copyWhichTables = '*';                             // String. Comma-list. This list of tables decides which tables will be copied. If empty then none will. If '*' then all will (that the user has permission to of course)
00264         var $generalComment = '';                               // General comment, eg. for staging in workspaces.
00265 
00266         var $copyTree = 0;                                              // Integer. If 0 then branch is NOT copied. If 1 then pages on the 1st level is copied. If 2 then pages on the second level is copied ... and so on
00267 
00268         var $defaultValues = array();                   // Array [table][fields]=value: New records are created with default values and you can set this array on the form $defaultValues[$table][$field] = $value to override the default values fetched from TCA. If ->setDefaultsFromUserTS is called UserTSconfig default values will overrule existing values in this array (thus UserTSconfig overrules externally set defaults which overrules TCA defaults)
00269         var $overrideValues = array();                  // Array [table][fields]=value: You can set this array on the form $overrideValues[$table][$field] = $value to override the incoming data. You must set this externally. You must make sure the fields in this array are also found in the table, because it's not checked. All columns can be set by this array!
00270         var $alternativeFileName = array();             // Array [filename]=alternative_filename: Use this array to force another name onto a file. Eg. if you set ['/tmp/blablabal'] = 'my_file.txt' and '/tmp/blablabal' is set for a certain file-field, then 'my_file.txt' will be used as the name instead.
00271         var $data_disableFields=array();                // If entries are set in this array corresponding to fields for update, they are ignored and thus NOT updated. You could set this array from a series of checkboxes with value=0 and hidden fields before the checkbox with 1. Then an empty checkbox will disable the field.
00272         var $suggestedInsertUids=array();               // Use this array to validate suggested uids for tables by setting [table]:[uid]. This is a dangerous option since it will force the inserted record to have a certain UID. The value just have to be true, but if you set it to "DELETE" it will make sure any record with that UID will be deleted first (raw delete). The option is used for import of T3D files when synchronizing between two mirrored servers. As a security measure this feature is available only for Admin Users (for now)
00273 
00274         var $callBackObj;                                               // Object. Call back object for flex form traversation. Useful when external classes wants to use the iteration functions inside tcemain for traversing a FlexForm structure.
00275 
00276 
00277 
00278 
00279                 // *********************
00280                 // Internal variables (mapping arrays) which can be used (read-only) from outside
00281                 // *********************
00282         var $autoVersionIdMap = Array();                        // Contains mapping of auto-versionized records.
00283         var $substNEWwithIDs = Array();                         // When new elements are created, this array contains a map between their "NEW..." string IDs and the eventual UID they got when stored in database
00284         var $substNEWwithIDs_table = Array();           // Like $substNEWwithIDs, but where each old "NEW..." id is mapped to the table it was from.
00285         var $newRelatedIDs = Array();                           // Holds the tables and there the ids of newly created child records from IRRE
00286         var $copyMappingArray_merged = Array();         // This array is the sum of all copying operations in this class. May be READ from outside, thus partly public.
00287         var $copiedFileMap = Array();                           // A map between input file name and final destination for files being attached to records.
00288         var $RTEmagic_copyIndex = Array();                      // Contains [table][id][field] of fiels where RTEmagic images was copied. Holds old filename as key and new filename as value.
00289         var $errorLog = Array();                                        // Errors are collected in this variable.
00290 
00291 
00292 
00293                 // *********************
00294                 // Internal Variables, do not touch.
00295                 // *********************
00296 
00297                 // Variables set in init() function:
00303         var $BE_USER;
00304         var $userid;            // will be set to uid of be_user executing this script
00305         var $username;          // will be set to username of be_user executing this script
00306         var $admin;                     // will be set if user is admin
00307 
00308         var $defaultPermissions = array(                // Can be overridden from $TYPO3_CONF_VARS
00309                 'user' => 'show,edit,delete,new,editcontent',
00310                 'group' => 'show,edit,new,editcontent',
00311                 'everybody' => ''
00312         );
00313 
00314         var $exclude_array;                     // The list of <table>-<fields> that cannot be edited by user. This is compiled from TCA/exclude-flag combined with non_exclude_fields for the user.
00315         var $datamap = Array();         // Set with incoming data array
00316         var $cmdmap = Array();          // Set with incoming cmd array
00317 
00318                 // Internal static:
00319         var $pMap = Array(              // Permission mapping
00320                 'show' => 1,                    // 1st bit
00321                 'edit' => 2,                    // 2nd bit
00322                 'delete' => 4,                  // 3rd bit
00323                 'new' => 8,                             // 4th bit
00324                 'editcontent' => 16             // 5th bit
00325         );
00326         var $sortIntervals = 256;                                       // Integer: The interval between sorting numbers used with tables with a 'sorting' field defined. Min 1
00327 
00328                 // Internal caching arrays
00329         var $recUpdateAccessCache = Array();            // Used by function checkRecordUpdateAccess() to store whether a record is updateable or not.
00330         var $recInsertAccessCache = Array();            // User by function checkRecordInsertAccess() to store whether a record can be inserted on a page id
00331         var $isRecordInWebMount_Cache=array();          // Caching array for check of whether records are in a webmount
00332         var $isInWebMount_Cache=array();                        // Caching array for page ids in webmounts
00333         var $cachedTSconfig = array();                          // Caching for collecting TSconfig for page ids
00334         var $pageCache = Array();                                       // Used for caching page records in pageInfo()
00335         var $checkWorkspaceCache = Array();                     // Array caching workspace access for BE_USER
00336 
00337                 // Other arrays:
00338         var $dbAnalysisStore=array();                           // For accumulation of MM relations that must be written after new records are created.
00339         var $removeFilesStore=array();                          // For accumulation of files which must be deleted after processing of all input content
00340         var $uploadedFileArray = array();                       // Uploaded files, set by process_uploads()
00341         var $registerDBList=array();                            // Used for tracking references that might need correction after operations
00342         var $registerDBPids=array();                            // Used for tracking references that might need correction in pid field after operations (e.g. IRRE)
00343         var $copyMappingArray = Array();                        // Used by the copy action to track the ids of new pages so subpages are correctly inserted! THIS is internally cleared for each executed copy operation! DO NOT USE THIS FROM OUTSIDE! Read from copyMappingArray_merged instead which is accumulating this information.
00344         var $remapStack = array();                                      // array used for remapping uids and values at the end of process_datamap
00345         var $remapStackRecords = array();                       // array used for remapping uids and values at the end of process_datamap (e.g. $remapStackRecords[<table>][<uid>] = <index in $remapStack>)
00346         var $updateRefIndexStack = array();                     // array used for additional calls to $this->updateRefIndex
00347         var $callFromImpExp = false;                            // tells, that this TCEmain was called from tx_impext - this variable is set by tx_impexp
00348 
00349                 // Various
00350         var $fileFunc;                                                          // For "singleTon" file-manipulation object
00351         var $checkValue_currentRecord=array();          // Set to "currentRecord" during checking of values.
00352         var $autoVersioningUpdate = FALSE;                      // A signal flag used to tell file processing that autoversioning has happend and hence certain action should be applied.
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00375         function start($data,$cmd,$altUserObject='')    {
00376 
00377                         // Initializing BE_USER
00378                 $this->BE_USER = is_object($altUserObject) ? $altUserObject : $GLOBALS['BE_USER'];
00379                 $this->userid = $this->BE_USER->user['uid'];
00380                 $this->username = $this->BE_USER->user['username'];
00381                 $this->admin = $this->BE_USER->user['admin'];
00382 
00383                 if ($GLOBALS['BE_USER']->uc['recursiveDelete'])    {
00384                         $this->deleteTree = 1;
00385                 }
00386 
00387                         // Initializing default permissions for pages
00388                 $defaultPermissions = $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPermissions'];
00389                 if (isset($defaultPermissions['user']))         {$this->defaultPermissions['user'] = $defaultPermissions['user'];}
00390                 if (isset($defaultPermissions['group']))                {$this->defaultPermissions['group'] = $defaultPermissions['group'];}
00391                 if (isset($defaultPermissions['everybody']))            {$this->defaultPermissions['everybody'] = $defaultPermissions['everybody'];}
00392 
00393                         // generates the excludelist, based on TCA/exclude-flag and non_exclude_fields for the user:
00394                 $this->exclude_array = $this->admin ? array() : $this->getExcludeListArray();
00395 
00396                         // Setting the data and cmd arrays
00397                 if (is_array($data)) {
00398                         reset($data);
00399                         $this->datamap = $data;
00400                 }
00401                 if (is_array($cmd))     {
00402                         reset($cmd);
00403                         $this->cmdmap = $cmd;
00404                 }
00405         }
00406 
00414         function setMirror($mirror)     {
00415                 if (is_array($mirror))  {
00416                         reset($mirror);
00417                         while(list($table,$uid_array)=each($mirror))    {
00418                                 if (isset($this->datamap[$table]))      {
00419                                         reset($uid_array);
00420                                         while (list($id,$uidList) = each($uid_array))   {
00421                                                 if (isset($this->datamap[$table][$id])) {
00422                                                         $theIdsInArray = t3lib_div::trimExplode(',',$uidList,1);
00423                                                         while(list(,$copyToUid)=each($theIdsInArray))   {
00424                                                                 $this->datamap[$table][$copyToUid] = $this->datamap[$table][$id];
00425                                                         }
00426                                                 }
00427                                         }
00428                                 }
00429                         }
00430                 }
00431         }
00432 
00439         function setDefaultsFromUserTS($userTS) {
00440                 global $TCA;
00441                 if (is_array($userTS))  {
00442                         foreach($userTS as $k => $v)    {
00443                                 $k = substr($k,0,-1);
00444                                 if ($k && is_array($v) && isset($TCA[$k]))      {
00445                                         if (is_array($this->defaultValues[$k])) {
00446                                                 $this->defaultValues[$k] = array_merge($this->defaultValues[$k],$v);
00447                                         } else {
00448                                                 $this->defaultValues[$k] = $v;
00449                                         }
00450                                 }
00451                         }
00452                 }
00453         }
00454 
00462         function process_uploads($postFiles)    {
00463 
00464                 if (is_array($postFiles))       {
00465 
00466                                 // Editing frozen:
00467                         if ($this->BE_USER->workspace!==0 && $this->BE_USER->workspaceRec['freeze'])    {
00468                                 $this->newlog('All editing in this workspace has been frozen!',1);
00469                                 return FALSE;
00470                         }
00471 
00472                         reset($postFiles);
00473                         $subA = current($postFiles);
00474                         if (is_array($subA))    {
00475                                 if (is_array($subA['name']) && is_array($subA['type']) && is_array($subA['tmp_name']) && is_array($subA['size']))       {
00476                                                 // Initialize the uploadedFilesArray:
00477                                         $this->uploadedFileArray=array();
00478 
00479                                                 // For each entry:
00480                                         foreach($subA as $key => $values)       {
00481                                                 $this->process_uploads_traverseArray($this->uploadedFileArray,$values,$key);
00482                                         }
00483                                 } else {
00484                                         $this->uploadedFileArray=$subA;
00485                                 }
00486                         }
00487                 }
00488         }
00489 
00500         function process_uploads_traverseArray(&$outputArr,$inputArr,$keyToSet) {
00501                 if (is_array($inputArr))        {
00502                         foreach($inputArr as $key => $value)    {
00503                                 $this->process_uploads_traverseArray($outputArr[$key],$inputArr[$key],$keyToSet);
00504                         }
00505                 } else {
00506                         $outputArr[$keyToSet]=$inputArr;
00507                 }
00508         }
00509 
00510 
00511 
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00523 
00524         /*********************************************
00525          *
00526          * HOOKS
00527          *
00528          *********************************************/
00529 
00544         function hook_processDatamap_afterDatabaseOperations(&$hookObjectsArr, &$status, &$table, &$id, &$fieldArray) {
00545                         // Process hook directly:
00546                 if (!isset($this->remapStackRecords[$table][$id])) {
00547                         foreach($hookObjectsArr as $hookObj)    {
00548                                 if (method_exists($hookObj, 'processDatamap_afterDatabaseOperations')) {
00549                                         $hookObj->processDatamap_afterDatabaseOperations($status, $table, $id, $fieldArray, $this);
00550                                 }
00551                         }
00552                         // If this record is in remapStack (e.g. when using IRRE), values will be updated/remapped later on. So the hook will also be called later:
00553                 } else {
00554                         $this->remapStackRecords[$table][$id]['processDatamap_afterDatabaseOperations'] = array(
00555                                 'status' => $status,
00556                                 'fieldArray' => $fieldArray,
00557                                 'hookObjectsArr' => $hookObjectsArr,
00558                         );
00559                 }
00560         }
00561 
00562 
00563 
00564 
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572 
00573 
00574 
00575         /*********************************************
00576          *
00577          * PROCESSING DATA
00578          *
00579          *********************************************/
00580 
00587         function process_datamap() {
00588                 global $TCA, $TYPO3_CONF_VARS;
00589                         // Keep versionized(!) relations here locally:
00590                 $registerDBList = array();
00591 
00592                         // Editing frozen:
00593                 if ($this->BE_USER->workspace!==0 && $this->BE_USER->workspaceRec['freeze'])    {
00594                         $this->newlog('All editing in this workspace has been frozen!',1);
00595                         return FALSE;
00596                 }
00597 
00598                         // First prepare user defined objects (if any) for hooks which extend this function:
00599                 $hookObjectsArr = array();
00600                 if (is_array ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'])) {
00601                         foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'] as $classRef) {
00602                                 $hookObjectsArr[] = &t3lib_div::getUserObj($classRef);
00603                         }
00604                 }
00605 
00606                         // Organize tables so that the pages-table is always processed first. This is required if you want to make sure that content pointing to a new page will be created.
00607                 $orderOfTables = Array();
00608                 if (isset($this->datamap['pages']))     {               // Set pages first.
00609                         $orderOfTables[]='pages';
00610                 }
00611                 reset($this->datamap);
00612                 while (list($table,) = each($this->datamap))    {
00613                         if ($table!='pages')    {
00614                                 $orderOfTables[]=$table;
00615                         }
00616                 }
00617 
00618                         // Process the tables...
00619                 foreach($orderOfTables as $table)       {
00620                                 /* Check if
00621                                         - table is set in $TCA,
00622                                         - table is NOT readOnly
00623                                         - the table is set with content in the data-array (if not, there's nothing to process...)
00624                                         - permissions for tableaccess OK
00625                                 */
00626                         $modifyAccessList = $this->checkModifyAccessList($table);
00627                         if (!$modifyAccessList) {
00628                                 $id = 0;
00629                                 $this->log($table,$id,2,0,1,"Attempt to modify table '%s' without permission",1,array($table));
00630                         }
00631                         if (isset($TCA[$table]) && !$this->tableReadOnly($table) && is_array($this->datamap[$table]) && $modifyAccessList)      {
00632                                 if ($this->reverseOrder)        {
00633                                         $this->datamap[$table] = array_reverse($this->datamap[$table], 1);
00634                                 }
00635 
00636                                         // For each record from the table, do:
00637                                         // $id is the record uid, may be a string if new records...
00638                                         // $incomingFieldArray is the array of fields
00639                                 foreach($this->datamap[$table] as $id => $incomingFieldArray)   {
00640                                         if (is_array($incomingFieldArray))      {
00641 
00642                                                         // Hook: processDatamap_preProcessIncomingFieldArray
00643                                                 foreach($hookObjectsArr as $hookObj)    {
00644                                                         if (method_exists($hookObj, 'processDatamap_preProcessFieldArray')) {
00645                                                                 $hookObj->processDatamap_preProcessFieldArray($incomingFieldArray, $table, $id, $this);
00646                                                         }
00647                                                 }
00648 
00649                                                         // ******************************
00650                                                         // Checking access to the record
00651                                                         // ******************************
00652                                                 $createNewVersion = FALSE;
00653                                                 $recordAccess = FALSE;
00654                                                 $old_pid_value = '';
00655                                                 $resetRejected = FALSE;
00656                                                 $this->autoVersioningUpdate = FALSE;
00657 
00658                                                 if (!t3lib_div::testInt($id)) {               // Is it a new record? (Then Id is a string)
00659                                                         $fieldArray = $this->newFieldArray($table);     // Get a fieldArray with default values
00660                                                         if (isset($incomingFieldArray['pid']))  {       // A pid must be set for new records.
00661                                                                         // $value = the pid
00662                                                                 $pid_value = $incomingFieldArray['pid'];
00663 
00664                                                                         // Checking and finding numerical pid, it may be a string-reference to another value
00665                                                                 $OK = 1;
00666                                                                 if (strstr($pid_value,'NEW'))   {       // If a NEW... id
00667                                                                         if (substr($pid_value,0,1)=='-') {$negFlag=-1;$pid_value=substr($pid_value,1);} else {$negFlag=1;}
00668                                                                         if (isset($this->substNEWwithIDs[$pid_value]))  {       // Trying to find the correct numerical value as it should be mapped by earlier processing of another new record.
00669                                                                                 $old_pid_value = $pid_value;
00670                                                                                 $pid_value=intval($negFlag*$this->substNEWwithIDs[$pid_value]);
00671                                                                         } else {$OK = 0;}       // If not found in the substArray we must stop the process...
00672                                                                 } elseif ($pid_value>=0 && $this->BE_USER->workspace!==0 && $TCA[$table]['ctrl']['versioning_followPages'])     {       // PID points to page, the workspace is an offline space and the table follows page during versioning: This means we must check if the PID page has a version in the workspace with swapmode set to 0 (zero = page+content) and if so, change the pid to the uid of that version.
00673                                                                         if ($WSdestPage = t3lib_BEfunc::getWorkspaceVersionOfRecord($this->BE_USER->workspace, 'pages', $pid_value, 'uid,t3ver_swapmode'))      {       // Looks for workspace version of page.
00674                                                                                 if ($WSdestPage['t3ver_swapmode']==0)   {       // if swapmode is zero, then change pid value.
00675                                                                                         $pid_value = $WSdestPage['uid'];
00676                                                                                 }
00677                                                                         }
00678                                                                 }
00679                                                                 $pid_value = intval($pid_value);
00680 
00681                                                                         // The $pid_value is now the numerical pid at this point
00682                                                                 if ($OK)        {
00683                                                                         $sortRow = $TCA[$table]['ctrl']['sortby'];
00684                                                                         if ($pid_value>=0)      {       // Points to a page on which to insert the element, possibly in the top of the page
00685                                                                                 if ($sortRow)   {       // If this table is sorted we better find the top sorting number
00686                                                                                         $fieldArray[$sortRow] = $this->getSortNumber($table,0,$pid_value);
00687                                                                                 }
00688                                                                                 $fieldArray['pid'] = $pid_value;        // The numerical pid is inserted in the data array
00689                                                                         } else {        // points to another record before ifself
00690                                                                                 if ($sortRow)   {       // If this table is sorted we better find the top sorting number
00691                                                                                         $tempArray=$this->getSortNumber($table,0,$pid_value);   // Because $pid_value is < 0, getSortNumber returns an array
00692                                                                                         $fieldArray['pid'] = $tempArray['pid'];
00693                                                                                         $fieldArray[$sortRow] = $tempArray['sortNumber'];
00694                                                                                 } else {        // Here we fetch the PID of the record that we point to...
00695                                                                                         $tempdata = $this->recordInfo($table,abs($pid_value),'pid');
00696                                                                                         $fieldArray['pid']=$tempdata['pid'];
00697                                                                                 }
00698                                                                         }
00699                                                                 }
00700                                                         }
00701                                                         $theRealPid = $fieldArray['pid'];
00702 
00703                                                                 // Now, check if we may insert records on this pid.
00704                                                         if ($theRealPid>=0)     {
00705                                                                 $recordAccess = $this->checkRecordInsertAccess($table,$theRealPid);             // Checks if records can be inserted on this $pid.
00706                                                                 if ($recordAccess)      {
00707                                                                         $this->addDefaultPermittedLanguageIfNotSet($table,$incomingFieldArray);
00708                                                                         $recordAccess = $this->BE_USER->recordEditAccessInternals($table,$incomingFieldArray,TRUE);
00709                                                                         if (!$recordAccess)             {
00710                                                                                 $this->newlog("recordEditAccessInternals() check failed. [".$this->BE_USER->errorMsg."]",1);
00711                                                                         } elseif(!$this->bypassWorkspaceRestrictions)   {
00712                                                                                         // Workspace related processing:
00713                                                                                 if ($res = $this->BE_USER->workspaceAllowLiveRecordsInPID($theRealPid,$table))  {       // If LIVE records cannot be created in the current PID due to workspace restrictions, prepare creation of placeholder-record
00714                                                                                         if ($res<0)     {
00715                                                                                                 $recordAccess = FALSE;
00716                                                                                                 $this->newlog('Stage for versioning root point and users access level did not allow for editing',1);
00717                                                                                         }
00718                                                                                 } else {        // So, if no live records were allowed, we have to create a new version of this record:
00719                                                                                         if ($TCA[$table]['ctrl']['versioningWS'])       {
00720                                                                                                 $createNewVersion = TRUE;
00721                                                                                         } else {
00722                                                                                                 $recordAccess = FALSE;
00723                                                                                                 $this->newlog('Record could not be created in this workspace in this branch',1);
00724                                                                                         }
00725                                                                                 }
00726                                                                         }
00727                                                                 }
00728                                                         } else {
00729                                                                 debug('Internal ERROR: pid should not be less than zero!');
00730                                                         }
00731                                                         $status = 'new';                                                // Yes new record, change $record_status to 'insert'
00732                                                 } else {        // Nope... $id is a number
00733                                                         $fieldArray = array();
00734                                                         $recordAccess = $this->checkRecordUpdateAccess($table,$id);
00735                                                         if (!$recordAccess)             {
00736                                                                 $propArr = $this->getRecordProperties($table,$id);
00737                                                                 $this->log($table,$id,2,0,1,"Attempt to modify record '%s' (%s) without permission. Or non-existing page.",2,array($propArr['header'],$table.':'.$id),$propArr['event_pid']);
00738                                                         } else {        // Next check of the record permissions (internals)
00739                                                                 $recordAccess = $this->BE_USER->recordEditAccessInternals($table,$id);
00740                                                                 if (!$recordAccess)             {
00741                                                                         $propArr = $this->getRecordProperties($table,$id);
00742                                                                         $this->newlog("recordEditAccessInternals() check failed. [".$this->BE_USER->errorMsg."]",1);
00743                                                                 } else {        // Here we fetch the PID of the record that we point to...
00744                                                                         $tempdata = $this->recordInfo($table,$id,'pid'.($TCA[$table]['ctrl']['versioningWS']?',t3ver_wsid,t3ver_stage':''));
00745                                                                         $theRealPid = $tempdata['pid'];
00746 
00747                                                                                 // Prepare the reset of the rejected flag if set:
00748                                                                         if ($TCA[$table]['ctrl']['versioningWS'] && $tempdata['t3ver_stage']<0) {
00749                                                                                 $resetRejected = TRUE;
00750                                                                         }
00751 
00752                                                                         // Use the new id of the versionized record we're trying to write to:
00753                                                                                 // (This record is a child record of a parent and has already been versionized.)
00754                                                                         if ($this->autoVersionIdMap[$table][$id]) {
00755                                                                                         // For the reason that creating a new version of this record, automatically
00756                                                                                         // created related child records (e.g. "IRRE"), update the accordant field:
00757                                                                                 $this->getVersionizedIncomingFieldArray($table, $id, $incomingFieldArray, $registerDBList);
00758 
00759                                                                                         // Use the new id of the copied/versionized record:
00760                                                                                 $id = $this->autoVersionIdMap[$table][$id];
00761                                                                                 $recordAccess = TRUE;
00762                                                                                 $this->autoVersioningUpdate = TRUE;
00763 
00764                                                                                 // Checking access in case of offline workspace:
00765                                                                         } elseif (!$this->bypassWorkspaceRestrictions && $errorCode = $this->BE_USER->workspaceCannotEditRecord($table,$tempdata)) {
00766                                                                                 $recordAccess = FALSE;          // Versioning is required and it must be offline version!
00767 
00768                                                                                         // Auto-creation of version: In offline workspace, test if versioning is enabled and look for workspace version of input record. If there is no versionized record found we will create one and save to that.
00769                                                                                 if ($this->BE_USER->workspaceAllowAutoCreation($table,$id,$theRealPid)) {
00770                                                                                         $tce = t3lib_div::makeInstance('t3lib_TCEmain');
00771                                                                                         $tce->stripslashes_values = 0;
00772 
00773                                                                                                 // Setting up command for creating a new version of the record:
00774                                                                                         $cmd = array();
00775                                                                                         $cmd[$table][$id]['version'] = array(
00776                                                                                                 'action' => 'new',
00777                                                                                                 'treeLevels' => -1,     // Default is to create a version of the individual records... element versioning that is.
00778                                                                                                 'label' => 'Auto-created for WS #'.$this->BE_USER->workspace
00779                                                                                         );
00780                                                                                         $tce->start(array(),$cmd);
00781                                                                                         $tce->process_cmdmap();
00782                                                                                         $this->errorLog = array_merge($this->errorLog,$tce->errorLog);
00783 
00784                                                                                                 // If copying was successful, share the new uids (also of related children):
00785                                                                                         if ($tce->copyMappingArray[$table][$id])        {
00786                                                                                                 foreach ($tce->copyMappingArray as $origTable => $origIdArray) {
00787                                                                                                         foreach ($origIdArray as $origId => $newId) {
00788                                                                                                                 $this->uploadedFileArray[$origTable][$newId] = $this->uploadedFileArray[$origTable][$origId];
00789                                                                                                                 $this->autoVersionIdMap[$origTable][$origId] = $newId;
00790                                                                                                         }
00791                                                                                                 }
00792                                                                                                 $this->RTEmagic_copyIndex = t3lib_div::array_merge_recursive_overrule($this->RTEmagic_copyIndex, $tce->RTEmagic_copyIndex);             // See where RTEmagic_copyIndex is used inside fillInFieldArray() for more information...
00793 
00794                                                                                                         // Update registerDBList, that holds the copied relations to child records:
00795                                                                                                 $registerDBList = array_merge($registerDBList, $tce->registerDBList);
00796                                                                                                         // For the reason that creating a new version of this record, automatically
00797                                                                                                         // created related child records (e.g. "IRRE"), update the accordant field:
00798                                                                                                 $this->getVersionizedIncomingFieldArray($table, $id, $incomingFieldArray, $registerDBList);
00799 
00800                                                                                                         // Use the new id of the copied/versionized record:
00801                                                                                                 $id = $this->autoVersionIdMap[$table][$id];
00802                                                                                                 $recordAccess = TRUE;
00803                                                                                                 $this->autoVersioningUpdate = TRUE;
00804                                                                                         } else $this->newlog("Could not be edited in offline workspace in the branch where found (failure state: '".$errorCode."'). Auto-creation of version failed!",1);
00805                                                                                 } else $this->newlog("Could not be edited in offline workspace in the branch where found (failure state: '".$errorCode."'). Auto-creation of version not allowed in workspace!",1);
00806                                                                         }
00807                                                                 }
00808                                                         }
00809                                                         $status = 'update';     // the default is 'update'
00810                                                 }
00811 
00812                                                         // If access was granted above, proceed to create or update record:
00813                                                 if ($recordAccess)      {
00814 
00815                                                         list($tscPID) = t3lib_BEfunc::getTSCpid($table,$id,$old_pid_value ? $old_pid_value : $fieldArray['pid']);       // Here the "pid" is set IF NOT the old pid was a string pointing to a place in the subst-id array.
00816                                                         $TSConfig = $this->getTCEMAIN_TSconfig($tscPID);
00817                                                         if ($status=='new' && $table=='pages' && is_array($TSConfig['permissions.']))   {
00818                                                                 $fieldArray = $this->setTSconfigPermissions($fieldArray,$TSConfig['permissions.']);
00819                                                         }
00820                                                         if ($createNewVersion)  {
00821                                                                 $newVersion_placeholderFieldArray = $fieldArray;
00822                                                         }
00823 
00824                                                                 // Processing of all fields in incomingFieldArray and setting them in $fieldArray
00825                                                         $fieldArray = $this->fillInFieldArray($table,$id,$fieldArray,$incomingFieldArray,$theRealPid,$status,$tscPID);
00826 
00827                                                                 // NOTICE! All manipulation beyond this point bypasses both "excludeFields" AND possible "MM" relations / file uploads to field!
00828 
00829                                                                 // Forcing some values unto field array:
00830                                                         $fieldArray = $this->overrideFieldArray($table,$fieldArray);    // NOTICE: This overriding is potentially dangerous; permissions per field is not checked!!!
00831                                                         if ($createNewVersion)  {
00832                                                                 $newVersion_placeholderFieldArray = $this->overrideFieldArray($table,$newVersion_placeholderFieldArray);
00833                                                         }
00834 
00835                                                                 // Setting system fields
00836                                                         if ($status=='new')     {
00837                                                                 if ($TCA[$table]['ctrl']['crdate'])     {
00838                                                                         $fieldArray[$TCA[$table]['ctrl']['crdate']]=time();
00839                                                                         if ($createNewVersion)  $newVersion_placeholderFieldArray[$TCA[$table]['ctrl']['crdate']]=time();
00840                                                                 }
00841                                                                 if ($TCA[$table]['ctrl']['cruser_id'])  {
00842                                                                         $fieldArray[$TCA[$table]['ctrl']['cruser_id']]=$this->userid;
00843                                                                         if ($createNewVersion)  $newVersion_placeholderFieldArray[$TCA[$table]['ctrl']['cruser_id']]=$this->userid;
00844                                                                 }
00845                                                         } elseif ($this->checkSimilar) {        // Removing fields which are equal to the current value:
00846                                                                 $fieldArray = $this->compareFieldArrayWithCurrentAndUnset($table,$id,$fieldArray);
00847                                                         }
00848                                                         if ($TCA[$table]['ctrl']['tstamp'] && count($fieldArray))       {
00849                                                                 $fieldArray[$TCA[$table]['ctrl']['tstamp']]=time();
00850                                                                 if ($createNewVersion)  $newVersion_placeholderFieldArray[$TCA[$table]['ctrl']['tstamp']]=time();
00851                                                         }
00852                                                         if ($resetRejected)     {
00853                                                                 $fieldArray['t3ver_stage'] = 0;
00854                                                         }
00855 
00856                                                                 // Hook: processDatamap_postProcessFieldArray
00857                                                         foreach($hookObjectsArr as $hookObj)    {
00858                                                                 if (method_exists($hookObj, 'processDatamap_postProcessFieldArray')) {
00859                                                                         $hookObj->processDatamap_postProcessFieldArray($status, $table, $id, $fieldArray, $this);
00860                                                                 }
00861                                                         }
00862 
00863                                                                 // Performing insert/update. If fieldArray has been unset by some userfunction (see hook above), don't do anything
00864                                                                 // Kasper: Unsetting the fieldArray is dangerous; MM relations might be saved already and files could have been uploaded that are now "lost"
00865                                                         if (is_array($fieldArray)) {
00866                                                                 if ($status=='new')     {
00867                                                                         if ($createNewVersion)  {       // This creates a new version of the record with online placeholder and offline version
00868                                                                                 $versioningType = $table==='pages' ? $this->BE_USER->workspaceVersioningTypeGetClosest(t3lib_div::intInRange($TYPO3_CONF_VARS['BE']['newPagesVersioningType'],-1,1)) : -1;
00869                                                                                 if ($this->BE_USER->workspaceVersioningTypeAccess($versioningType))     {
00870                                                                                         $newVersion_placeholderFieldArray['t3ver_label'] = 'INITIAL PLACEHOLDER';
00871                                                                                         $newVersion_placeholderFieldArray['t3ver_state'] = 1;   // Setting placeholder state value for temporary record
00872                                                                                         $newVersion_placeholderFieldArray['t3ver_wsid'] = $this->BE_USER->workspace;    // Setting workspace - only so display of place holders can filter out those from other workspaces.
00873                                                                                         $newVersion_placeholderFieldArray[$TCA[$table]['ctrl']['label']] = '[PLACEHOLDER, WS#'.$this->BE_USER->workspace.']';
00874                                                                                         $this->insertDB($table,$id,$newVersion_placeholderFieldArray,FALSE);    // Saving placeholder as 'original'
00875 
00876                                                                                                 // For the actual new offline version, set versioning values to point to placeholder:
00877                                                                                         $fieldArray['pid'] = -1;
00878                                                                                         $fieldArray['t3ver_oid'] = $this->substNEWwithIDs[$id];
00879                                                                                         $fieldArray['t3ver_id'] = 1;
00880                                                                                         $fieldArray['t3ver_state'] = -1;        // Setting placeholder state value for version (so it can know it is currently a new version...)
00881                                                                                         $fieldArray['t3ver_label'] = 'First draft version';
00882                                                                                         $fieldArray['t3ver_wsid'] = $this->BE_USER->workspace;
00883                                                                                         if ($table==='pages') {         // Swap mode set to "branch" so we can build branches for pages.
00884                                                                                                 $fieldArray['t3ver_swapmode'] = $versioningType;
00885                                                                                         }
00886                                                                                         $phShadowId = $this->insertDB($table,$id,$fieldArray,TRUE,0,TRUE);      // When inserted, $this->substNEWwithIDs[$id] will be changed to the uid of THIS version and so the interface will pick it up just nice!
00887                                                                                         if ($phShadowId)        {
00888                                                                                                 $this->placeholderShadowing($table,$phShadowId);
00889                                                                                                         // Hold auto-versionized ids of placeholders:
00890                                                                                                 $this->autoVersionIdMap[$table][$this->substNEWwithIDs[$id]] = $phShadowId;
00891                                                                                         }
00892                                                                                 } else $this->newlog('Versioning type "'.$versioningType.'" was not allowed, so could not create new record.',1);
00893                                                                         } else {
00894                                                                                 $this->insertDB($table,$id,$fieldArray,FALSE,$incomingFieldArray['uid']);
00895                                                                         }
00896                                                                 } else {
00897                                                                         $this->updateDB($table,$id,$fieldArray);
00898                                                                         $this->placeholderShadowing($table,$id);
00899                                                                 }
00900                                                         }
00901 
00902                                                                 /*
00903                                                                  * Hook: processDatamap_afterDatabaseOperations
00904                                                                  *
00905                                                                  * Note: When using the hook after INSERT operations, you will only get the temporary NEW... id passed to your hook as $id,
00906                                                                  *               but you can easily translate it to the real uid of the inserted record using the $this->substNEWwithIDs array.
00907                                                                  */
00908                                                         $this->hook_processDatamap_afterDatabaseOperations($hookObjectsArr, $status, $table, $id, $fieldArray);
00909                                                 }       // if ($recordAccess)   {
00910                                         }       // if (is_array($incomingFieldArray))   {
00911                                 }
00912                         }
00913                 }
00914 
00915                         // Process the stack of relations to remap/correct
00916                 $this->processRemapStack();
00917 
00918                 $this->dbAnalysisStoreExec();
00919                 $this->removeRegisteredFiles();
00920         }
00921 
00929         function placeholderShadowing($table,$id)       {
00930                 global $TCA;
00931 
00932                 t3lib_div::loadTCA($table);
00933                 if ($liveRec = t3lib_BEfunc::getLiveVersionOfRecord($table,$id,'*'))    {
00934                         if ((int)$liveRec['t3ver_state']>0)     {
00935                                 $justStoredRecord = t3lib_BEfunc::getRecord($table,$id);
00936                                 $newRecord = array();
00937 
00938                                 $shadowCols = $TCA[$table]['ctrl']['shadowColumnsForNewPlaceholders'];
00939                                 $shadowCols.= ','.$TCA[$table]['ctrl']['languageField'];
00940                                 $shadowCols.= ','.$TCA[$table]['ctrl']['transOrigPointerField'];
00941                                 $shadowCols.= ','.$TCA[$table]['ctrl']['type'];
00942                                 $shadowCols.= ','.$TCA[$table]['ctrl']['label'];
00943 
00944                                 $shadowColumns = array_unique(t3lib_div::trimExplode(',', $shadowCols,1));
00945                                 foreach($shadowColumns as $fieldName)   {
00946                                         if (strcmp($justStoredRecord[$fieldName],$liveRec[$fieldName]) && isset($TCA[$table]['columns'][$fieldName]) && $fieldName!=='uid' && $fieldName!=='pid')       {
00947                                                 $newRecord[$fieldName] = $justStoredRecord[$fieldName];
00948                                         }
00949                                 }
00950 
00951                                 if (count($newRecord))  {
00952                                         $this->newlog('Shadowing done on fields '.implode(',',array_keys($newRecord)).' in Placeholder record '.$table.':'.$liveRec['uid'].' (offline version UID='.$id.')');
00953                                         $this->updateDB($table,$liveRec['uid'],$newRecord);
00954                                 }
00955                         }
00956                 }
00957         }
00958 
00972         function fillInFieldArray($table,$id,$fieldArray,$incomingFieldArray,$realPid,$status,$tscPID)  {
00973                 global $TCA;
00974 
00975                         // Initialize:
00976                 t3lib_div::loadTCA($table);
00977                 $originalLanguageRecord = NULL;
00978                 $originalLanguage_diffStorage = NULL;
00979                 $diffStorageFlag = FALSE;
00980 
00981                         // Setting 'currentRecord' and 'checkValueRecord':
00982                 if (strstr($id,'NEW'))  {
00983                         $currentRecord = $checkValueRecord = $fieldArray;       // must have the 'current' array - not the values after processing below...
00984 
00985                                 // IF $incomingFieldArray is an array, overlay it.
00986                                 // The point is that when new records are created as copies with flex type fields there might be a field containing information about which DataStructure to use and without that information the flexforms cannot be correctly processed.... This should be OK since the $checkValueRecord is used by the flexform evaluation only anyways...
00987                         if (is_array($incomingFieldArray) && is_array($checkValueRecord))       {
00988                                 $checkValueRecord = t3lib_div::array_merge_recursive_overrule($checkValueRecord, $incomingFieldArray);
00989                         }
00990                 } else {
00991                         $currentRecord = $checkValueRecord = $this->recordInfo($table,$id,'*'); // We must use the current values as basis for this!
00992 
00993                         t3lib_BEfunc::fixVersioningPid($table,$currentRecord);  // This is done to make the pid positive for offline versions; Necessary to have diff-view for pages_language_overlay in workspaces.
00994 
00995                                 // Get original language record if available:
00996                         if (is_array($currentRecord)
00997                                         && $TCA[$table]['ctrl']['transOrigDiffSourceField']
00998                                         && $TCA[$table]['ctrl']['languageField']
00999                                         && $currentRecord[$TCA[$table]['ctrl']['languageField']] > 0
01000                                         && $TCA[$table]['ctrl']['transOrigPointerField']
01001                                         && intval($currentRecord[$TCA[$table]['ctrl']['transOrigPointerField']]) > 0)   {
01002 
01003                                 $lookUpTable = $TCA[$table]['ctrl']['transOrigPointerTable'] ? $TCA[$table]['ctrl']['transOrigPointerTable'] : $table;
01004                                 $originalLanguageRecord = $this->recordInfo($lookUpTable,$currentRecord[$TCA[$table]['ctrl']['transOrigPointerField']],'*');
01005                                 t3lib_BEfunc::workspaceOL($lookUpTable,$originalLanguageRecord);
01006                                 $originalLanguage_diffStorage = unserialize($currentRecord[$TCA[$table]['ctrl']['transOrigDiffSourceField']]);
01007                         }
01008                 }
01009                 $this->checkValue_currentRecord = $checkValueRecord;
01010 
01011                         /*
01012                                 In the following all incoming value-fields are tested:
01013                                 - Are the user allowed to change the field?
01014                                 - Is the field uid/pid (which are already set)
01015                                 - perms-fields for pages-table, then do special things...
01016                                 - If the field is nothing of the above and the field is configured in TCA, the fieldvalues are evaluated by ->checkValue
01017 
01018                                 If everything is OK, the field is entered into $fieldArray[]
01019                         */
01020                 foreach($incomingFieldArray as $field => $fieldValue)   {
01021                         if (!in_array($table.'-'.$field, $this->exclude_array) && !$this->data_disableFields[$table][$id][$field])      {       // The field must be editable.
01022 
01023                                         // Checking if a value for language can be changed:
01024                                 $languageDeny = $TCA[$table]['ctrl']['languageField'] && !strcmp($TCA[$table]['ctrl']['languageField'], $field) && !$this->BE_USER->checkLanguageAccess($fieldValue);
01025 
01026                                 if (!$languageDeny)     {
01027                                                 // Stripping slashes - will probably be removed the day $this->stripslashes_values is removed as an option...
01028                                         if ($this->stripslashes_values) {
01029                                                 if (is_array($fieldValue))      {
01030                                                         t3lib_div::stripSlashesOnArray($fieldValue);
01031                                                 } else $fieldValue = stripslashes($fieldValue);
01032                                         }
01033 
01034                                         switch ($field) {
01035                                                 case 'uid':
01036                                                 case 'pid':
01037                                                         // Nothing happens, already set
01038                                                 break;
01039                                                 case 'perms_userid':
01040                                                 case 'perms_groupid':
01041                                                 case 'perms_user':
01042                                                 case 'perms_group':
01043                                                 case 'perms_everybody':
01044                                                                 // Permissions can be edited by the owner or the administrator
01045                                                         if ($table=='pages' && ($this->admin || $status=='new' || $this->pageInfo($id,'perms_userid')==$this->userid) ) {
01046                                                                 $value=intval($fieldValue);
01047                                                                 switch($field)  {
01048                                                                         case 'perms_userid':
01049                                                                                 $fieldArray[$field]=$value;
01050                                                                         break;
01051                                                                         case 'perms_groupid':
01052                                                                                 $fieldArray[$field]=$value;
01053                                                                         break;
01054                                                                         default:
01055                                                                                 if ($value>=0 && $value<pow(2,5))       {
01056                                                                                         $fieldArray[$field]=$value;
01057                                                                                 }
01058                                                                         break;
01059                                                                 }
01060                                                         }
01061                                                 break;
01062                                                 case 't3ver_oid':
01063                                                 case 't3ver_id':
01064                                                 case 't3ver_wsid':
01065                                                 case 't3ver_state':
01066                                                 case 't3ver_swapmode':
01067                                                 case 't3ver_count':
01068                                                 case 't3ver_stage':
01069                                                 case 't3ver_tstamp':
01070                                                         // t3ver_label is not here because it CAN be edited as a regular field!
01071                                                 break;
01072                                                 default:
01073                                                         if (isset($TCA[$table]['columns'][$field]))     {
01074                                                                         // Evaluating the value.
01075                                                                 $res = $this->checkValue($table,$field,$fieldValue,$id,$status,$realPid,$tscPID);
01076                                                                 if (isset($res['value']))       {
01077                                                                         $fieldArray[$field]=$res['value'];
01078 
01079                                                                                 // Add the value of the original record to the diff-storage content:
01080                                                                         if ($TCA[$table]['ctrl']['transOrigDiffSourceField'])   {
01081                                                                                 $originalLanguage_diffStorage[$field] = $originalLanguageRecord[$field];
01082                                                                                 $diffStorageFlag = TRUE;
01083                                                                         }
01084                                                                 }
01085 
01086 
01087                                                                         // If autoversioning is happening we need to perform a nasty hack. The case is parallel to a similar hack inside checkValue_group_select_file().
01088                                                                         // When a copy or version is made of a record, a search is made for any RTEmagic* images in fields having the "images" soft reference parser applied. That should be true for RTE fields. If any are found they are duplicated to new names and the file reference in the bodytext is updated accordingly.
01089                                                                         // However, with auto-versioning the submitted content of the field will just overwrite the corrected values. This leaves a) lost RTEmagic files and b) creates a double reference to the old files.
01090                                                                         // The only solution I can come up with is detecting when auto versioning happens, then see if any RTEmagic images was copied and if so make a stupid string-replace of the content !
01091                                                                 if ($this->autoVersioningUpdate===TRUE) {
01092                                                                         if (is_array($this->RTEmagic_copyIndex[$table][$id][$field]))   {
01093                                                                                 foreach($this->RTEmagic_copyIndex[$table][$id][$field] as $oldRTEmagicName => $newRTEmagicName) {
01094                                                                                         $fieldArray[$field] = str_replace(' src="'.$oldRTEmagicName.'"',' src="'.$newRTEmagicName.'"',$fieldArray[$field]);
01095                                                                                 }
01096                                                                         }
01097                                                                 }
01098 
01099                                                         } elseif ($TCA[$table]['ctrl']['origUid']===$field) {   // Allow value for original UID to pass by...
01100                                                                 $fieldArray[$field] = $fieldValue;
01101                                                         }
01102                                                 break;
01103                                         }
01104                                 }       // Checking language.
01105                         }       // Check exclude fields / disabled fields...
01106                 }
01107                         // Add diff-storage information:
01108                 if ($diffStorageFlag && !isset($fieldArray[$TCA[$table]['ctrl']['transOrigDiffSourceField']]))  {       // If the field is set it would probably be because of an undo-operation - in which case we should not update the field of course...
01109                          $fieldArray[$TCA[$table]['ctrl']['transOrigDiffSourceField']] = serialize($originalLanguage_diffStorage);
01110                 }
01111 
01112                         // Checking for RTE-transformations of fields:
01113                 $types_fieldConfig = t3lib_BEfunc::getTCAtypes($table,$currentRecord);
01114                 $theTypeString =