Documentation TYPO3 par Ameos

class.t3lib_tcemain.php

00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00163 // *******************************
00164 // Including necessary libraries
00165 // *******************************
00166 require_once (PATH_t3lib.'class.t3lib_loaddbgroup.php');
00167 require_once (PATH_t3lib.'class.t3lib_parsehtml_proc.php');
00168 require_once (PATH_t3lib.'class.t3lib_stdgraphic.php');
00169 require_once (PATH_t3lib.'class.t3lib_basicfilefunc.php');
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00199 class t3lib_TCEmain     {
00200         var $log_table = 'sys_log';
00201 
00202         var $checkStoredRecords = 1;    // 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
00203         var $checkStoredRecords_loose=1;        // If set, values '' and 0 will equal each other when the stored records are checked.
00204         var $sortIntervals = 256;               // The interval between sorting numbers used with tables with a 'sorting' field defined. Min 1
00205 
00206         var $deleteTree = 0;                    // 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 delete ONLY if it has no branch
00207         var $copyTree = 0;                              // int. 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
00208         var $versionizeTree = 0;                // int. If 0 then branch is NOT versionized. If 1 then pages on the 1st level is versionized. If 2 then pages on the second level is versionized ... and so on
00209         var $neverHideAtCopy = 0;               // Boolean. If set, then the 'hideAtCopy' flag for tables will be ignored.
00210         var $reverseOrder=0;                    // boolean. If set, the dataarray is reversed in the order, which is a nice thing if you're creating a whole new bunch of records.
00211         var $copyWhichTables = '*';             // 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)
00212         var $stripslashes_values=1;             // If set, 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!
00213         var $storeLogMessages=1;                // If set, 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.
00214         var $enableLogging=1;                   // If set, actions are logged.
00215 
00216         var $callBackObj;                               // Call back object for flex form traversation. Useful when external classes wants to use the iteration functions inside tcemain for traversing a FlexForm structure.
00217 
00218 //      var $history=1;                                 // Bit-array: Bit0: History on/off. DEPENDS on checkSimilar to be set!
00219         var $checkSimilar=1;                    // Boolean: If set, 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.
00220         var $dontProcessTransformations=0;      // Boolean: If set, then transformations are NOT performed on the input.
00221 #       var $disableRTE = 0;                    // Boolean: If set, the RTE is expected to have been disabled in the interface which submitted information. Thus transformations related to the RTE is not done.
00222 
00223         var $pMap = Array(              // Permission mapping
00224                 'show' => 1,                    // 1st bit
00225                 'edit' => 2,                    // 2nd bit
00226                 'delete' => 4,                  // 3rd bit
00227                 'new' => 8,                             // 4th bit
00228                 'editcontent' => 16             // 5th bit
00229         );
00230         var $defaultPermissions = array(                // Can be overridden from $TYPO3_CONF_VARS
00231                 'user' => 'show,edit,delete,new,editcontent',
00232                 'group' => 'show,edit,new,editcontent',
00233                 'everybody' => ''
00234         );
00235 
00236 
00237         var $alternativeFileName=array();               // 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.
00238         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.
00239         var $defaultValues=array();                             // You can set this array on the form $defaultValues[$table][$field] = $value to override the default values fetched from TCA. You must set this externally.
00240         var $overrideValues=array();                    // 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!
00241         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)
00242 
00243                 // *********
00244                 // internal
00245                 // *********
00246         var $fileFunc;          // May contain an object
00247         var $last_log_id;
00248         var $BE_USER;           // The user-object the script uses. If not set from outside, this is set to the current global $BE_USER.
00249         var $userid;            // will be set to uid of be_user executing this script
00250         var $username;          // will be set to username of be_user executing this script
00251         var $admin;                     // will be set if user is admin
00252         var $exclude_array;     // the list of <table>-<fields> that cannot be edited. This is compiled from TCA/exclude-flag combined with non_exclude_fields for the user.
00253 
00254         var $data = Array();
00255         var $datamap = Array();
00256         var $cmd = Array();
00257         var $cmdmap = Array();
00258         var $uploadedFileArray = array();
00259 
00260         var $cachedTSconfig = array();
00261         var $substNEWwithIDs = Array();
00262         var $substNEWwithIDs_table = Array();
00263         var $recUpdateAccessCache = Array();    // Used by function checkRecordUpdateAccess() to store whether a record is updateable or not.
00264         var $recInsertAccessCache = Array();
00265         var $isRecordInWebMount_Cache=array();
00266         var $isInWebMount_Cache=array();
00267         var $pageCache = Array();                                       // Used for caching page records in pageInfo()
00268         var $copyMappingArray = Array();                        // Use by the copy action to track the ids of new pages so subpages are correctly inserted!
00269         var $copyMappingArray_merged = Array();         // This array is the sum of all copying operations in this class. May be READ from outside, thus partly public.
00270         var $registerDBList=array();
00271         var $dbAnalysisStore=array();
00272         var $removeFilesStore=array();
00273         var $copiedFileMap=array();
00274 
00275         var $checkValue_currentRecord=array();          // Set to "currentRecord" during checking of values.
00276 
00277 
00288         function start($data,$cmd,$altUserObject='')    {
00289                         // Initializing BE_USER
00290                 $this->BE_USER = is_object($altUserObject) ? $altUserObject : $GLOBALS['BE_USER'];
00291                 $this->userid = $this->BE_USER->user['uid'];
00292                 $this->username = $this->BE_USER->user['username'];
00293                 $this->admin = $this->BE_USER->user['admin'];
00294 
00295                         // Initializing default permissions for pages
00296                 $defaultPermissions = $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPermissions'];
00297                 if (isset($defaultPermissions['user']))         {$this->defaultPermissions['user'] = $defaultPermissions['user'];}
00298                 if (isset($defaultPermissions['group']))                {$this->defaultPermissions['group'] = $defaultPermissions['group'];}
00299                 if (isset($defaultPermissions['everybody']))            {$this->defaultPermissions['everybody'] = $defaultPermissions['everybody'];}
00300 
00301                         // generates the excludelist, based on TCA/exclude-flag and non_exclude_fields for the user:
00302                 $this->exclude_array = ($this->admin) ? array() : $this->getExcludeListArray();
00303 
00304                         // Setting the data and cmd arrays
00305                 if (is_array($data)) {
00306                         reset($data);
00307                         $this->datamap = $data;
00308                 }
00309                 if (is_array($cmd))     {
00310                         reset($cmd);
00311                         $this->cmdmap = $cmd;
00312                 }
00313         }
00314 
00321         function setMirror($mirror)     {
00322                 if (is_array($mirror))  {
00323                         reset($mirror);
00324                         while(list($table,$uid_array)=each($mirror))    {
00325                                 if (isset($this->datamap[$table]))      {
00326                                         reset($uid_array);
00327                                         while (list($id,$uidList) = each($uid_array))   {
00328                                                 if (isset($this->datamap[$table][$id])) {
00329                                                         $theIdsInArray = t3lib_div::trimExplode(',',$uidList,1);
00330                                                         while(list(,$copyToUid)=each($theIdsInArray))   {
00331                                                                 $this->datamap[$table][$copyToUid] = $this->datamap[$table][$id];
00332                                                         }
00333                                                 }
00334                                         }
00335                                 }
00336                         }
00337                 }
00338         }
00339 
00346         function setDefaultsFromUserTS($userTS) {
00347                 global $TCA;
00348                 if (is_array($userTS))  {
00349                         foreach($userTS as $k => $v)    {
00350                                 $k = substr($k,0,-1);
00351                                 if ($k && is_array($v) && isset($TCA[$k]))      {
00352                                         if (is_array($this->defaultValues[$k])) {
00353                                                 $this->defaultValues[$k] = array_merge($this->defaultValues[$k],$v);
00354                                         } else {
00355                                                 $this->defaultValues[$k] = $v;
00356                                         }
00357                                 }
00358                         }
00359                 }
00360         }
00361 
00369         function process_uploads($postFiles)    {
00370                 if (is_array($postFiles))       {
00371                         reset($postFiles);
00372                         $subA = current($postFiles);
00373                         if (is_array($subA))    {
00374                                 if (is_array($subA['name']) && is_array($subA['type']) && is_array($subA['tmp_name']) && is_array($subA['size']))       {
00375                                                 // Initialize the uploadedFilesArray:
00376                                         $this->uploadedFileArray=array();
00377 
00378                                                 // For each entry:
00379                                         foreach($subA as $key => $values)       {
00380                                                 $this->process_uploads_traverseArray($this->uploadedFileArray,$values,$key);
00381                                         }
00382                                 } else {
00383                                         $this->uploadedFileArray=$subA;
00384                                 }
00385                         }
00386                 }
00387         }
00388 
00399         function process_uploads_traverseArray(&$outputArr,$inputArr,$keyToSet) {
00400                 if (is_array($inputArr))        {
00401                         foreach($inputArr as $key => $value)    {
00402                                 $this->process_uploads_traverseArray($outputArr[$key],$inputArr[$key],$keyToSet);
00403                         }
00404                 } else {
00405                         $outputArr[$keyToSet]=$inputArr;
00406                 }
00407         }
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423         /*********************************************
00424          *
00425          * PROCESSING DATA
00426          *
00427          *********************************************/
00428 
00435         function process_datamap() {
00436                 global $TCA, $TYPO3_CONF_VARS;
00437 
00438                         // First prepare user defined objects (if any) for hooks which extend this function:
00439                 $hookObjectsArr = array();
00440                 if (is_array ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'])) {
00441                         foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'] as $classRef) {
00442                                 $hookObjectsArr[] = &t3lib_div::getUserObj($classRef);
00443                         }
00444                 }
00445 
00446                         // Organize tables so that the pages-table are always processed first. This is required if you want to make sure that content pointing to a new page will be created.
00447                 $orderOfTables = Array();
00448                 if (isset($this->datamap['pages']))     {               // Set pages first.
00449                         $orderOfTables[]='pages';
00450                 }
00451                 reset($this->datamap);
00452                 while (list($table,) = each($this->datamap))    {
00453                         if ($table!='pages')    {
00454                                 $orderOfTables[]=$table;
00455                         }
00456                 }
00457 
00458                         // Process the tables...
00459                 foreach($orderOfTables as $table)       {
00460                                 /* Check if
00461                                         - table is set in $TCA,
00462                                         - table is NOT readOnly,
00463                                         - the table is set with content in the data-array (if not, there's nothing to process...)
00464                                         - permissions for tableaccess OK
00465                                 */
00466                         $modifyAccessList = $this->checkModifyAccessList($table);
00467                         if (!$modifyAccessList) {
00468                                 $this->log($table,$id,2,0,1,"Attempt to modify table '%s' without permission",1,array($table));
00469                         }
00470                         if (isset($TCA[$table]) && !$this->tableReadOnly($table) && is_array($this->datamap[$table]) && $modifyAccessList)      {
00471                                 if ($this->reverseOrder)        {
00472                                         $this->datamap[$table] = array_reverse($this->datamap[$table], 1);
00473                                 }
00474 
00475                                         // For each record from the table, do:
00476                                         // $id is the record uid, may be a string if new records...
00477                                         // $incomingFieldArray is the array of fields
00478                                 foreach($this->datamap[$table] as $id => $incomingFieldArray)   {
00479                                         if (is_array($incomingFieldArray))      {
00480 
00481                                                         // Hook: processDatamap_preProcessIncomingFieldArray
00482                                                 foreach($hookObjectsArr as $hookObj)    {
00483                                                         if (method_exists($hookObj, 'processDatamap_preProcessFieldArray')) {
00484                                                                 $hookObj->processDatamap_preProcessFieldArray($incomingFieldArray, $table, $id, $this);
00485                                                         }
00486                                                 }
00487 
00488                                                         // ******************************
00489                                                         // Checking access to the record
00490                                                         // ******************************
00491                                                 $recordAccess = 0;
00492                                                 $old_pid_value = '';
00493                                                 if (!t3lib_div::testInt($id)) {               // Is it a new record? (Then Id is a string)
00494                                                         $fieldArray = $this->newFieldArray($table);     // Get a fieldArray with default values
00495                                                         if (isset($incomingFieldArray['pid']))  {       // A pid must be set for new records.
00496                                                                         // $value = the pid
00497                                                                 $pid_value = $incomingFieldArray['pid'];
00498 
00499                                                                         // Checking and finding numerical pid, it may be a string-reference to another value
00500                                                                 $OK = 1;
00501                                                                 if (strstr($pid_value,'NEW'))   {       // If a NEW... id
00502                                                                         if (substr($pid_value,0,1)=='-') {$negFlag=-1;$pid_value=substr($pid_value,1);} else {$negFlag=1;}
00503                                                                         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.
00504                                                                                 $old_pid_value = $pid_value;
00505                                                                                 $pid_value=intval($negFlag*$this->substNEWwithIDs[$pid_value]);
00506                                                                         } else {$OK = 0;}       // If not found in the substArray we must stop the proces...
00507                                                                 }
00508                                                                 $pid_value = intval($pid_value);
00509 
00510                                                                         // The $pid_value is now the numerical pid at this point
00511                                                                 if ($OK)        {
00512                                                                         $sortRow = $TCA[$table]['ctrl']['sortby'];
00513                                                                         if ($pid_value>=0)      {       // Points to a page on which to insert the element, possibly in the top of the page
00514                                                                                 if ($sortRow)   {       // If this table is sorted we better find the top sorting number
00515                                                                                         $fieldArray[$sortRow] = $this->getSortNumber($table,0,$pid_value);
00516                                                                                 }
00517                                                                                 $fieldArray['pid'] = $pid_value;        // The numerical pid is inserted in the data array
00518                                                                         } else {        // points to another record before ifself
00519                                                                                 if ($sortRow)   {       // If this table is sorted we better find the top sorting number
00520                                                                                         $tempArray=$this->getSortNumber($table,0,$pid_value);   // Because $pid_value is < 0, getSortNumber returns an array
00521                                                                                         $fieldArray['pid'] = $tempArray['pid'];
00522                                                                                         $fieldArray[$sortRow] = $tempArray['sortNumber'];
00523                                                                                 } else {        // Here we fetch the PID of the record that we point to...
00524                                                                                         $tempdata = $this->recordInfo($table,abs($pid_value),'pid');
00525                                                                                         $fieldArray['pid']=$tempdata['pid'];
00526                                                                                 }
00527                                                                         }
00528                                                                 }
00529                                                         }
00530                                                         $theRealPid = $fieldArray['pid'];
00531                                                                 // Now, check if we may insert records on this pid.
00532                                                         if ($theRealPid>=0)     {
00533                                                                 $recordAccess = $this->checkRecordInsertAccess($table,$theRealPid);     // Checks if records can be inserted on this $pid.
00534                                                         } else {
00535                                                                 debug('Internal ERROR: pid should not be less than zero!');
00536                                                         }
00537                                                         $status = 'new';                                                // Yes new record, change $record_status to 'insert'
00538                                                 } else {        // Nope... $id is a number
00539                                                         $fieldArray = Array();
00540                                                         $recordAccess = $this->checkRecordUpdateAccess($table,$id);
00541                                                         if (!$recordAccess)             {
00542                                                                 $propArr = $this->getRecordProperties($table,$id);
00543                                                                 $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']);
00544                                                         } else {        // Next check of the record permissions (internals)
00545                                                                 $recordAccess = $this->BE_USER->recordEditAccessInternals($table,$id);
00546                                                                 if (!$recordAccess)             {
00547                                                                         $propArr = $this->getRecordProperties($table,$id);
00548                                                                         $this->log($table,$id,2,0,1,"recordEditAccessInternals() check failed. [".$this->BE_USER->errorMsg."]",2,array($propArr['header'],$table.':'.$id),$propArr['event_pid']);
00549                                                                 } else {        // Here we fetch the PID of the record that we point to...
00550                                                                         $tempdata = $this->recordInfo($table,$id,'pid');
00551                                                                         $theRealPid = $tempdata['pid'];
00552                                                                 }
00553                                                         }
00554                                                         $status = 'update';     // the default is 'update'
00555                                                 }
00556 
00557                                                         // **************************************
00558                                                         // If access was granted above, proceed:
00559                                                         // **************************************
00560                                                 if ($recordAccess)      {
00561 
00562                                                         list($tscPID) = t3lib_BEfunc::getTSCpid($table,$id,$old_pid_value ? $old_pid_value : $fieldArray['pid']);       // Here the "pid" is sent IF NOT the old pid was a string pointing to a place in the subst-id array.
00563                                                         $TSConfig = $this->getTCEMAIN_TSconfig($tscPID);
00564                                                         if ($status=='new' && $table=='pages' && is_array($TSConfig['permissions.']))   {
00565                                                                 $fieldArray = $this->setTSconfigPermissions($fieldArray,$TSConfig['permissions.']);
00566                                                         }
00567 
00568                                                         $fieldArray = $this->fillInFieldArray($table,$id,$fieldArray,$incomingFieldArray,$theRealPid,$status,$tscPID);
00569 
00570                                                                 // NOTICE! All manipulation beyond this point bypasses both "excludeFields" AND possible "MM" relations / file uploads to field!
00571 
00572                                                         $fieldArray = $this->overrideFieldArray($table,$fieldArray);    // NOTICE: This overriding is potentially dangerous; permissions per field is not checked!!!
00573 
00574                                                                 // Setting system fields
00575                                                         if ($status=='new')     {
00576                                                                 if ($TCA[$table]['ctrl']['crdate'])     {
00577                                                                         $fieldArray[$TCA[$table]['ctrl']['crdate']]=time();
00578                                                                 }
00579                                                                 if ($TCA[$table]['ctrl']['cruser_id'])  {
00580                                                                         $fieldArray[$TCA[$table]['ctrl']['cruser_id']]=$this->userid;
00581                                                                 }
00582                                                         } elseif ($this->checkSimilar) {        // Removing fields which are equal to the current value:
00583                                                                 $fieldArray = $this->compareFieldArrayWithCurrentAndUnset($table,$id,$fieldArray);
00584                                                         }
00585                                                         if ($TCA[$table]['ctrl']['tstamp'])     {
00586                                                                 $fieldArray[$TCA[$table]['ctrl']['tstamp']]=time();
00587                                                         }
00588 
00589                                                                 // Hook: processDatamap_postProcessFieldArray
00590                                                         foreach($hookObjectsArr as $hookObj)    {
00591                                                                 if (method_exists($hookObj, 'processDatamap_postProcessFieldArray')) {
00592                                                                         $hookObj->processDatamap_postProcessFieldArray($status, $table, $id, $fieldArray, $this);
00593                                                                 }
00594                                                         }
00595 
00596                                                                 // Performing insert/update. If fieldArray has been unset by some userfunction (see hook above), don't do anything
00597                                                                 // Kasper: Unsetting the fieldArray is dangerous; MM relations might be saved already and files could have been uploaded that are now "lost"
00598                                                         if (is_array($fieldArray)) {
00599                                                                 if ($status=='new')     {
00600         //                                                              if ($pid_value<0)       {$fieldArray = $this->fixCopyAfterDuplFields($table,$id,abs($pid_value),0,$fieldArray);}        // Out-commented 02-05-02: I couldn't understand WHY this is needed for NEW records. Obviously to proces records being copied? Problem is that the fields are not set anyways and the copying function should basically take care of this!
00601                                                                         $this->insertDB($table,$id,$fieldArray,FALSE,$incomingFieldArray['uid']);
00602                                                                 } else {
00603                                                                         $this->updateDB($table,$id,$fieldArray);
00604                                                                 }
00605                                                         }
00606 
00607                                                                 // Hook: processDatamap_afterDatabaseOperations
00608                                                         foreach($hookObjectsArr as $hookObj)    {
00609                                                                 if (method_exists($hookObj, 'processDatamap_afterDatabaseOperations')) {
00610                                                                         $hookObj->processDatamap_afterDatabaseOperations($status, $table, $id, $fieldArray, $this);
00611                                                                 }
00612                                                         }
00613                                                 }       // if ($recordAccess)   {
00614                                         }       // if (is_array($incomingFieldArray))   {
00615                                 }
00616                         }
00617                 }
00618                 $this->dbAnalysisStoreExec();
00619                 $this->removeRegisteredFiles();
00620         }
00621 
00635         function fillInFieldArray($table,$id,$fieldArray,$incomingFieldArray,$realPid,$status,$tscPID)  {
00636                 global $TCA;
00637 
00638                         // Initialize:
00639                 t3lib_div::loadTCA($table);
00640                 unset($originalLanguageRecord);
00641                 unset($originalLanguage_diffStorage);
00642                 $diffStorageFlag = FALSE;
00643 
00644                         // Setting 'currentRecord' and 'checkValueRecord':
00645                 if (strstr($id,'NEW'))  {
00646                         $currentRecord = $checkValueRecord = $fieldArray;       // must have the 'current' array - not the values after processing below...
00647 
00648                                 // IF $incomingFieldArray is an array, overlay it.
00649                                 // 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...
00650                         if (is_array($incomingFieldArray) && is_array($checkValueRecord))       {
00651                                 $checkValueRecord = t3lib_div::array_merge_recursive_overrule($checkValueRecord, $incomingFieldArray);
00652                         }
00653                 } else {
00654                         $currentRecord = $checkValueRecord = $this->recordInfo($table,$id,'*'); // We must use the current values as basis for this!
00655 
00656                                 // Get original language record if available:
00657                         if (is_array($currentRecord)
00658                                         && $TCA[$table]['ctrl']['transOrigDiffSourceField']
00659                                         && $TCA[$table]['ctrl']['languageField']
00660                                         && $currentRecord[$TCA[$table]['ctrl']['languageField']] > 0
00661                                         && $TCA[$table]['ctrl']['transOrigPointerField']
00662                                         && intval($currentRecord[$TCA[$table]['ctrl']['transOrigPointerField']]) > 0)   {
00663 
00664                                 $lookUpTable = $TCA[$table]['ctrl']['transOrigPointerTable'] ? $TCA[$table]['ctrl']['transOrigPointerTable'] : $table;
00665                                 $originalLanguageRecord = $this->recordInfo($lookUpTable,$currentRecord[$TCA[$table]['ctrl']['transOrigPointerField']],'*');
00666                                 $originalLanguage_diffStorage = unserialize($currentRecord[$TCA[$table]['ctrl']['transOrigDiffSourceField']]);
00667                         }
00668                 }
00669                 $this->checkValue_currentRecord = $checkValueRecord;
00670 
00671                         /*
00672                                 In the following all incoming value-fields are tested:
00673                                 - Are the user allowed to change the field?
00674                                 - Is the field uid/pid (which are already set)
00675                                 - perms-fields for pages-table, then do special things...
00676                                 - If the field is nothing of the above and the field is configured in TCA, the fieldvalues are evaluated by ->checkValue
00677 
00678                                 If everything is OK, the field is entered into $fieldArray[]
00679                         */
00680                 foreach($incomingFieldArray as $field => $fieldValue)   {
00681                         if (!in_array($table.'-'.$field, $this->exclude_array) && !$this->data_disableFields[$table][$id][$field])      {       // The field must be editable.
00682 
00683                                         // Checking language:
00684                                 $languageDeny = $TCA[$table]['ctrl']['languageField'] && !strcmp($TCA[$table]['ctrl']['languageField'], $field) && !$this->BE_USER->checkLanguageAccess($fieldValue);
00685 
00686                                 if (!$languageDeny)     {
00687                                                 // Stripping slashes - will probably be removed the day $this->stripslashes_values is removed as an option...
00688                                         if ($this->stripslashes_values) {
00689                                                 if (is_array($fieldValue))      {
00690                                                         t3lib_div::stripSlashesOnArray($fieldValue);
00691                                                 } else $fieldValue = stripslashes($fieldValue);
00692                                         }
00693 
00694                                         switch ($field) {
00695                                                 case 'uid':
00696                                                 case 'pid':
00697                                                         // Nothing happens, already set
00698                                                 break;
00699                                                 case 'perms_userid':
00700                                                 case 'perms_groupid':
00701                                                 case 'perms_user':
00702                                                 case 'perms_group':
00703                                                 case 'perms_everybody':
00704                                                                 // Permissions can be edited by the owner or the administrator
00705                                                         if ($table=='pages' && ($this->admin || $status=='new' || $this->pageInfo($id,'perms_userid')==$this->userid) ) {
00706                                                                 $value=intval($fieldValue);
00707                                                                 switch($field)  {
00708                                                                         case 'perms_userid':
00709                                                                                 $fieldArray[$field]=$value;
00710                                                                         break;
00711                                                                         case 'perms_groupid':
00712                                                                                 $fieldArray[$field]=$value;
00713                                                                         break;
00714                                                                         default:
00715                                                                                 if ($value>=0 && $value<pow(2,5))       {
00716                                                                                         $fieldArray[$field]=$value;
00717                                                                                 }
00718                                                                         break;
00719                                                                 }
00720                                                         }
00721                                                 break;
00722                                                 case 't3ver_oid':
00723                                                 case 't3ver_id':
00724                                                         // t3ver_label is not here because it CAN be edited as a regular field!
00725                                                 break;
00726                                                 default:
00727                                                         if (isset($TCA[$table]['columns'][$field]))     {
00728                                                                         // Evaluating the value.
00729                                                                 $res = $this->checkValue($table,$field,$fieldValue,$id,$status,$realPid,$tscPID);
00730                                                                 if (isset($res['value']))       {
00731                                                                         $fieldArray[$field]=$res['value'];
00732 
00733                                                                                 // Add the value of the original record to the diff-storage content:
00734                                                                         if ($TCA[$table]['ctrl']['transOrigDiffSourceField'])   {
00735                                                                                 $originalLanguage_diffStorage[$field] = $originalLanguageRecord[$field];
00736                                                                                 $diffStorageFlag = TRUE;
00737                                                                         }
00738                                                                 }
00739                                                         }
00740 
00741 
00742                                                 break;
00743                                         }
00744                                 }       // Checking language.
00745                         }       // Check exclude fields / disabled fields...
00746                 }
00747 
00748                         // Add diff-storage information:
00749                 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...
00750                          $fieldArray[$TCA[$table]['ctrl']['transOrigDiffSourceField']] = serialize($originalLanguage_diffStorage);
00751                 }
00752 
00753                         // Checking for RTE-transformations of fields:
00754                 $types_fieldConfig = t3lib_BEfunc::getTCAtypes($table,$currentRecord);
00755                 $theTypeString = t3lib_BEfunc::getTCAtypeValue($table,$currentRecord);
00756                 if (is_array($types_fieldConfig))       {
00757                         reset($types_fieldConfig);
00758                         while(list(,$vconf) = each($types_fieldConfig)) {
00759                                         // Write file configuration:
00760                                 $eFile = t3lib_parsehtml_proc::evalWriteFile($vconf['spec']['static_write'],array_merge($currentRecord,$fieldArray));   // inserted array_merge($currentRecord,$fieldArray) 170502
00761 
00762                                         // RTE transformations:
00763                                 if (!$this->dontProcessTransformations) {
00764                                         if (isset($fieldArray[$vconf['field']]))        {
00765                                                         // Look for transformation flag:
00766                                                 switch((string)$incomingFieldArray['_TRANSFORM_'.$vconf['field']])      {
00767                                                         case 'RTE':
00768                                                                 $RTEsetup = $this->BE_USER->getTSConfig('RTE',t3lib_BEfunc::getPagesTSconfig($tscPID));
00769                                                                 $thisConfig = t3lib_BEfunc::RTEsetup($RTEsetup['properties'],$table,$vconf['field'],$theTypeString);
00770 
00771                                                                         // Set alternative relative path for RTE images/links:
00772                                                                 $RTErelPath = is_array($eFile) ? dirname($eFile['relEditFile']) : '';
00773 
00774                                                                         // Get RTE object, draw form and set flag:
00775                                                                 $RTEobj = &t3lib_BEfunc::RTEgetObj();
00776                                                                 if (is_object($RTEobj)) {
00777                                                                         $fieldArray[$vconf['field']] = $RTEobj->transformContent('db',$fieldArray[$vconf['field']],$table,$vconf['field'],$currentRecord,$vconf['spec'],$thisConfig,$RTErelPath,$currentRecord['pid']);
00778                                                                 } else {
00779                                                                         debug('NO RTE OBJECT FOUND!');
00780                                                                 }
00781                                                         break;
00782                                                 }
00783                                         }
00784                                 }
00785 
00786                                         // Write file configuration:
00787                                 if (is_array($eFile))   {
00788                                         $mixedRec = array_merge($currentRecord,$fieldArray);
00789                                         $SW_fileContent = t3lib_div::getUrl($eFile['editFile']);
00790                                         $parseHTML = t3lib_div::makeInstance('t3lib_parsehtml_proc');
00791                                         $parseHTML->init('','');
00792 
00793                                         $eFileMarker = $eFile['markerField']&&trim($mixedRec[$eFile['markerField']]) ? trim($mixedRec[$eFile['markerField']]) : '###TYPO3_STATICFILE_EDIT###';
00794                                         $insertContent = str_replace($eFileMarker,'',$mixedRec[$eFile['contentField']]);        // must replace the marker if present in content!
00795 
00796                                         $SW_fileNewContent = $parseHTML->substituteSubpart($SW_fileContent, $eFileMarker, chr(10).$insertContent.chr(10), 1, 1);
00797                                         t3lib_div::writeFile($eFile['editFile'],$SW_fileNewContent);
00798 
00799                                                 // Write status:
00800                                         if (!strstr($id,'NEW') && $eFile['statusField'])        {
00801                                                 $GLOBALS['TYPO3_DB']->exec_UPDATEquery(
00802                                                         $table,
00803                                                         'uid='.intval($id),
00804                                                         array(
00805                                                                 $eFile['statusField'] => $eFile['relEditFile'].' updated '.date('d-m-Y H:i:s').', bytes '.strlen($mixedRec[$eFile['contentField']])
00806                                                         )
00807                                                 );
00808                                         }
00809                                 } elseif ($eFile && is_string($eFile))  {
00810                                         $this->log($insertTable,$id,2,0,1,"Write-file error: '%s'",13,array($eFile),$realPid);
00811                                 }
00812                         }
00813                 }
00814                         // Return fieldArray
00815                 return $fieldArray;
00816         }
00817 
00826         function checkModifyAccessList($table)  {
00827                 $res = ($this->admin || (!$this->tableAdminOnly($table) && t3lib_div::inList($this->BE_USER->groupData['tables_modify'],$table)));
00828                 return $res;
00829         }
00830 
00838         function isRecordInWebMount($table,$id) {
00839                 if (!isset($this->isRecordInWebMount_Cache[$table.':'.$id]))    {
00840                         $recP=$this->getRecordProperties($table,$id);
00841                         $this->isRecordInWebMount_Cache[$table.':'.$id]=$this->isInWebMount($recP['event_pid']);
00842                 }
00843                 return $this->isRecordInWebMount_Cache[$table.':'.$id];
00844         }
00845 
00852         function isInWebMount($pid)     {
00853                 if (!isset($this->isInWebMount_Cache[$pid]))    {
00854                         $this->isInWebMount_Cache[$pid]=$this->BE_USER->isInWebMount($pid);
00855                 }
00856 //debug($this->isInWebMount_Cache);
00857                 return $this->isInWebMount_Cache[$pid];
00858         }
00859 
00869         function checkRecordUpdateAccess($table,$id)    {
00870                 global $TCA;
00871                 $res = 0;
00872                 if ($TCA[$table] && intval($id)>0)      {
00873                         if (isset($this->recUpdateAccessCache[$table][$id]))    {       // If information is cached, return it
00874                                 return $this->recUpdateAccessCache[$table][$id];
00875                                 // Check if record exists and 1) if 'pages' the page may be edited, 2) if page-content the page allows for editing
00876                         } elseif ($this->doesRecordExist($table,$id,'edit'))    {
00877                                 $res = 1;
00878                         }
00879                         $this->recUpdateAccessCache[$table][$id]=$res;  // Cache the result
00880                 }
00881                 return $res;
00882         }
00883 
00894         function checkRecordInsertAccess($insertTable,$pid,$action=1)   {
00895                 global $TCA;
00896                 $res = 0;
00897                 $pid = intval($pid);
00898                 if ($pid>=0)    {
00899                         if (isset($this->recInsertAccessCache[$insertTable][$pid]))     {       // If information is cached, return it
00900                                 return $this->recInsertAccessCache[$insertTable][$pid];
00901                         } else {
00902                                         // If either admin and root-level or if page record exists and 1) if 'pages' you may create new ones 2) if page-content, new content items may be inserted on the $pid page
00903                                 if ( (!$pid && $this->admin) || $this->doesRecordExist('pages',$pid,($insertTable=='pages'?$this->pMap['new']:$this->pMap['editcontent'])) )    {               // Check permissions
00904                                         if ($this->isTableAllowedForThisPage($pid, $insertTable))       {
00905                                                 $res = 1;
00906                                                 $this->recInsertAccessCache[$insertTable][$pid]=$res;   // Cache the result
00907                                         } else {
00908                                                 $propArr = $this->getRecordProperties('pages',$pid);
00909                                                 $this->log($insertTable,$pid,$action,0,1,"Attempt to insert record on page '%s' (%s) where this table, %s, is not allowed",11,array($propArr['header'],$pid,$insertTable),$propArr['event_pid']);
00910                                         }
00911                                 } else {
00912                                         $propArr = $this->getRecordProperties('pages',$pid);
00913                                         $this->log($insertTable,$pid,$action,0,1,"Attempt to insert a record on page '%s' (%s) from table '%s' without permissions. Or non-existing page.",12,array($propArr['header'],$pid,$insertTable),$propArr['event_pid']);
00914                                 }
00915                         }
00916                 }
00917                 return $res;
00918         }
00919 
00930         function isTableAllowedForThisPage($page_uid, $checkTable)      {
00931                 global $TCA, $PAGES_TYPES;
00932                 $page_uid = intval($page_uid);
00933 
00934                         // Check if rootLevel flag is set and we're trying to insert on rootLevel - and reversed - and that the table is not "pages" which are allowed anywhere.
00935                 if (($TCA[$checkTable]['ctrl']['rootLevel'] xor !$page_uid) && $TCA[$checkTable]['ctrl']['rootLevel']!=-1 && $checkTable!='pages')      {
00936                         return false;
00937                 }
00938 
00939                         // Check root-level
00940                 if (!$page_uid) {
00941                         if ($this->admin)       {
00942                                 return true;
00943                         }
00944                 } else {
00945                                 // Check non-root-level
00946                         $doktype = $this->pageInfo($page_uid,'doktype');
00947                         $allowedTableList = isset($PAGES_TYPES[$doktype]['allowedTables']) ? $PAGES_TYPES[$doktype]['allowedTables'] : $PAGES_TYPES['default']['allowedTables'];
00948                         $allowedArray = t3lib_div::trimExplode(',',$allowedTableList,1);
00949                         if (strstr($allowedTableList,'*') || in_array($checkTable,$allowedArray))       {               // If all tables or the table is listed as a allowed type, return true
00950                                 return true;
00951                         }
00952                 }
00953         }
00954 
00965         function doesRecordExist($table,$id,$perms)     {
00966                 global $TCA;
00967 
00968                 $res = 0;
00969                 $id = intval($id);
00970 
00971                         // Processing the incoming $perms (from possible string to integer that can be AND'ed)
00972                 if (!t3lib_div::testInt($perms))        {
00973                         if ($table!='pages')    {
00974                                 switch($perms)  {
00975                                         case 'edit':
00976                                         case 'delete':
00977                                         case 'new':
00978                                                 $perms = 'editcontent';         // This holds it all in case the record is not page!!
00979                                         break;
00980                                 }
00981                         }
00982                         $perms = intval($this->pMap[$perms]);
00983                 } else {
00984                         $perms = intval($perms);
00985                 }
00986 
00987                 if (!$perms)    {debug('Internal ERROR: no permissions to check for non-admin user.');}
00988 
00989                         // For all tables: Check if record exists:
00990                         // Notice: If $perms are 0 (zero) no perms-clause is added!
00991                 if (is_array($TCA[$table]) && $id>0 && ($this->isRecordInWebMount($table,$id) || $this->admin)) {
00992                         if ($table != 'pages')  {
00993 
00994                                         // Find record without checking page:
00995                                 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,pid', $table, 'uid='.intval($id).$this->deleteClause($table));
00996                                 $output = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres);
00997                                 t3lib_BEfunc::fixVersioningPid($table,$output);
00998 
00999                                         // If record found, check page as well:
01000                                 if (is_array($output))  {
01001 
01002                                                 // Looking up the page for record:
01003                                         $mres = $this->doesRecordExist_pageLookUp($output['pid'], $perms);
01004                                         $pageRec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres);
01005 
01006                                                 // Return true if either a page was found OR if the PID is zero AND the user is ADMIN (in which case the record is at root-level):
01007                                         if (is_array($pageRec) || (!$output['pid'] && $this->admin))    {
01008                                                 return TRUE;
01009                                         }
01010                                 }
01011                                 return FALSE;
01012                         } else {
01013                                 $mres = $this->doesRecordExist_pageLookUp($id, $perms);
01014                                 return $GLOBALS['TYPO3_DB']->sql_num_rows($mres);
01015                         }
01016                 }
01017         }
01018 
01028         function doesRecordExist_pageLookUp($id, $perms)        {
01029                 global $TCA;
01030 
01031                 return $GLOBALS['TYPO3_DB']->exec_SELECTquery(
01032                         'uid',
01033                         'pages',
01034                         'uid='.intval($id).
01035                                 $this->deleteClause('pages').
01036                                 ($perms && !$this->admin ? ' AND '.$this->BE_USER->getPagePermsClause($perms) : '').
01037                                 (!$this->admin && $TCA['pages']['ctrl']['editlock'] && ($perms & (2+4+16)) ? ' AND '.$TCA['pages']['ctrl']['editlock'].'=0':'') // admin users don't need check
01038                 );
01039         }
01040 
01054         function doesBranchExist($inList,$pid,$perms, $recurse) {
01055                 global $TCA;
01056                 $pid = intval($pid);
01057                 $perms = intval($perms);
01058                 if ($pid>=0)    {
01059                         $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
01060                                                 'uid, perms_userid, perms_groupid, perms_user, perms_group, perms_everybody',
01061                                                 'pages',
01062                                                 'pid='.intval($pid).$this->deleteClause('pages'),
01063                                                 '',
01064                                                 'sorting'
01065                                         );
01066                         while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres))     {
01067                                 if ($this->admin || $this->BE_USER->doesUserHaveAccess($row,$perms))    {       // IF admin, then it's OK
01068                                         $inList.=$row['uid'].',';
01069                                         if ($recurse)   {       // Follow the subpages recursively...
01070                                                 $inList = $this->doesBranchExist($inList, $row['uid'], $perms, $recurse);
01071                                                 if ($inList == -1)      {return -1;}            // No permissions somewhere in the branch
01072                                         }
01073                                 } else {
01074                                         return -1;              // No permissions
01075                                 }
01076                         }
01077                 }
01078                 return $inList;
01079         }
01080 
01089         function pageInfo($id,$field)   {
01090                 if (!isset($this->pageCache[$id]))      {
01091                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'uid='.intval($id));
01092                         if ($GLOBALS['TYPO3_DB']->sql_num_rows($res))   {
01093                                 $this->pageCache[$id] = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
01094                         }
01095                         $GLOBALS['TYPO3_DB']->sql_free_result($res);
01096                 }
01097                 return $this->pageCache[$id][$field];
01098         }
01099 
01109         function recordInfo($table,$id,$fieldList)      {
01110                 global $TCA;
01111                 if (is_array($TCA[$table]))     {
01112                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fieldList, $table, 'uid='.intval($id));
01113                         if ($GLOBALS['TYPO3_DB']->sql_num_rows($res))   {
01114                                 return $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
01115                         }
01116                 }
01117         }
01118 
01126         function getRecordProperties($table,$id)        {
01127                 $row = ($table=='pages' && !$id) ? array('title'=>'[root-level]', 'uid' => 0, 'pid' => 0) :$this->recordInfo($table,$id,'*');
01128                 t3lib_BEfunc::fixVersioningPid($table,$row);
01129                 return $this->getRecordPropertiesFromRow($table,$row);
01130         }
01131 
01139         function getRecordPropertiesFromRow($table,$row)        {
01140                 global $TCA;
01141                 if ($TCA[$table])       {
01142                         $out = array(
01143                                 'header' => $row[$TCA[$table]['ctrl']['label']],
01144                                 'pid' => $row['pid'],
01145                                 'event_pid' => ($table=='pages'?$row['uid']:$row['pid'])
01146                         );
01147                         return $out;
01148                 }
01149         }
01150 
01158         function setTSconfigPermissions($fieldArray,$TSConfig_p)        {
01159                 if (strcmp($TSConfig_p['userid'],''))   $fieldArray['perms_userid']=intval($TSConfig_p['userid']);
01160                 if (strcmp($TSConfig_p['groupid'],''))  $fieldArray['perms_groupid']=intval($TSConfig_p['groupid']);
01161                 if (strcmp($TSConfig_p['user'],''))                     $fieldArray['perms_user']=t3lib_div::testInt($TSConfig_p['user']) ? $TSConfig_p['user'] : $this->assemblePermissions($TSConfig_p['user']);
01162                 if (strcmp($TSConfig_p['group'],''))            $fieldArray['perms_group']=t3lib_div::testInt($TSConfig_p['group']) ? $TSConfig_p['group'] : $this->assemblePermissions($TSConfig_p['group']);
01163                 if (strcmp($TSConfig_p['everybody'],''))        $fieldArray['perms_everybody']=t3lib_div::testInt($TSConfig_p['everybody']) ? $TSConfig_p['everybody'] : $this->assemblePermissions($TSConfig_p['everybody']);
01164 
01165                 return $fieldArray;
01166         }
01167 
01174         function newFieldArray($table)  {
01175                 global $TCA;
01176                 t3lib_div::loadTCA($table);
01177                 $fieldArray=Array();
01178                 if (is_array($TCA[$table]['columns']))  {
01179                         reset ($TCA[$table]['columns']);
01180                         while (list($field,$content)=each($TCA[$table]['columns']))     {
01181                                 if (isset($this->defaultValues[$table][$field]))        {
01182                                         $fieldArray[$field] = $this->defaultValues[$table][$field];
01183                                 } elseif (isset($content['config']['default'])) {
01184                                         $fieldArray[$field] = $content['config']['default'];
01185                                 }
01186                         }
01187                 }
01188                 if ($table=='pages')    {               // Set default permissions for a page.
01189                         $fieldArray['perms_userid'] = $this->userid;
01190                         $fieldArray['perms_groupid'] = intval($this->BE_USER->firstMainGroup);
01191                         $fieldArray['perms_user'] = $this->assemblePermissions($this->defaultPermissions['user']);
01192                         $fieldArray['perms_group'] = $this->assemblePermissions($this->defaultPermissions['group']);
01193                         $fieldArray['perms_everybody'] = $this->assemblePermissions($this->defaultPermissions['everybody']);
01194                 }
01195                 return $fieldArray;
01196         }
01197 
01205         function overrideFieldArray($table,$data)       {
01206                 if (is_array($this->overrideValues[$table]))    {
01207                         $data = array_merge($data,$this->overrideValues[$table]);                       // Candidate for t3lib_div::array_merge() if integer-keys will some day make trouble...
01208                 }
01209                 return $data;
01210         }
01211 
01218         function assemblePermissions($string)   {
01219                 $keyArr = t3lib_div::trimExplode(',',$string,1);
01220                 $value=0;
01221                 while(list(,$key)=each($keyArr))        {
01222                         if ($key && isset($this->pMap[$key]))   {
01223                                 $value |= $this->pMap[$key];
01224                         }
01225                 }
01226                 return $value;
01227         }
01228 
01229 
01230 
01231 
01232 
01233 
01234 
01235 
01236 
01237 
01238 
01239 
01240 
01241 
01242 
01243 
01244 
01245 
01246 
01247 
01248         /*********************************************
01249          *
01250          * Evaluation of input values
01251          *
01252          ********************************************/
01253 
01268         function checkValue($table,$field,$value,$id,$status,$realPid,$tscPID)  {
01269                 global $TCA, $PAGES_TYPES;
01270                 t3lib_div::loadTCA($table);
01271 
01272                 $res = Array(); // result array
01273                 $recFID = $table.':'.$id.':'.$field;
01274 
01275                         // Processing special case of field pages.doktype
01276                 if ($table=='pages' && $field=='doktype')       {
01277                                 // If the user may not use this specific doktype, we issue a warning
01278                         if (! ($this->admin || t3lib_div::inList($this->BE_USER->groupData['pagetypes_select'],$value)))        {
01279                                 $propArr = $this->getRecordProperties($table,$id);
01280                                 $this->log($table,$id,5,0,1,"You cannot change the 'doktype' of page '%s' to the desired value.",1,array($propArr['header']),$propArr['event_pid']);
01281                                 return $res;
01282                         };
01283                         if ($status=='update')  {
01284                                         // This checks 1) if we should check for disallowed tables and 2) if there are records from disallowed tables on the current page
01285                                 $onlyAllowedTables = isset($PAGES_TYPES[$value]['onlyAllowedTables']) ? $PAGES_TYPES[$value]['onlyAllowedTables'] : $PAGES_TYPES['default']['onlyAllowedTables'];
01286                                 if ($onlyAllowedTables) {
01287                                         $theWrongTables = $this->doesPageHaveUnallowedTables($id,$value);
01288                                         if ($theWrongTables)    {
01289                                                 $propArr = $this->getRecordProperties($table,$id);
01290                                                 $this->log($table,$id,5,0,1,"'doktype' of page '%s' could not be changed because the page contains records from disallowed tables; %s",2,array($propArr['header'],$theWrongTables),$propArr['event_pid']);
01291                                                 return $res;
01292                                         }
01293                                 }
01294                         }
01295                 }
01296 
01297                         // Get current value:
01298                 $curValueRec = $this->recordInfo($table,$id,$field);
01299                 $curValue = $curValueRec[$field];
01300 
01301                         // Getting config for the field
01302                 $tcaFieldConf = $TCA[$table]['columns'][$field]['config'];
01303 
01304                         // Preform processing:
01305                 $res = $this->checkValue_SW($res,$value,$tcaFieldConf,$table,$id,$curValue,$status,$realPid,$recFID,$field,$this->uploadedFileArray[$table][$id][$field],$tscPID);
01306 
01307                 return $res;
01308         }
01309 
01328         function checkValue_SW($res,$value,$tcaFieldConf,$table,$id,$curValue,$status,$realPid,$recFID,$field,$uploadedFiles,$tscPID)   {
01329 
01330                 $PP = array($table,$id,$curValue,$status,$realPid,$recFID,$tscPID);
01331 
01332                 switch ($tcaFieldConf['type']) {
01333                         case 'text':
01334                         case 'passthrough':
01335                         case 'user':
01336                                 $res['value'] = $value;
01337                         break;
01338                         case 'input':
01339                                 $res = $this->checkValue_input($res,$value,$tcaFieldConf,$PP,$field);
01340                         break;
01341                         case 'check':
01342                                 $res = $this->checkValue_check($res,$value,$tcaFieldConf,$PP);
01343                         break;
01344                         case 'radio':
01345                                 $res = $this->checkValue_radio($res,$value,$tcaFieldConf,$PP);
01346                         break;
01347                         case 'group':
01348                         case 'select':
01349                                 $res = $this->checkValue_group_select($res,$value,$tcaFieldConf,$PP,$uploadedFiles,$field);
01350                         break;
01351                         case 'flex':
01352                                 if ($field)     {       // FlexForms are only allowed for real fields.
01353                                         $res = $this->checkValue_flex($res,$value,$tcaFieldConf,$PP,$uploadedFiles,$field);
01354                                 }
01355                         break;
01356                         default:
01357                                 #debug(array($tcaFieldConf,$res,$value),'NON existing field type:');
01358                         break;
01359                 }
01360 
01361                 return $res;
01362         }
01363 
01374         function checkValue_input($res,$value,$tcaFieldConf,$PP,$field='')      {
01375                 list($table,$id,$curValue,$status,$realPid,$recFID) = $PP;
01376 
01377                         // Secures the string-length to be less than max. Will probably make problems with multi-byte strings!
01378                 if (intval($tcaFieldConf['max'])>0)     {$value = substr($value,0,intval($tcaFieldConf['max']));}
01379 
01380                         // Checking range of value:
01381                 if ($tcaFieldConf['range'] && $value!=$tcaFieldConf['checkbox'])        {       // If value is not set to the allowed checkbox-value then it is checked against the ranges
01382                         if (isset($tcaFieldConf['range']['upper'])&&$value>$tcaFieldConf['range']['upper'])     {$value=$tcaFieldConf['range']['upper'];}
01383                         if (isset($tcaFieldConf['range']['lower'])&&$value<$tcaFieldConf['range']['lower'])     {$value=$tcaFieldConf['range']['lower'];}
01384                 }
01385 
01386                         // Process evaluation settings:
01387                 $evalCodesArray = t3lib_div::trimExplode(',',$tcaFieldConf['eval'],1);
01388                 $res = $this->checkValue_input_Eval($value,$evalCodesArray,$tcaFieldConf['is_in']);
01389 
01390                         // Process UNIQUE settings:
01391                 if ($field && $realPid>=0)      {       // Field is NOT set for flexForms - which also means that uniqueInPid and unique is NOT available for flexForm fields! Also getUnique should not be done for versioning and if PID is -1 ($realPid<0) then versioning is happening...
01392                         if ($res['value'] && in_array('uniqueInPid',$evalCodesArray))   {
01393                                 $res['value'] = $this->getUnique($table,$field,$res['value'],$id,$realPid);
01394                         }
01395                         if ($res['value'] && in_array('unique',$evalCodesArray))        {
01396                                 $res['value'] = $this->getUnique($table,$field,$res['value'],$id);
01397                         }
01398                 }
01399 
01400                 return $res;
01401         }
01402 
01412         function checkValue_check($res,$value,$tcaFieldConf,$PP)        {
01413                 list($table,$id,$curValue,$status,$realPid,$recFID) = $PP;
01414 
01415                 $itemC = count($tcaFieldConf['items']);
01416                 if (!$itemC)    {$itemC=1;}
01417                 $maxV = pow(2,$itemC);
01418 
01419                 if ($value<0)   {$value=0;}
01420                 if ($value>$maxV)       {$value=$maxV;}
01421                 $res['value'] = $value;
01422 
01423                 return $res;
01424         }
01425 
01435         function checkValue_radio($res,$value,$tcaFieldConf,$PP)        {
01436                 list($table,$id,$curValue,$status,$realPid,$recFID) = $PP;
01437 
01438                 if (is_array($tcaFieldConf['items']))   {
01439                         foreach($tcaFieldConf['items'] as $set) {
01440                                 if (!strcmp($set[1],$value))    {
01441                                         $res['value'] = $value;
01442                                         break;
01443                                 }
01444                         }
01445                 }
01446 
01447                 return $res;
01448         }
01449 
01461         function checkValue_group_select($res,$value,$tcaFieldConf,$PP,$uploadedFiles,$field)   {
01462                 list($table,$id,$curValue,$status,$realPid,$recFID) = $PP;
01463 
01464                         // Detecting if value send is an array and if so, implode it around a comma:
01465                 if (is_array($value))   {
01466                         $value = implode(',',$value);
01467                 }
01468 
01469                         // This converts all occurencies of '&#123;' to the byte 123 in the string - this is needed in very rare cases where filenames with special characters (like ćřĺ, umlaud etc) gets sent to the server as HTML entities instead of bytes. The error is done only by MSIE, not Mozilla and Opera.
01470                         // Anyways, this should NOT disturb anything else:
01471                 $value = $this->convNumEntityToByteValue($value);
01472 
01473                         // When values are send as group or select they come as comma-separated values which are exploded by this function:
01474                 $valueArray = $this->checkValue_group_select_explodeSelectGroupValue($value);
01475 
01476                         // If not multiple is set, then remove duplicates:
01477                 if (!$tcaFieldConf['multiple']) {
01478                         $valueArray = array_unique($valueArray);
01479                 }
01480 
01481                 // This could be a good spot for parsing the array through a validation-function which checks if the values are allright (except that database references are not in their final form - but that is the point, isn't it?)
01482                 // NOTE!!! Must check max-items of files before the later check because that check would just leave out filenames if there are too many!!
01483 
01484                         // Checking for select / authMode, removing elements from $valueArray if any of them is not allowed!
01485                 if ($tcaFieldConf['type']=='select' && $tcaFieldConf['authMode'])       {
01486                         $preCount = count($valueArray);
01487                         foreach($valueArray as $kk => $vv)      {
01488                                 if (!$this->BE_USER->checkAuthMode($table,$field,$vv,$tcaFieldConf['authMode']))        {
01489                                         unset($valueArray[$kk]);
01490                                 }
01491                         }
01492 
01493                                 // During the check it turns out that the value / all values were removed - we respond by simply returning an empty array so nothing is written to DB for this field.
01494                         if ($preCount && !count($valueArray))   {
01495                                 return array();
01496                         }
01497                 }
01498 
01499                         // For group types:
01500                 if ($tcaFieldConf['type']=='group')     {
01501                         switch($tcaFieldConf['internal_type'])  {
01502                                 case 'file':
01503                                         $valueArray = $this->checkValue_group_select_file(
01504                                                 $valueArray,
01505                                                 $tcaFieldConf,
01506                                                 $curValue,
01507                                                 $uploadedFiles,
01508                                                 $status,
01509                                                 $table,
01510                                                 $id,
01511                                                 $recFID
01512                                         );
01513                                 break;
01514                                 case 'db':
01515                                         $valueArray = $this->checkValue_group_select_processDBdata($valueArray,$tcaFieldConf,$id,$status,'group');
01516                                 break;
01517                         }
01518                 }
01519                         // For select types which has a foreign table attached:
01520                 if ($tcaFieldConf['type']=='select' && $tcaFieldConf['foreign_table'])  {
01521                         $valueArray = $this->checkValue_group_select_processDBdata($valueArray,$tcaFieldConf,$id,$status,'select');
01522                 }
01523 
01524 // BTW, checking for min and max items here does NOT make any sense when MM is used because the above function calls will just return an array with a single item (the count) if MM is used... Why didn't I perform the check before? Probably because we could not evaluate the validity of record uids etc... Hmm...
01525 
01526                         // Checking the number of items, that it is correct.
01527                         // If files, there MUST NOT be too many files in the list at this point, so check that prior to this code.
01528                 $valueArrayC = count($valueArray);
01529                 $minI = isset($tcaFieldConf['minitems']) ? intval($tcaFieldConf['minitems']):0;
01530 
01531                         // NOTE to the comment: It's not really possible to check for too few items, because you must then determine first, if the field is actual used regarding the CType.
01532                 $maxI = isset($tcaFieldConf['maxitems']) ? intval($tcaFieldConf['maxitems']):1;
01533                 if ($valueArrayC > $maxI)       {$valueArrayC=$maxI;}   // Checking for not too many elements
01534 
01535                         // Dumping array to list
01536                 $newVal=array();
01537                 foreach($valueArray as $nextVal)        {
01538                         if ($valueArrayC==0)    {break;}
01539                         $valueArrayC--;
01540                         $newVal[]=$nextVal;
01541                 }
01542                 $res['value'] = implode(',',$newVal);
01543 
01544                 return $res;
01545         }
01546 
01561         function checkValue_group_select_file($valueArray,$tcaFieldConf,$curValue,$uploadedFileArray,$status,$table,$id,$recFID)        {
01562 
01563                         // If any files are uploaded:
01564                 if (is_array($uploadedFileArray) &&
01565                         $uploadedFileArray['name'] &&
01566                         strcmp($uploadedFileArray['tmp_name'],'none'))  {
01567                                 $valueArray[]=$uploadedFileArray['tmp_name'];
01568                                 $this->alternativeFileName[$uploadedFileArray['tmp_name']] = $uploadedFileArray['name'];
01569                 }
01570 
01571                         // Creating fileFunc object.
01572                 if (!$this->fileFunc)   {
01573                         $this->fileFunc = t3lib_div::makeInstance('t3lib_basicFileFunctions');
01574                         $this->include_filefunctions=1;
01575                 }
01576                         // Setting permitted extensions.
01577                 $all_files = Array();
01578                 $all_files['webspace']['allow'] = $tcaFieldConf['allowed'];
01579                 $all_files['webspace']['deny'] = $tcaFieldConf['disallowed'] ? $tcaFieldConf['disallowed'] : '*';
01580                 $all_files['ftpspace'] = $all_files['webspace'];
01581                 $this->fileFunc->init('', $all_files);
01582 
01583                         // If there is an upload folder defined:
01584                 if ($tcaFieldConf['uploadfolder'])      {
01585                                 // For logging..
01586                         $propArr = $this->getRecordProperties($table,$id);
01587 
01588                                 // Get destrination path:
01589                         $dest = $this->destPathFromUploadFolder($tcaFieldConf['uploadfolder']);
01590 
01591                                 // If we are updating:
01592                         if ($status=='update')  {
01593 
01594                                         // Finding the CURRENT files listed, either from MM or from the current record.
01595                                 $theFileValues=array();
01596                                 if ($tcaFieldConf['MM'])        {       // If MM relations for the files also!
01597                                         $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
01598                                         $dbAnalysis->start('','files',$tcaFieldConf['MM'],$id);
01599                                         reset($dbAnalysis->itemArray);
01600                                         while (list($somekey,$someval)=each($dbAnalysis->itemArray))    {
01601                                                 if ($someval['id'])     {
01602                                                         $theFileValues[]=$someval['id'];
01603                                                 }
01604                                         }
01605                                 } else {
01606                                         $theFileValues=t3lib_div::trimExplode(',',$curValue,1);
01607                                 }
01608 
01609                                         // DELETE files: If existing files were found, traverse those and register files for deletion which has been removed:
01610                                 if (count($theFileValues))      {
01611                                                 // Traverse the input values and for all input values which match an EXISTING value, remove the existing from $theFileValues array (this will result in an array of all the existing files which should be deleted!)
01612                                         foreach($valueArray as $key => $theFile)        {
01613                                                 if ($theFile && !strstr(t3lib_div::fixWindowsFilePath($theFile),'/'))   {
01614                                                         $theFileValues = t3lib_div::removeArrayEntryByValue($theFileValues,$theFile);
01615                                                 }
01616                                         }
01617 
01618                                                 // This array contains the filenames in the uploadfolder that should be deleted:
01619                                         foreach($theFileValues as $key => $theFile)     {
01620                                                 $theFile = trim($theFile);
01621                                                 if (@is_file($dest.'/'.$theFile))       {
01622                                                         $this->removeFilesStore[]=$dest.'/'.$theFile;
01623                                                 } elseif ($theFile) {
01624                                                         $this->log($table,$id,5,0,1,"Could not delete file '%s' (does not exist). (%s)",10,array($dest.'/'.$theFile, $recFID),$propArr['event_pid']);
01625                                                 }
01626                                         }
01627                                 }
01628                         }
01629 
01630                                 // Traverse the submitted values:
01631                         foreach($valueArray as $key => $theFile)        {
01632                                         // NEW FILES? If the value contains '/' it indicates, that the file is new and should be added to the uploadsdir (whether its absolute or relative does not matter here)
01633                                 if (strstr(t3lib_div::fixWindowsFilePath($theFile),'/'))        {
01634                                                 // Init:
01635                                         $maxSize = intval($tcaFieldConf['max_size']);
01636                                         $cmd='';
01637                                         $theDestFile='';                // Must be cleared. Else a faulty fileref may be inserted if the below code returns an error!! (Change: 22/12/2000)
01638 
01639                                                 // Check various things before copying file:
01640                                         if (@is_dir($dest) && (@is_file($theFile) || @is_uploaded_file($theFile)))      {               // File and destination must exist
01641 
01642                                                         // Finding size. For safe_mode we have to rely on the size in the upload array if the file is uploaded.
01643                                                 if (is_uploaded_file($theFile) && $theFile==$uploadedFileArray['tmp_name'])     {
01644                                                         $fileSize = $uploadedFileArray['size'];
01645                                                 } else {
01646                                                         $fileSize = filesize($theFile);
01647                                                 }
01648 
01649                                                 if (!$maxSize || $fileSize<=($maxSize*1024))    {       // Check file size:
01650                                                                 // Prepare filename:
01651                                                         $theEndFileName = isset($this->alternativeFileName[$theFile]) ? $this->alternativeFileName[$theFile] : $theFile;
01652                                                         $fI = t3lib_div::split_fileref($theEndFileName);
01653 
01654                                                                 // Check for allowed extension:
01655                                                         if ($this->fileFunc->checkIfAllowed($fI['fileext'], $dest, $theEndFileName)) {
01656                                                                 $theDestFile = $this->fileFunc->getUniqueName($this->fileFunc->cleanFileName($fI['file']), $dest);
01657 
01658                                                                         // If we have a unique destination filename, then write the file:
01659                                                                 if ($theDestFile)       {
01660                                                                         t3lib_div::upload_copy_move($theFile,$theDestFile);
01661                                                                         $this->copiedFileMap[$theFile] = $theDestFile;
01662                                                                         clearstatcache();
01663                                                                         if (!@is_file($theDestFile))    $this->log($table,$id,5,0,1,"Copying file '%s' failed!: The destination path (%s) may be write protected. Please make it write enabled!. (%s)",16,array($theFile, dirname($theDestFile), $recFID),$propArr['event_pid']);
01664                                                                 } else $this->log($table,$id,5,0,1,"Copying file '%s' failed!: No destination file (%s) possible!. (%s)",11,array($theFile, $theDestFile, $recFID),$propArr['event_pid']);
01665                                                         } else $this->log($table,$id,5,0,1,"Fileextension '%s' not allowed. (%s)",12,array($fI['fileext'], $recFID),$propArr['event_pid']);
01666                                                 } else $this->log($table,$id,5,0,1,"Filesize (%s) of file '%s' exceeds limit (%s). (%s)",13,array(t3lib_div::formatSize($fileSize),$theFile,t3lib_div::formatSize($maxSize*1024),$recFID),$propArr['event_pid']);
01667                                         } else $this->log($table,$id,5,0,1,'The destination (%s) or the source file (%s) does not exist. (%s)',14,array($dest, $theFile, $recFID),$propArr['event_pid']);
01668 
01669                                                 // If the destination file was created, we will set the new filename in the value array, otherwise unset the entry in the value array!
01670                                         if (@is_file($theDestFile))     {
01671                                                 $info = t3lib_div::split_fileref($theDestFile);
01672                                                 $valueArray[$key]=$info['file']; // The value is set to the new filename
01673                                         } else {
01674                                                 unset($valueArray[$key]);       // The value is set to the new filename
01675                                         }
01676                                 }
01677                         }
01678 
01679                                 // If MM relations for the files, we will set the relations as MM records and change the valuearray to contain a single entry with a count of the number of files!
01680                         if ($tcaFieldConf['MM'])        {
01681                                 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
01682                                 $dbAnalysis->tableArray['files']=array();       // dummy
01683 
01684                                 reset($valueArray);
01685                                 while (list($key,$theFile)=each($valueArray))   {
01686                                                 // explode files
01687                                                 $dbAnalysis->itemArray[]['id']=$theFile;
01688                                 }
01689                                 if ($status=='update')  {
01690                                         $dbAnalysis->writeMM($tcaFieldConf['MM'],$id,0);
01691                                 } else {
01692                                         $this->dbAnalysisStore[] = array($dbAnalysis, $tcaFieldConf['MM'], $id, 0);     // This will be traversed later to execute the actions
01693                                 }
01694                                 $cc=count($dbAnalysis->itemArray);
01695                                 $valueArray = array($cc);
01696                         }
01697                 }
01698 
01699                 return $valueArray;
01700         }
01701 
01714         function checkValue_flex($res,$value,$tcaFieldConf,$PP,$uploadedFiles,$field)   {
01715                 list($table,$id,$curValue,$status,$realPid,$recFID) = $PP;
01716 
01717                 if (is_array($value))   {
01718 
01719                                 // Get current value array:
01720                         $dataStructArray = t3lib_BEfunc::getFlexFormDS($tcaFieldConf,$this->checkValue_currentRecord,$table);
01721 #debug($this->checkValue_currentRecord);
01722                         $currentValueArray = t3lib_div::xml2array($curValue);
01723                         if (!is_array($currentValueArray))      $currentValueArray = array();
01724                         if (is_array($currentValueArray['meta']['currentLangId']))              unset($currentValueArray['meta']['currentLangId']);     // Remove all old meta for languages...
01725 
01726                                 // Evaluation of input values:
01727                         $value['data'] = $this->checkValue_flex_procInData($value['data'],$currentValueArray['data'],$uploadedFiles['data'],$dataStructArray,$PP);
01728 
01729                                 // Create XML and convert charsets from input value:
01730                         $xmlValue = $this->checkValue_flexArray2Xml($value);
01731 
01732                                 // If we wanted to set UTF fixed:
01733                         // $storeInCharset='utf-8';
01734                         // $currentCharset=$GLOBALS['LANG']->charSet;
01735                         // $xmlValue = $GLOBALS['LANG']->csConvObj->conv($xmlValue,$currentCharset,$storeInCharset,1);
01736                         $storeInCharset=$GLOBALS['LANG']->charSet;
01737 
01738                                 // Merge them together IF they are both arrays:
01739                                 // Here we convert the currently submitted values BACK to an array, then merge the two and then BACK to XML again. This is needed to ensure the charsets are the same (provided that the current value was already stored IN the charset that the new value is converted to).
01740                         if (is_array($currentValueArray))       {
01741                                 $arrValue = t3lib_div::xml2array($xmlValue);
01742                                 $arrValue = t3lib_div::array_merge_recursive_overrule($currentValueArray,$arrValue);
01743                                 $xmlValue = $this->checkValue_flexArray2Xml($arrValue);
01744                         }
01745 
01746                                 // Temporary fix to delete flex form elements:
01747                         $deleteCMDs = t3lib_div::_GP('_DELETE_FLEX_FORMdata');
01748                         if (is_array($deleteCMDs[$table][$id][$field]['data'])) {
01749                                 $arrValue = t3lib_div::xml2array($xmlValue);
01750                                 $this->_DELETE_FLEX_FORMdata($arrValue['data'],$deleteCMDs[$table][$id][$field]['data']);
01751                                 $xmlValue = $this->checkValue_flexArray2Xml($arrValue);
01752                         }
01753 
01754                                 // Temporary fix to move flex form elements up:
01755                         $moveCMDs = t3lib_div::_GP('_MOVEUP_FLEX_FORMdata');
01756                         if (is_array($moveCMDs[$table][$id][$field]['data']))   {
01757                                 $arrValue = t3lib_div::xml2array($xmlValue);
01758                                 $this->_MOVE_FLEX_FORMdata($arrValue['data'],$moveCMDs[$table][$id][$field]['data'], 'up');
01759                                 $xmlValue = $this->checkValue_flexArray2Xml($arrValue);
01760                         }
01761 
01762                                 // Temporary fix to move flex form elements down:
01763                         $moveCMDs = t3lib_div::_GP('_MOVEDOWN_FLEX_FORMdata');
01764                         if (is_array($moveCMDs[$table][$id][$field]['data']))   {
01765                                 $arrValue = t3lib_div::xml2array($xmlValue);
01766                                 $this->_MOVE_FLEX_FORMdata($arrValue['data'],$moveCMDs[$table][$id][$field]['data'], 'down');
01767                                 $xmlValue = $this->checkValue_flexArray2Xml($arrValue);
01768                         }
01769 
01770                                 // Create the value XML:
01771                         $res['value']='';
01772                         $res['value'].='<?xml version="1.0" encoding="'.$storeInCharset.'" standalone="yes" ?>'.chr(10);
01773                         $res['value'].=$xmlValue;
01774                 } else {        // Passthrough...:
01775                         $res['value']=$value;
01776                 }
01777 
01778                 return $res;
01779         }
01780 
01787         function checkValue_flexArray2Xml($array)       {
01788                 $output = t3lib_div::array2xml($array,'',0,'T3FlexForms',4,array('parentTagMap' => array(
01789 /*                                                              'data' => 'sheets',
01790                                                                 'sheets' => 'language',
01791                                                                 'language' => 'fieldname',
01792                                                                 'el' => 'fieldname'             */
01793                                                         )));
01794                 return $output;
01795         }
01796 
01804         function _DELETE_FLEX_FORMdata(&$valueArrayToRemoveFrom,$deleteCMDS)    {
01805                 if (is_array($valueArrayToRemoveFrom) && is_array($deleteCMDS)) {
01806                         foreach($deleteCMDS as $key => $value)  {
01807                                 if (is_array($deleteCMDS[$key]))        {
01808                                         $this->_DELETE_FLEX_FORMdata($valueArrayToRemoveFrom[$key],$deleteCMDS[$key]);
01809                                 } else {
01810                                         unset($valueArrayToRemoveFrom[$key]);
01811                                 }
01812                         }
01813                 }
01814         }
01815 
01825         function _MOVE_FLEX_FORMdata(&$valueArrayToMoveIn, $moveCMDS, $direction)       {
01826                 if (is_array($valueArrayToMoveIn) && is_array($moveCMDS))       {
01827 
01828                                 // Only execute the first move command:
01829                         list ($key, $value) = each ($moveCMDS);
01830 
01831                         if (is_array($moveCMDS[$key]))  {
01832                                 $this->_MOVE_FLEX_FORMdata($valueArrayToMoveIn[$key],$moveCMDS[$key], $direction);
01833                         } else {
01834                                 switch ($direction) {
01835                                         case 'up':
01836                                                 if ($key > 1) {
01837                                                         $tmpArr = $valueArrayToMoveIn[$key];
01838                                                         $valueArrayToMoveIn[$key] = $valueArrayToMoveIn[$key-1];
01839                                                         $valueArrayToMoveIn[$key-1] = $tmpArr;
01840                                                 }
01841                                         break;
01842                                         case 'down':
01843                                                 if ($key < count($valueArrayToMoveIn)) {
01844                                                         $tmpArr = $valueArrayToMoveIn[$key];
01845                                                         $valueArrayToMoveIn[$key] = $valueArrayToMoveIn[$key+1];
01846                                                         $valueArrayToMoveIn[$key+1] = $tmpArr;
01847                                                 }
01848                                         break;
01849                                 }
01850                         }
01851                 }
01852         }
01853 
01854 
01855 
01856 
01857 
01858 
01859 
01860 
01861 
01862 
01863 
01864 
01865 
01866 
01867 
01868 
01869 
01870 
01871         /*********************************************
01872          *
01873          * Helper functions for evaluation functions.
01874          *
01875          ********************************************/
01876 
01877 
01888         function getUnique($table,$field,$value,$id,$newPid=0)  {
01889                 global $TCA;
01890 
01891                         // Initialize:
01892                 t3lib_div::loadTCA($table);
01893                 $whereAdd='';
01894                 $newValue='';
01895                 if (intval($newPid))    { $whereAdd.=' AND pid='.intval($newPid); } else { $whereAdd.=' AND pid>=0'; }  // "AND pid>=0" for versioning
01896                 $whereAdd.=$this->deleteClause($table);
01897 
01898                         // If the field is configured in TCA, proceed:
01899                 if (is_array($TCA[$table]) && is_array($TCA[$table]['columns'][$field]))        {
01900 
01901                                 // Look for a record which might already have the value:
01902                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, $field.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($value, $table).' AND uid!='.intval($id).$whereAdd);
01903                         $counter = 0;
01904 
01905                                 // For as long as records with the test-value existing, try again (with incremented numbers appended).
01906                         while ($GLOBALS['TYPO3_DB']->sql_num_rows($res))        {
01907                                 $newValue = $value.$counter;
01908                                 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, $field.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($newValue, $table).' AND uid!='.intval($id).$whereAdd);
01909                                 $counter++;
01910                                 if ($counter>100)       { break; }      // At "100" it will give up and accept a duplicate - should probably be fixed to a small hash string instead...!
01911                         }
01912                                 // If the new value is there:
01913                         $value = strlen($newValue) ? $newValue : $value;
01914                 }
01915                 return $value;
01916         }
01917 
01926         function checkValue_input_Eval($value,$evalArray,$is_in)        {
01927                 $res = Array();
01928                 $newValue = $value;
01929                 $set = true;
01930 
01931                 foreach($evalArray as $func)    {
01932                         switch($func)   {
01933                                 case 'int':
01934                                 case 'year':
01935                                 case 'date':
01936                                 case 'datetime':
01937                                 case 'time':
01938                                 case 'timesec':
01939                                         $value = intval($value);
01940                                 break;
01941                                 case 'double2':
01942                                         $theDec = 0;
01943                                         for ($a=strlen($value); $a>0; $a--)     {
01944                                                 if (substr($value,$a-1,1)=='.' || substr($value,$a-1,1)==',')   {
01945                                                         $theDec = substr($value,$a);
01946                                                         $value = substr($value,0,$a-1);
01947                                                         break;
01948                                                 }
01949                                         }
01950                                         $theDec = ereg_replace('[^0-9]','',$theDec).'00';
01951                                         $value = intval(str_replace(' ','',$value)).'.'.substr($theDec,0,2);
01952                                 break;
01953                                 case 'md5':
01954                                         if (strlen($value)!=32){$set=false;}
01955                                 break;
01956                                 case 'trim':
01957                                         $value = trim($value);
01958                                 break;
01959                                 case 'upper':
01960                                         $value = strtoupper($value);
01961 #                                       $value = strtr($value, 'áéúíâęűôîćřĺäöü', 'ÁÉÚÍÂĘŰÔÎĆŘĹÄÖÜ');   // WILL make trouble with other charsets than ISO-8859-1, so what do we do here? PHP-function which can handle this for other charsets? Currently the browsers JavaScript will fix it.
01962                                 break;
01963                                 case 'lower':
01964                                         $value = strtolower($value);
01965 #                                       $value = strtr($value, 'ÁÉÚÍÂĘŰÔÎĆŘĹÄÖÜ', 'áéúíâęűôîćřĺäöü');   // WILL make trouble with other charsets than ISO-8859-1, so what do we do here? PHP-function which can handle this for other charsets? Currently the browsers JavaScript will fix it.
01966                                 break;
01967                                 case 'required':
01968                                         if (!$value)    {$set=0;}
01969                                 break;
01970                                 case 'is_in':
01971                                         $c=strlen($value);
01972                                         if ($c) {
01973                                                 $newVal = '';
01974                                                 for ($a=0;$a<$c;$a++)   {
01975                                                         $char = substr($value,$a,1);
01976                                                         if (strstr($is_in,$char))       {
01977                                                                 $newVal.=$char;
01978                                                         }
01979                                                 }
01980                                                 $value = $newVal;
01981                                         }
01982                                 break;
01983                                 case 'nospace':
01984                                         $value = str_replace(' ','',$value);
01985                                 break;
01986                                 case 'alpha':
01987                                         $value = ereg_replace('[^a-zA-Z]','',$value);
01988                                 break;
01989                                 case 'num':
01990                                         $value = ereg_replace('[^0-9]','',$value);
01991                                 break;
01992                                 case 'alphanum':
01993                                         $value = ereg_replace('[^a-zA-Z0-9]','',$value);
01994                                 break;
01995                                 case 'alphanum_x':
01996                                         $value = ereg_replace('[^a-zA-Z0-9_-]','',$value);
01997                                 break;
01998                         }
01999                 }
02000                 if ($set)       {$res['value'] = $value;}
02001                 return $res;
02002         }
02003 
02014         function checkValue_group_select_processDBdata($valueArray,$tcaFieldConf,$id,$status,$type)     {
02015                 $tables = $type=='group'?$tcaFieldConf['allowed']:$tcaFieldConf['foreign_table'].','.$tcaFieldConf['neg_foreign_table'];
02016                 $prep = $type=='group'?$tcaFieldConf['prepend_tname']:$tcaFieldConf['neg_foreign_table'];
02017 
02018                 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
02019                 $dbAnalysis->registerNonTableValues=$tcaFieldConf['allowNonIdValues'] ? 1 : 0;
02020                 $dbAnalysis->start(implode(',',$valueArray),$tables);
02021 
02022                 if ($tcaFieldConf['MM'])        {
02023                         if ($status=='update')  {
02024                                 $dbAnalysis->writeMM($tcaFieldConf['MM'],$id,$prep);
02025                         } else {
02026                                 $this->dbAnalysisStore[] = array($dbAnalysis,$tcaFieldConf['MM'],$id,$prep);    // This will be traversed later to execute the actions
02027                         }
02028                         $cc=count($dbAnalysis->itemArray);
02029                         $valueArray = array($cc);
02030                 } else {
02031                         $valueArray = $dbAnalysis->getValueArray($prep);
02032                         if ($type=='select' && $prep)   {
02033                                 $valueArray = $dbAnalysis->convertPosNeg($valueArray,$tcaFieldConf['foreign_table'],$tcaFieldConf['neg_foreign_table']);
02034                         }
02035                 }
02036 
02037                         // Here we should se if 1) the records exist anymore, 2) which are new and check if the BE_USER has read-access to the new ones.
02038                 return $valueArray;
02039         }
02040 
02047         function checkValue_group_select_explodeSelectGroupValue($value)        {
02048                 $valueArray = t3lib_div::trimExplode(',',$value,1);
02049                 reset($valueArray);
02050                 while(list($key,$newVal)=each($valueArray))     {
02051                         $temp=explode('|',$newVal,2);
02052                         $valueArray[$key] = str_replace(',','',str_replace('|','',rawurldecode($temp[0])));
02053                 }
02054                 return $valueArray;
02055         }
02056 
02070         function checkValue_flex_procInData($dataPart,$dataPart_current,$uploadedFiles,$dataStructArray,$pParams,$callBackFunc='')      {
02071 #debug(array($dataPart,$dataPart_current,$dataStructArray));
02072                 if (is_array($dataPart))        {
02073                         foreach($dataPart as $sKey => $sheetDef)        {
02074                                 list ($dataStruct,$actualSheet) = t3lib_div::resolveSheetDefInDS($dataStructArray,$sKey);
02075 #debug(array($dataStruct,$actualSheet,$sheetDef,$actualSheet,$sKey));
02076                                 if (is_array($dataStruct) && $actualSheet==$sKey && is_array($sheetDef))        {
02077                                         foreach($sheetDef as $lKey => $lData)   {
02078                                                 $this->checkValue_flex_procInData_travDS(
02079                                                         $dataPart[$sKey][$lKey],
02080                                                         $dataPart_current[$sKey][$lKey],
02081                                                         $uploadedFiles[$sKey][$lKey],
02082                                                         $dataStruct['ROOT']['el'],
02083                                                         $pParams,
02084                                                         $callBackFunc,
02085                                                         $sKey.'/'.$lKey.'/'
02086                                                 );
02087                                         }
02088                                 }
02089                         }
02090                 }
02091 
02092                 return $dataPart;
02093         }
02094 
02109         function checkValue_flex_procInData_travDS(&$dataValues,$dataValues_current,$uploadedFiles,$DSelements,$pParams,$callBackFunc,$structurePath)   {
02110                 if (is_array($DSelements))      {
02111 
02112                                 // For each DS element:
02113                         foreach($DSelements as $key => $dsConf) {
02114 
02115                                                 // Array/Section:
02116                                 if ($DSelements[$key]['type']=='array') {
02117                                         if (is_array($dataValues[$key]['el']))  {
02118                                                 if ($DSelements[$key]['section'])       {
02119                                                         foreach($dataValues[$key]['el'] as $ik => $el)  {
02120                                                                 $theKey = key($el);
02121                                                                 if (is_array($dataValues[$key]['el'][$ik][$theKey]['el']))      {
02122                                                                         $this->checkValue_flex_procInData_travDS(
02123                                                                                         $dataValues[$key]['el'][$ik][$theKey]['el'],
02124                                                                                         $dataValues_current[$key]['el'][$ik][$theKey]['el'],
02125                                                                                         $uploadedFiles[$key]['el'][$ik][$theKey]['el'],
02126                                                                                         $DSelements[$key]['el'][$theKey]['el'],
02127                                                                                         $pParams,
02128                                                                                         $callBackFunc,
02129                                                                                         $structurePath.$key.'/el/'.$ik.'/'.$theKey.'/el/'
02130                                                                                 );
02131                                                                 }
02132                                                         }
02133                                                 } else {
02134                                                         if (!isset($dataValues[$key]['el']))    $dataValues[$key]['el']=array();
02135                                                         $this->checkValue_flex_procInData_travDS(
02136                                                                         $dataValues[$key]['el'],
02137                                                                         $dataValues_current[$key]['el'],
02138                                                                         $uploadedFiles[$key]['el'],
02139                                                                         $DSelements[$key]['el'],
02140                                                                         $pParams,
02141                                                                         $callBackFunc,
02142                                                                         $structurePath.$key.'/el/'
02143                                                                 );
02144                                                 }
02145                                         }
02146                                 } else {
02147                                         if (is_array($dsConf['TCEforms']['config']) && is_array($dataValues[$key]))     {
02148                                                 foreach($dataValues[$key] as $vKey => $data)    {
02149 
02150                                                         if ($callBackFunc)      {
02151                                                                 if (is_object($this->callBackObj))      {
02152                                                                         $res = $this->callBackObj->$callBackFunc(
02153                                                                                                 $pParams,
02154                                                                                                 $dsConf['TCEforms']['config'],
02155                                                                                                 $dataValues[$key][$vKey],
02156                                                                                                 $dataValues_current[$key][$vKey],
02157                                                                                                 $uploadedFiles[$key][$vKey],
02158                                                                                                 $structurePath.$key.'/'.$vKey.'/'
02159                                                                                         );
02160                                                                 } else {
02161                                                                         $res = $this->$callBackFunc(
02162                                                                                                 $pParams,
02163                                                                                                 $dsConf['TCEforms']['config'],
02164                                                                                                 $dataValues[$key][$vKey],
02165                                                                                                 $dataValues_current[$key][$vKey],
02166                                                                                                 $uploadedFiles[$key][$vKey]
02167                                                                                         );
02168                                                                 }
02169                                                         } else {        // Default
02170                                                                 list($CVtable,$CVid,$CVcurValue,$CVstatus,$CVrealPid,$CVrecFID,$CVtscPID) = $pParams;
02171 
02172                                                                 $res = $this->checkValue_SW(
02173                                                                                         array(),
02174                                                                                         $dataValues[$key][$vKey],
02175                                                                                         $dsConf['TCEforms']['config'],
02176                                                                                         $CVtable,
02177                                                                                         $CVid,
02178                                                                                         $dataValues_current[$key][$vKey],
02179                                                                                         $CVstatus,
02180                                                                                         $CVrealPid,
02181                                                                                         $CVrecFID,
02182                                                                                         '',
02183                                                                                         $uploadedFiles[$key][$vKey],
02184                                                                                         array(),
02185                                                                                         $CVtscPID
02186                                                                                 );
02187 
02188                                                                         // Look for RTE transformation of field:
02189                                                                 if ($dataValues[$key]['_TRANSFORM_'.$vKey] == 'RTE' && !$this->dontProcessTransformations)      {
02190 
02191                                                                                 // Unsetting trigger field - we absolutely don't want that into the data storage!
02192                                                                         unset($dataValues[$key]['_TRANSFORM_'.$vKey]);
02193 
02194                                                                         if (isset($res['value']))       {
02195 
02196                                                                                         // Calculating/Retrieving some values here:
02197                                                                                 list(,,$recFieldName) = explode(':', $CVrecFID);
02198                                                                                 $theTypeString = t3lib_BEfunc::getTCAtypeValue($CVtable,$this->checkValue_currentRecord);
02199                                                                                 $specConf = t3lib_BEfunc::getSpecConfParts('',$dsConf['TCEforms']['defaultExtras']);
02200 
02201                                                                                         // Find, thisConfig:
02202                                                                                 $RTEsetup = $this->BE_USER->getTSConfig('RTE',t3lib_BEfunc::getPagesTSconfig($CVtscPID));
02203                                                                                 $thisConfig = t3lib_BEfunc::RTEsetup($RTEsetup['properties'],$CVtable,$recFieldName,$theTypeString);
02204 
02205                                                                                         // Get RTE object, draw form and set flag:
02206                                                                                 $RTEobj = &t3lib_BEfunc::RTEgetObj();
02207                                                                                 if (is_object($RTEobj)) {
02208                                                                                         $res['value'] = $RTEobj->transformContent('db',$res['value'],$CVtable,$recFieldName,$this->checkValue_currentRecord,$specConf,$thisConfig,'',$CVrealPid);
02209                                                                                 } else {
02210                                                                                         debug('NO RTE OBJECT FOUND!');
02211                                                                                 }
02212                                                                         }
02213                                                                 }
02214                                                         }
02215 
02216                                                                 // Adding the value:
02217                                                         if (isset($res['value']))       {
02218                                                                 $dataValues[$key][$vKey] = $res['value'];
02219                                                         }
02220                                                 }
02221                                         }
02222                                 }
02223                         }
02224                 }
02225         }
02226 
02227 
02228 
02229 
02230 
02231 
02232 
02233 
02234 
02235 
02236 
02237 
02238 
02239 
02240 
02241 
02242 
02243 
02244 
02245 
02246         /*********************************************
02247          *
02248          * Storing data to Database Layer
02249          *
02250          ********************************************/
02251 
02252 
02262         function updateDB($table,$id,$fieldArray)       {
02263                 global $TCA;
02264 
02265                 if (is_array($fieldArray) && is_array($TCA[$table]) && intval($id))     {
02266                         unset($fieldArray['uid']);      // Do NOT update the UID field, ever!
02267 
02268                         if (count($fieldArray)) {
02269 
02270                                         // Execute the UPDATE query:
02271                                 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid='.intval($id), $fieldArray);
02272 
02273                                         // If succees, do...:
02274                                 if (!$GLOBALS['TYPO3_DB']->sql_error()) {
02275                                         if ($this->checkStoredRecords)  {
02276                                                 $newRow = $this->checkStoredRecord($table,$id,$fieldArray,2);
02277                                         }
02278 
02279                                                 // Set log entry:
02280                                         $propArr = $this->getRecordPropertiesFromRow($table,$newRow);
02281                                         $theLogId = $this->log($table,$id,2,$recpid,0,"Record '%s' (%s) was updated.",10,array($propArr['header'],$table.':'.$id),$propArr['event_pid']);
02282 
02283                                                 // Set History data:
02284                                         $this->setHistory($table,$id,$theLogId);
02285 
02286                                                 // Clear cache for relavant pages:
02287                                         $this->clear_cache($table,$id);
02288 
02289                                                 // Unset the pageCache for the id if table was page.
02290                                         if ($table=='pages')    unset($this->pageCache[$id]);
02291                                 } else {
02292                                         $this->log($table,$id,2,0,2,"SQL error: '%s' (%s)",12,array($GLOBALS['TYPO3_DB']->sql_error(),$table.':'.$id));
02293                                 }
02294                         }
02295                 }
02296         }
02297 
02308         function compareFieldArrayWithCurrentAndUnset($table,$id,$fieldArray)   {
02309 
02310                         // Fetch the original record:
02311                 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'uid='.intval($id));
02312                 $currentRecord = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
02313 
02314                         // If the current record exists (which it should...), begin comparison:
02315                 if (is_array($currentRecord))   {
02316 
02317                                 // Read all field types:
02318                         $c = 0;
02319                         $cRecTypes = array();
02320                         foreach($currentRecord as $col => $val) {
02321 // DBAL
02322 #                               $cRecTypes[$col] = $GLOBALS['TYPO3_DB']->sql_field_type($table,$col);
02323                                 $cRecTypes[$col] = $GLOBALS['TYPO3_DB']->sql_field_type($res,$c);
02324                                 $c++;
02325                         }
02326 #debug($cRecTypes);
02327 
02328                                 // Free result:
02329                         $GLOBALS['TYPO3_DB']->sql_free_result($res);
02330 
02331                                 // Unset the fields which are similar:
02332                         foreach($fieldArray as $col => $val)    {
02333                                 if (
02334                                                 #!isset($currentRecord[$col]) ||                // Unset fields which were NOT found in the current record! [Uncommented because NULL fields will not return an entry in the array!]
02335                                                 !strcmp($val,$currentRecord[$col]) ||   // Unset fields which matched exactly.
02336                                                 ($cRecTypes[$col]=='int' && $currentRecord[$col]==0 && !strcmp($val,''))        // Now, a situation where TYPO3 tries to put an empty string into an integer field, we should not strcmp the integer-zero and '', but rather accept them to be similar.
02337                                         )       {
02338                                         unset($fieldArray[$col]);
02339                                 } else {
02340                                         $this->historyRecords[$table.':'.$id]['oldRecord'][$col] = $currentRecord[$col];
02341                                         $this->historyRecords[$table.':'.$id]['newRecord'][$col] = $fieldArray[$col];
02342                                 }
02343                         }
02344                 } else {        // If the current record does not exist this is an error anyways and we just return an empty array here.
02345                         $fieldArray = array();
02346                 }
02347 
02348                 return $fieldArray;
02349         }
02350 
02362         function insertDB($table,$id,$fieldArray,$newVersion=FALSE,$suggestedUid=0)     {
02363                 global $TCA;
02364 
02365                 if (is_array($fieldArray) && is_array($TCA[$table]) && isset($fieldArray['pid']))       {
02366                         unset($fieldArray['uid']);      // Do NOT insert the UID field, ever!
02367 
02368                         if (count($fieldArray)) {
02369 
02370                                         // Check for "suggestedUid".
02371                                         // This feature is used by the import functionality to force a new record to have a certain UID value.
02372                                         // This is only recommended for use when the destination server is a passive mirrow of another server.
02373                                         // As a security measure this feature is available only for Admin Users (for now)
02374                                 $suggestedUid = intval($suggestedUid);
02375                                 if ($this->BE_USER->isAdmin() && $suggestedUid && $this->suggestedInsertUids[$table.':'.$suggestedUid]) {
02376                                                 // When the value of ->suggestedInsertUids[...] is "DELETE" it will try to remove the previous record
02377                                         if ($this->suggestedInsertUids[$table.':'.$suggestedUid]==='DELETE')    {
02378                                                         // DELETE:
02379                                                 $GLOBALS['TYPO3_DB']->exec_DELETEquery($table, 'uid='.intval($suggestedUid));
02380                                         }
02381                                         $fieldArray['uid'] = $suggestedUid;
02382                                 }
02383 
02384                                         // Execute the INSERT query:
02385                                 $GLOBALS['TYPO3_DB']->exec_INSERTquery($table, $fieldArray);
02386 
02387                                         // If succees, do...:
02388                                 if (!$GLOBALS['TYPO3_DB']->sql_error()) {
02389 
02390                                                 // Set mapping for NEW... -> real uid:
02391                                         $NEW_id = $id;          // the NEW_id now holds the 'NEW....' -id
02392                                         $id = $GLOBALS['TYPO3_DB']->sql_insert_id();
02393                                         $this->substNEWwithIDs[$NEW_id] = $id;
02394                                         $this->substNEWwithIDs_table[$NEW_id] = $table;
02395 
02396                                                 // Checking the record is properly saved and writing to log
02397                                         if ($this->checkStoredRecords)  {
02398                                                 $newRow = $this->checkStoredRecord($table,$id,$fieldArray,1);
02399                                         }
02400 
02401                                         if ($newVersion)        {
02402                                                 $this->log($table,$id,1,0,0,"New version created of table '%s', uid '%s'",10,array($table,$fieldArray['t3ver_oid']),$newRow['pid'],$NEW_id);
02403                                         } else {
02404                                                         // Set log entry:
02405                                                 if ($table=='pages')    {
02406                                                         $thePositionID = $this->getInterfacePagePositionID($id);
02407                                                 } else {
02408                                                         $thePositionID = 0;
02409                                                 }
02410                                                 $propArr = $this->getRecordPropertiesFromRow($table,$newRow);
02411                                                 $page_propArr = $this->getRecordProperties('pages',$propArr['pid']);
02412                                                 $this->log($table,$id,1,$thePositionID,0,"Record '%s' (%s) was inserted on page '%s' (%s)",10,array($propArr['header'],$table.':'.$id,$page_propArr['header'],$newRow['pid']),$newRow['pid'],$NEW_id);
02413 
02414                                                         // Clear cache for relavant pages:
02415                                                 $this->clear_cache($table,$id);
02416                                         }
02417                                 } else {
02418                                         $this->log($table,$id,1,0,2,"SQL error: '%s' (%s)",12,array($GLOBALS['TYPO3_DB']->sql_error(),$table.':'.$id));
02419                                 }
02420                         }
02421                 }
02422         }
02423 
02434         function checkStoredRecord($table,$id,$fieldArray,$action)      {
02435                 global $TCA;
02436 
02437                 $id = intval($id);
02438                 if (is_array($TCA[$table]) && $id)      {
02439                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'uid='.intval($id));
02440                         if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
02441                                         // Traverse array of values that was inserted into the database and compare with the actually stored value:
02442                                 $errorString = array();
02443                                 foreach($fieldArray as $key => $value)  {
02444                                         if ($this->checkStoredRecords_loose && !$value && !$row[$key])  {
02445                                                 // Nothing...
02446                                         } elseif (strcmp($value,$row[$key]))    {
02447                                           // DEBUGGING KFISH
02448                                           // debug(array("$value != ".$row[$key]));
02449                                                 $errorString[] = $key;
02450                                         }
02451                                 }
02452 
02453                                         // Set log message if there were fields with unmatching values:
02454                                 if (count($errorString))        {
02455                                         $this->log($table,$id,$action,0,102,'These fields are not properly updated in database: ('.implode(',',$errorString).') Probably value mismatch with fieldtype.');
02456                                 }
02457 
02458                                         // Return selected rows:
02459                                 return $row;
02460                         }
02461                         $GLOBALS['TYPO3_DB']->sql_free_result($res);
02462                 }
02463         }
02464 
02470         function dbAnalysisStoreExec()  {
02471                 reset($this->dbAnalysisStore);
02472                 while(list($k,$v)=each($this->dbAnalysisStore)) {
02473                         $id = $this->substNEWwithIDs[$v[2]];
02474                         if ($id)        {
02475                                 $v[2] = $id;
02476                                 $v[0]->writeMM($v[1],$v[2],$v[3]);
02477                         }
02478                 }
02479         }
02480 
02486         function removeRegisteredFiles()        {
02487                 reset($this->removeFilesStore);
02488                 while(list($k,$v)=each($this->removeFilesStore))        {
02489                         unlink($v);
02490 //                      debug($v,1);
02491                 }
02492         }
02493 
02503         function clear_cache($table,$uid) {
02504                 global $TCA, $TYPO3_CONF_VARS;
02505 
02506                 $uid = intval($uid);
02507                 if (is_array($TCA[$table]) && $uid > 0) {
02508 
02509                                 // Get Page TSconfig relavant:
02510                         list($tscPID) = t3lib_BEfunc::getTSCpid($table,$uid,'');
02511                         $TSConfig = $this->getTCEMAIN_TSconfig($tscPID);
02512 
02513                         if (!$TSConfig['clearCache_disable'])   {
02514 
02515                                         // If table is "pages":
02516                                 if (t3lib_extMgm::isLoaded('cms'))      {
02517                                         $list_cache = array();
02518                                         if ($table=='pages')    {
02519 
02520                                                         // Builds list of pages on the SAME level as this page (siblings)
02521                                                 $res_tmp = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
02522                                                                                 'A.pid AS pid, B.uid AS uid',
02523                                                                                 'pages A, pages B',
02524                                                                                 'A.uid='.intval($uid).' AND B.pid=A.pid AND B.deleted=0'
02525                                                                         );
02526 
02527                                                 $pid_tmp = 0;
02528                                                 while ($row_tmp = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res_tmp)) {
02529                                                         $list_cache[] = $row_tmp['uid'];
02530                                                         $pid_tmp = $row_tmp['pid'];
02531 
02532                                                                 // Add children as well:
02533                                                         if ($TSConfig['clearCache_pageSiblingChildren'])        {
02534                                                                 $res_tmp2 = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
02535                                                                                                 'uid',
02536                                                                                                 'pages',
02537                                                                                                 'pid='.intval($row_tmp['uid']).' AND deleted=0'
02538                                                                                         );
02539                                                                 while ($row_tmp2 = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res_tmp2))    {
02540                                                                         $list_cache[] = $row_tmp2['uid'];
02541                                                                 }
02542                                                         }
02543                                                 }
02544 
02545                                                         // Finally, add the parent page as well:
02546                                                 $list_cache[] = $pid_tmp;
02547 
02548                                                         // Add grand-parent as well:
02549                                                 if ($TSConfig['clearCache_pageGrandParent'])    {
02550                                                         $res_tmp = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
02551                                                                                         'pid',
02552                                                                                         'pages',
02553                                                                                         'uid='.intval($pid_tmp)
02554                                                                                 );
02555                                                         if ($row_tmp = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res_tmp)) {
02556                                                                 $list_cache[] = $row_tmp['pid'];
02557                                                         }
02558                                                 }
02559                                         } else {        // For other tables than "pages", delete cache for the records "parent page".
02560                                                 $list_cache[] = intval($this->getPID($table,$uid));
02561                                         }
02562 
02563                                                 // Call pre-processing function for clearing of cache for page ids:
02564                                         if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearPageCacheEval']))    {
02565                                                 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearPageCacheEval'] as $funcName)     {
02566                                                         $_params = array('pageIdArray' => &$list_cache, 'table' => $table, 'uid' => $uid, 'functionID' => 'clear_cache()');
02567                                                                 // Returns the array of ids to clear, false if nothing should be cleared! Never an empty array!
02568                                                         t3lib_div::callUserFunction($funcName,$_params,$this);
02569                                                 }
02570                                         }
02571 
02572                                                 // Delete cache for selected pages:
02573                                         if (is_array($list_cache))      {
02574                                                 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages','page_id IN ('.implode(',',$GLOBALS['TYPO3_DB']->cleanIntArray($list_cache)).')');
02575                                                 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pagesection', 'page_id IN ('.implode(',',$GLOBALS['TYPO3_DB']->cleanIntArray($list_cache)).')');
02576                                         }
02577                                 }
02578                         }
02579 
02580                                 // Clear cache for pages entered in TSconfig:
02581                         if ($TSConfig['clearCacheCmd']) {
02582                                 $Commands = t3lib_div::trimExplode(',',strtolower($TSConfig['clearCacheCmd']),1);
02583                                 $Commands = array_unique($Commands);
02584                                 foreach($Commands as $cmdPart)  {
02585                                         $this->clear_cacheCmd($cmdPart);
02586                                 }
02587                         }
02588 
02589                                 // Call post processing function for clear-cache:
02590                         global $TYPO3_CONF_VARS;
02591                         if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc']))    {
02592                                 $_params = array('table' => $table,'uid' => $uid,'uid_page' => $uid_page,'TSConfig' => $TSConfig);
02593                                 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc'] as $_funcRef)     {
02594                                         t3lib_div::callUserFunction($_funcRef,$_params,$this);
02595                                 }
02596                         }
02597                 }
02598         }
02599 
02607         function getPID($table,$uid)    {
02608                 $res_tmp = $GLOBALS['TYPO3_DB']->exec_SELECTquery('pid', $table, 'uid='.intval($uid));
02609                 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res_tmp))     {
02610                         return $row['pid'];
02611                 }
02612         }
02613 
02614 
02615 
02616 
02617 
02618 
02619 
02620 
02621 
02622 
02623 
02624 
02625 
02626 
02627 
02628 
02629 
02630 
02631 
02632 
02633 
02634 
02635 
02636 
02637 
02638         /*********************************************
02639          *
02640          * PROCESSING COMMANDS
02641          *
02642          ********************************************/
02643 
02650         function process_cmdmap() {
02651                 global $TCA, $TYPO3_CONF_VARS;
02652 
02653                 $hookObjectsArr = array();
02654                 if (is_array ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass'])) {
02655                         foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processCmdmapClass'] as $classRef) {
02656                                 $hookObjectsArr[] = &t3lib_div::getUserObj($classRef);
02657                         }
02658                 }
02659 
02660                         // Traverse command map:
02661                 reset ($this->cmdmap);
02662                 while (list($table,) = each($this->cmdmap))     {
02663 
02664                                 // Check if the table may be modified!
02665                         $modifyAccessList = $this->checkModifyAccessList($table);
02666                         if (!$modifyAccessList) {
02667                                 $this->log($table,$id,2,0,1,"Attempt to modify table '%s' without permission",1,array($table));
02668                         }
02669 
02670                                 // Check basic permissions and circumstances:
02671                         if (isset($TCA[$table]) && !$this->tableReadOnly($table) && is_array($this->cmdmap[$table]) && $modifyAccessList)       {
02672 
02673                                         // Traverse the command map:
02674                                 foreach($this->cmdmap[$table] as $id => $incomingCmdArray)      {
02675                                         if (is_array($incomingCmdArray))        {       // have found a command.
02676 
02677                                                         // Get command and value (notice, only one command is observed at a time!):
02678                                                 reset($incomingCmdArray);
02679                                                 $command = key($incomingCmdArray);
02680                                                 $value = current($incomingCmdArray);
02681 
02682                                                 foreach($hookObjectsArr as $hookObj) {
02683                                                         if (method_exists($hookObj, 'processCmdmap_preProcess')) {
02684                                                                 $hookObj->processCmdmap_preProcess($command, $table, $id, $value, $this);
02685                                                         }
02686                                                 }
02687 
02688                                                         // Init copyMapping array:
02689                                                 $this->copyMappingArray = Array();              // Must clear this array before call from here to those functions: Contains mapping information between new and old id numbers.
02690 
02691                                                         // Branch, based on command
02692                                                 switch ($command)       {
02693                                                         case 'move':
02694                                                                 $this->moveRecord($table,$id,$value);
02695                                                         break;
02696                                                         case 'copy':
02697                                                                 if ($table == 'pages')  {
02698                                                                         $this->copyPages($id,$value);
02699                                                                 } else {
02700                                                                         $this->copyRecord($table,$id,$value,1);
02701                                                                 }
02702                                                         break;
02703                                                         case 'localize':
02704                                                                 $this->copyRecord_localize($table,$id,$value);
02705                                                         break;
02706                                                         case 'version':
02707                                                                 switch ((string)$value['action'])       {
02708                                                                         case 'new':
02709                                                                                 $this->versionizeTree = t3lib_div::intInRange($value['treeLevels'],-1,4);       // Max 4 levels of versioning...
02710                                                                                 if ($table == 'pages' && $this->versionizeTree>=0)      {
02711                                                                                         $this->versionizePages($id,$value['label']);
02712                                                                                 } else {
02713                                                                                         $this->versionizeRecord($table,$id,$value['label']);
02714                                                                                 }
02715                                                                         break;
02716                                                                         case 'swap':
02717                                                                                 $this->version_swap($table,$id,$value['swapWith'],$value['swapContent']);
02718                                                                         break;
02719                                                                 }
02720                                                         break;
02721                                                         case 'delete':
02722                                                                 if ($table == 'pages')  {
02723                                                                         $this->deletePages($id);
02724                                                                 } else {
02725                                                                         $this->deleteRecord($table,$id, 0);
02726                                                                 }
02727                                                         break;
02728                                                 }
02729 
02730                                                 foreach($hookObjectsArr as $hookObj) {
02731                                                         if (method_exists($hookObj, 'processCmdmap_postProcess')) {
02732                                                                 $hookObj->processCmdmap_postProcess($command, $table, $id, $value, $this);
02733                                                         }
02734                                                 }
02735 
02736                                                         // Merging the copy-array info together for remapping purposes.
02737                                                 $this->copyMappingArray_merged= t3lib_div::array_merge_recursive_overrule($this->copyMappingArray_merged,$this->copyMappingArray);
02738                                         }
02739                                 }
02740                         }
02741                 }
02742 
02743 #debug($this->copyMappingArray_merged,'$this->copyMappingArray_merged');
02744 #debug($this->registerDBList,'$this->registerDBList');
02745 
02746                         // Finally, before exit, check if there are ID references to remap. This might be the case if versioning or copying has taken place!
02747                 $this->remapListedDBRecords();
02748         }
02749 
02758         function moveRecord($table,$uid,$destPid)       {
02759                 global $TCA;
02760 
02761                         // Initialize:
02762                 $sortRow = $TCA[$table]['ctrl']['sortby'];
02763                 $destPid = intval($destPid);
02764                 $origDestPid = $destPid;
02765 
02766                 if ($TCA[$table])       {
02767                         $propArr = $this->getRecordProperties($table,$uid);     // Get this before we change the pid (for logging)
02768                         $resolvedPid = $this->resolvePid($table,$destPid);      // This is the actual pid of the moving.
02769 
02770                                 // Finding out, if the record may be moved from where it is. If the record is a non-page, then it depends on edit-permissions.
02771                                 // If the record is a page, then there are two options: If the page is moved within itself, (same pid) it's edit-perms of the pid. If moved to another place then its both delete-perms of the pid and new-page perms on the destination.
02772                         if ($table!='pages' || $resolvedPid==$propArr['pid'])   {
02773                                 $mayMoveAccess = $this->checkRecordUpdateAccess($table,$uid);   // Edit rights for the record...
02774                         } else {
02775                                 $mayMoveAccess = $this->doesRecordExist($table,$uid,'delete');
02776                         }
02777 
02778                                 // Finding out, if the record may be moved TO another place. Here we check insert-rights (non-pages = edit, pages = new), unless the pages is moved on the same pid, then edit-rights are checked
02779                         if ($table!='pages' || $resolvedPid!=$propArr['pid'])   {
02780                                 $mayInsertAccess = $this->checkRecordInsertAccess($table,$resolvedPid,4);       // Edit rights for the record...
02781                         } else {
02782                                 $mayInsertAccess = $this->checkRecordUpdateAccess($table,$uid);
02783                         }
02784 
02785                                 // Checking if the pid is negativ, but no sorting row is defined. In that case, find the correct pid. Basically this check make the error message 4-13 meaning less... But you can always remove this check if you prefer the error instead of a no-good action (which is to move the record to its own page...)
02786                         if ($destPid<0 && !$sortRow)    {
02787                                 $destPid = $resolvedPid;
02788                         }
02789 
02790                                 // Timestamp field:
02791                         $updateFields = array();
02792                         if ($TCA[$table]['ctrl']['tstamp'])     {
02793                                 $updateFields[$TCA[$table]['ctrl']['tstamp']] = time();
02794                         }
02795 
02796                                 // If moving is allowed, begin the processing:
02797                         if ($mayMoveAccess)     {
02798                                 if ($destPid>=0)        {       // insert as first element on page (where uid = $destPid)
02799                                         if ($mayInsertAccess)   {
02800                                                 if ($table!='pages' || $this->destNotInsideSelf ($destPid,$uid))        {
02801                                                         $this->clear_cache($table,$uid);        // clear cache before moving
02802 
02803                                                         $updateFields['pid'] = $destPid;        // Setting PID
02804 
02805                                                                 // table is sorted by 'sortby'
02806                                                         if ($sortRow)   {
02807                                                                 $sortNumber = $this->getSortNumber($table,$uid,$destPid);
02808                                                                 $updateFields[$sortRow] = $sortNumber;
02809                                                         }
02810 
02811                                                                 // Create query for update:
02812                                                         $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid='.intval($uid), $updateFields);
02813 
02814                                                                 // Logging...
02815                                                         $newPropArr = $this->getRecordProperties($table,$uid);
02816                                                         $oldpagePropArr = $this->getRecordProperties('pages',$propArr['pid']);
02817                                                         $newpagePropArr = $this->getRecordProperties('pages',$destPid);
02818 
02819                                                         if ($destPid!=$propArr['pid'])  {
02820                                                                 $this->log($table,$uid,4,$destPid,0,"Moved record '%s' (%s) to page '%s' (%s)",2,array($propArr['header'],$table.':'.$uid, $newpagePropArr['header'], $newPropArr['pid']),$propArr['pid']);     // Logged to old page
02821                                                                 $this->log($table,$uid,4,$destPid,0,"Moved record '%s' (%s) from page '%s' (%s)",3,array($propArr['header'],$table.':'.$uid, $oldpagePropArr['header'], $propArr['pid']),$destPid);     // Logged to new page
02822                                                         } else {
02823                                                                 $this->log($table,$uid,4,$destPid,0,"Moved record '%s' (%s) on page '%s' (%s)",4,array($propArr['header'],$table.':'.$uid, $oldpagePropArr['header'], $propArr['pid']),$destPid);       // Logged to new page
02824                                                         }
02825                                                         $this->clear_cache($table,$uid);        // clear cache after moving
02826                                                         $this->fixUniqueInPid($table,$uid);
02827                                                                 // fixCopyAfterDuplFields
02828                                                         if ($origDestPid<0)     {$this->fixCopyAfterDuplFields($table,$uid,abs($origDestPid),1);}       // origDestPid is retrieve before it may possibly be converted to resolvePid if the table is not sorted anyway. In this way, copying records to after another records which are not sorted still lets you use this function in order to copy fields from the one before.
02829                                                 } else {
02830                                                         $destPropArr = $this->getRecordProperties('pages',$destPid);
02831                                                         $this->log($table,$uid,4,0,1,"Attempt to move page '%s' (%s) to inside of its own rootline (at page '%s' (%s))",10,array($propArr['header'],$uid, $destPropArr['header'], $destPid),$propArr['pid']);
02832                                                 }
02833                                         }
02834                                 } else {        // Put after another record
02835                                         if ($sortRow)   {       // table is being sorted
02836                                                 $sortInfo = $this->getSortNumber($table,$uid,$destPid);
02837                                                 $destPid = $sortInfo['pid'];    // Setting the destPid to the new pid of the record.
02838                                                 if (is_array($sortInfo))        {       // If not an array, there was an error (which is already logged)
02839                                                         if ($mayInsertAccess)   {
02840                                                                 if ($table!='pages' || $this->destNotInsideSelf($destPid,$uid)) {
02841                                                                         $this->clear_cache($table,$uid);        // clear cache before moving
02842 
02843                                                                                 // We now update the pid and sortnumber
02844                                                                         $updateFields['pid'] = $destPid;
02845                                                                         $updateFields[$sortRow] = $sortInfo['sortNumber'];
02846                                                                         $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid='.intval($uid), $updateFields);
02847 
02848                                                                                 // Logging...
02849                                                                         if ($table=='pages')    {
02850                                                                                 $thePositionID = $this->getInterfacePagePositionID($uid);
02851                                                                         } else {
02852                                                                                 $thePositionID = 0;
02853                                                                         }
02854                                                                         $this->log($table,$uid,4,$thePositionID,0,'');
02855 
02856                                                                                 // Logging...
02857                                                                         $newPropArr = $this->getRecordProperties($table,$uid);
02858                                                                         $oldpagePropArr = $this->getRecordProperties('pages',$propArr['pid']);
02859                                                                         if ($destPid!=$propArr['pid'])  {
02860                                                                                 $newpagePropArr = $this->getRecordProperties('pages',$destPid);
02861                                                                                 $this->log($table,$uid,4,$thePositionID,0,"Moved record '%s' (%s) to page '%s' (%s)",2,array($propArr['header'],$table.':'.$uid, $newpagePropArr['header'], $newPropArr['pid']),$propArr['pid']);       // Logged to old page
02862                                                                                 $this->log($table,$uid,4,$thePositionID,0,"Moved record '%s' (%s) from page '%s' (%s)",3,array($propArr['header'],$table.':'.$uid, $oldpagePropArr['header'], $propArr['pid']),$destPid);       // Logged to new page
02863                                                                         } else {
02864                                                                                 $this->log($table,$uid,4,$thePositionID,0,"Moved record '%s' (%s) on page '%s' (%s)",4,array($propArr['header'],$table.':'.$uid, $oldpagePropArr['header'], $propArr['pid']),$destPid); // Logged to new page
02865                                                                         }
02866 
02867                                                                                 // clear cache after moving
02868                                                                         $this->clear_cache($table,$uid);
02869 
02870                                                                                 // fixUniqueInPid
02871                                                                         $this->fixUniqueInPid($table,$uid);
02872 
02873                                                                                 // fixCopyAfterDuplFields
02874                                                                         if ($origDestPid<0)     {$this->fixCopyAfterDuplFields($table,$uid,abs($origDestPid),1);}
02875                                                                 } else {
02876                                                                         $destPropArr = $this->getRecordProperties('pages',$destPid);
02877                                                                         $this->log($table,$uid,4,0,1,"Attempt to move page '%s' (%s) to inside of its own rootline (at page '%s' (%s))",10,array($propArr['header'],$uid, $destPropArr['header'], $destPid),$propArr['pid']);
02878                                                                 }
02879                                                         }
02880                                                 }
02881                                         } else {
02882                                                 $this->log($table,$uid,4,0,1,"Attempt to move record '%s' (%s) to after another record, although the table has no sorting row.",13,array($propArr['header'],$table.':'.$uid),$propArr['event_pid']);
02883                                         }
02884                                 }
02885                         } else {
02886                                 $this->log($table,$uid,4,0,1,"Attempt to move record '%s' (%s) without having permissions to do so",14,array($propArr['header'],$table.':'.$uid),$propArr['event_pid']);
02887                         }
02888                 }
02889         }
02890 
02902         function copyRecord($table,$uid,$destPid,$first=0,$overrideValues=array(),$excludeFields='')    {
02903                 global $TCA;
02904 
02905                 $uid = intval($uid);
02906                 if ($TCA[$table] && $uid)       {
02907                         t3lib_div::loadTCA($table);
02908                         if ($this->doesRecordExist($table,$uid,'show')) {               // This checks if the record can be selected which is all that a copy action requires.
02909                                 $data = Array();
02910 
02911                                 $nonFields = array_unique(t3lib_div::trimExplode(',','uid,perms_userid,perms_groupid,perms_user,perms_group,perms_everybody,t3ver_oid,t3ver_id,t3ver_label,'.$excludeFields,1));
02912 
02913                                 $row = $this->recordInfo($table,$uid,'*');
02914                                 if (is_array($row))     {
02915 
02916                                                 // Initializing:
02917                                         $theNewID = uniqid('NEW');
02918                                         $enableField = isset($TCA[$table]['ctrl']['enablecolumns']) ? $TCA[$table]['ctrl']['enablecolumns']['disabled'] : '';
02919                                         $headerField = $TCA[$table]['ctrl']['label'];
02920 
02921                                                 // Getting default data:
02922                                         $defaultData = $this->newFieldArray($table);
02923 
02924                                                 // Getting "copy-after" fields if applicable:
02925                                                 // origDestPid is retrieve before it may possibly be converted to resolvePid if the table is not sorted anyway. In this way, copying records to after another records which are not sorted still lets you use this function in order to copy fields from the one before.
02926                                         $copyAfterFields = $destPid<0 ? $this->fixCopyAfterDuplFields($table,$uid,abs($destPid),0) : array();
02927 
02928                                                 // Page TSconfig related:
02929                                         $tscPID = t3lib_BEfunc::getTSconfig_pidValue($table,$uid,$destPid);     // NOT using t3lib_BEfunc::getTSCpid() because we need the real pid - not the id of a page, if the input is a page...
02930                                         $TSConfig = $this->getTCEMAIN_TSconfig($tscPID);
02931                                         $tE = $this->getTableEntries($table,$TSConfig);
02932 
02933                                                 // Traverse ALL fields of the selected record:
02934                                         foreach($row as $field => $value)       {
02935                                                 if (!in_array($field,$nonFields))       {
02936 
02937                                                                 // Get TCA configuration for the field:
02938                                                         $conf = $TCA[$table]['columns'][$field]['config'];
02939 
02940                                                                 // Preparation/Processing of the value:
02941                                                         if ($field=='pid')      {       // "pid" is hardcoded of course:
02942                                                                 $value = $destPid;
02943                                                         } elseif (isset($overrideValues[$field]))       {       // Override value...
02944                                                                 $value = $overrideValues[$field];
02945                                                         } elseif (isset($copyAfterFields[$field]))      {       // Copy-after value if available:
02946                                                                 $value = $copyAfterFields[$field];
02947                                                         } elseif ($TCA[$table]['ctrl']['setToDefaultOnCopy'] && t3lib_div::inList($TCA[$table]['ctrl']['setToDefaultOnCopy'],$field))   {       // Revert to default for some fields:
02948                                                                 $value = $defaultData[$field];
02949                                                         } else {
02950                                                                         // Hide at copy may override:
02951                                                                 if ($first && $field==$enableField && $TCA[$table]['ctrl']['hideAtCopy'] && !$this->neverHideAtCopy && !$tE['disableHideAtCopy'])       {
02952                                                                         $value=1;
02953                                                                 }
02954                                                                         // Prepend label on copy:
02955                                                                 if ($first && $field==$headerField && $TCA[$table]['ctrl']['prependAtCopy'] && !$tE['disablePrependAtCopy'])    {
02956                                                                         $value = $this->getCopyHeader($table,$this->resolvePid($table,$destPid),$field,$this->clearPrefixFromValue($table,$value),0);
02957                                                                 }
02958                                                                         // Processing based on the TCA config field type (files, references, flexforms...)
02959                                                                 $value = $this->copyRecord_procBasedOnFieldType($table,$uid,$field,$value,$row,$conf);
02960                                                         }
02961 
02962                                                                 // Add value to array.
02963                                                         $data[$table][$theNewID][$field] = $value;
02964                                                 }
02965 
02966                                                         // Overriding values:
02967                                                 if ($TCA[$table]['ctrl']['editlock'])   {
02968                                                         $data[$table][$theNewID][$TCA[$table]['ctrl']['editlock']] = 0;
02969                                                 }
02970                                         }
02971 
02972                                                 // Do the copy by simply submitting the array through TCEmain:
02973                                         $copyTCE = t3lib_div::makeInstance('t3lib_TCEmain');
02974                                         $copyTCE->stripslashes_values = 0;
02975                                         $copyTCE->copyTree = $this->copyTree;
02976                                         $copyTCE->cachedTSconfig = $this->cachedTSconfig;       // Copy forth the cached TSconfig
02977                                         $copyTCE->dontProcessTransformations=1;         // Transformations should NOT be carried out during copy
02978         //                              $copyTCE->enableLogging = $table=='pages'?1:0;  // If enabled the list-view does not update...
02979 
02980                                         $copyTCE->start($data,'',$this->BE_USER);
02981                                         $copyTCE->process_datamap();
02982 
02983                                                 // Getting the new UID:
02984                                         $theNewSQLID = $copyTCE->substNEWwithIDs[$theNewID];
02985                                         if ($theNewSQLID)       {
02986                                                 $this->copyMappingArray[$table][$uid] = $theNewSQLID;
02987                                         }
02988 
02989                                                 // Copy back the cached TSconfig
02990                                         $this->cachedTSconfig = $copyTCE->cachedTSconfig;
02991                                         unset($copyTCE);
02992                                 } else $this->log($table,$uid,3,0,1,'Attempt to copy record that did not exist!');
02993                         } else $this->log($table,$uid,3,0,1,'Attempt to copy record without permission');
02994                 }
02995         }
02996 
03011         function copyRecord_raw($table,$uid,$pid,$overrideArray=array())        {
03012                 global $TCA;
03013 
03014                 $uid = intval($uid);
03015                 if ($TCA[$table] && $uid)       {
03016                         t3lib_div::loadTCA($table);
03017                         if ($this->doesRecordExist($table,$uid,'show')) {
03018 
03019                                         // Set up fields which should not be processed. They are still written - just passed through no-questions-asked!
03020                                 $nonFields = array('uid','pid','t3ver_id','t3ver_oid','t3ver_label','perms_userid','perms_groupid','perms_user','perms_group','perms_everybody');
03021 
03022                                         // Select main record:
03023                                 $row = $this->recordInfo($table,$uid,'*');
03024                                 if (is_array($row))     {
03025 
03026                                                 // Merge in override array.
03027                                         $row = array_merge($row,$overrideArray);
03028 
03029                                                 // Traverse ALL fields of the selected record:
03030                                         foreach($row as $field => $value)       {
03031                                                 if (!in_array($field,$nonFields))       {
03032 
03033                                                                 // Get TCA configuration for the field:
03034                                                         $conf = $TCA[$table]['columns'][$field]['config'];
03035                                                         if (is_array($conf))    {
03036                                                                         // Processing based on the TCA config field type (files, references, flexforms...)
03037                                                                 $value = $this->copyRecord_procBasedOnFieldType($table,$uid,$field,$value,$row,$conf);
03038                                                         }
03039 
03040                                                                 // Add value to array.
03041                                                         $row[$field] = $value;
03042                                                 }
03043                                         }
03044 
03045                                                 // Force versioning related fields:
03046                                         $row['pid'] = $pid;
03047 
03048                                                 // Do the copy by internal function
03049                                         $theNewSQLID = $this->insertNewCopyVersion($table,$row,$pid);
03050                                         if ($theNewSQLID)       {
03051                                                 return $this->copyMappingArray[$table][$uid] = $theNewSQLID;
03052                                         }
03053                                 } else $this->log($table,$uid,3,0,1,'Attempt to rawcopy/versionize record that did not exist!');
03054                         } else $this->log($table,$uid,3,0,1,'Attempt to rawcopy/versionize record without copy permission');
03055                 }
03056         }
03057 
03067         function insertNewCopyVersion($table,$fieldArray,$realPid)      {
03068                 global $TCA;
03069 
03070                 $id = uniqid('NEW');
03071 
03072                         // $fieldArray is set as current record.
03073                         // 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...
03074                 $this->checkValue_currentRecord = $fieldArray;
03075 
03076                         // Traverse record and input-process each value:
03077                 foreach($fieldArray as $field => $fieldValue)   {
03078                         if (isset($TCA[$table]['columns'][$field]))     {
03079                                         // Evaluating the value.
03080                                 $res = $this->checkValue($table,$field,$fieldValue,$id,'new',$realPid,0);
03081                                 if (isset($res['value']))       {
03082                                         $fieldArray[$field] = $res['value'];
03083                                 }
03084                         }
03085                 }
03086 
03087                         // System fields being set:
03088                 if ($TCA[$table]['ctrl']['crdate'])     {
03089                         $fieldArray[$TCA[$table]['ctrl']['crdate']]=time();
03090                 }
03091                 if ($TCA[$table]['ctrl']['cruser_id'])  {
03092                         $fieldArray[$TCA[$table]['ctrl']['cruser_id']]=$this->userid;
03093                 }
03094                 if ($TCA[$table]['ctrl']['tstamp'])     {
03095                         $fieldArray[$TCA[$table]['ctrl']['tstamp']]=time();
03096                 }
03097 
03098                         // Finally, insert record:
03099                 $this->insertDB($table,$id,$fieldArray, TRUE);
03100 
03101                         // Return new id:
03102                 return $this->substNEWwithIDs[$id];
03103         }
03104 
03118         function copyRecord_procBasedOnFieldType($table,$uid,$field,$value,$row,$conf)  {
03119                 global $TCA;
03120 
03121                         // Process references and files, currently that means only the files, prepending absolute paths (so the TCEmain engine will detect the file as new and one that should be made into a copy)
03122                 $value = $this->copyRecord_procFilesRefs($conf, $uid, $value);
03123 
03124 
03125                         // Register if there are references to take care of (no change to value):
03126                 if ($this->isReferenceField($conf))     {
03127                         $allowedTables = $conf['type']=='group' ? $conf['allowed'] : $conf['foreign_table'].','.$conf['neg_foreign_table'];
03128                         $prependName = $conf['type']=='group' ? $conf['prepend_tname'] : $conf['neg_foreign_table'];
03129                         if ($conf['MM'])        {
03130                                 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
03131                                 $dbAnalysis->start('',$allowedTables,$conf['MM'],$uid);
03132                                 $value = implode(',',$dbAnalysis->getValueArray($prependName));
03133                         }
03134                         if ($value)     {       // Setting the value in this array will notify the remapListedDBRecords() function that this field MAY need references to be corrected
03135                                 $this->registerDBList[$table][$uid][$field] = $value;
03136                         }
03137                 }
03138 
03139                         // For "flex" fieldtypes we need to traverse the structure for two reasons: If there are file references they have to be prepended with absolute paths and if there are database reference they MIGHT need to be remapped (still done in remapListedDBRecords())
03140                 if ($conf['type']=='flex')      {
03141 
03142                                 // Get current value array:
03143                         $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $row, $table);
03144                         $currentValueArray = t3lib_div::xml2array($value);
03145 
03146                                 // Traversing the XML structure, processing files:
03147                         if (is_array($currentValueArray))       {
03148                                 $currentValueArray['data'] = $this->checkValue_flex_procInData(
03149                                                         $currentValueArray['data'],
03150                                                         array(),        // Not used.
03151                                                         array(),        // Not used.
03152                                                         $dataStructArray,
03153                                                         array($table,$uid,$field),      // Parameters.
03154                                                         'copyRecord_flexFormCallBack'
03155                                                 );
03156                                 $value = $currentValueArray;    // Setting value as an array! -> which means the input will be processed according to the 'flex' type when the new copy is created.
03157                         }
03158                 }
03159 
03160                 return $value;
03161         }
03162 
03171         function copyRecord_localize($table,$uid,$language)     {
03172                 global $TCA;
03173 
03174                 $uid = intval($uid);
03175 
03176                 if ($TCA[$table] && $uid)       {
03177                         t3lib_div::loadTCA($table);
03178 
03179                         if ($TCA[$table]['ctrl']['languageField'] && $TCA[$table]['ctrl']['transOrigPointerField'])     {
03180                                 if ($langRec = t3lib_BEfunc::getRecord('sys_language',intval($language),'uid,title'))   {
03181                                         if ($this->doesRecordExist($table,$uid,'show')) {
03182 
03183                                                 $row = $this->recordInfo($table,$uid,'*');
03184                                                 if (is_array($row))     {
03185                                                         if ($row[$TCA[$table]['ctrl']['languageField']] <= 0)   {
03186                                                                 if ($row[$TCA[$table]['ctrl']['transOrigPointerField']] == 0)   {
03187                                                                         if (!t3lib_BEfunc::getRecordsByField($table,$TCA[$table]['ctrl']['transOrigPointerField'],$uid,'AND pid='.intval($row['pid']).' AND '.$TCA[$table]['ctrl']['languageField'].'='.$langRec['uid']))       {
03188 
03189                                                                                         // Initialize:
03190                                                                                 $overrideValues = array();
03191                                                                                 $excludeFields = array();
03192 
03193                                                                                         // Set override values:
03194                                                                                 $overrideValues[$TCA[$table]['ctrl']['languageField']] = $langRec['uid'];
03195                                                                                 $overrideValues[$TCA[$table]['ctrl']['transOrigPointerField']] = $uid;
03196 
03197                                                                                         // Set exclude Fields:
03198                                                                                 foreach($TCA[$table]['columns'] as $fN => $fCfg)        {
03199                                                                                         if ($fCfg['l10n_mode']=='prefixLangTitle')      {       // Check if we are just prefixing:
03200                                                                                                 if ($fCfg['config']['type']=='text' || $fCfg['config']['type']=='input')        {
03201                                                                                                         $overrideValues[$fN] = '[Translate to '.$langRec['title'].':] '.$row[$fN];
03202                                                                                                 }
03203                                                                                         } elseif (t3lib_div::inList('exclude,noCopy,mergeIfNotBlank',$fCfg['l10n_mode']) && $fN!=$TCA[$table]['ctrl']['languageField'] && $fN!=$TCA[$table]['ctrl']['transOrigPointerField']) {  // Otherwise, do not copy field (unless it is the language field or pointer to the original language)
03204                                                                                                 $excludeFields[] = $fN;
03205                                                                                         }
03206                                                                                 }
03207                                                                                         // Execute the copy:
03208                                                                                 $this->copyRecord($table,$uid,-$uid,1,$overrideValues,implode(',',$excludeFields));
03209                                                                         } else $this->log($table,$uid,3,0,1,'Localization failed; There already was a localization for this language of the record!');
03210                                                                 } else $this->log($table,$uid,3,0,1,'Localization failed; Source record contained a reference to an original default record (which is strange)!');
03211                                                         } else $this->log($table,$uid,3,0,1,'Localization failed; Source record had another language than "Default" or "All" defined!');
03212                                                 } else $this->log($table,$uid,3,0,1,'Attempt to localize record that did not exist!');
03213                                         } else $this->log($table,$uid,3,0,1,'Attempt to localize record without permission');
03214                                 } else $this->log($table,$uid,3,0,1,'Sys language UID "'.$language.'" not found valid!');
03215                         } else $this->log($table,$uid,3,0,1,'Localization failed; "languageField" and "transOrigPointerField" must be defined for the table!');
03216                 }
03217         }
03218 
03230         function copyRecord_flexFormCallBack($pParams, $dsConf, $dataValue, $dataValue_ext1, $dataValue_ext2)   {
03231 
03232                         // Extract parameters:
03233                 list($table, $uid, $field) = $pParams;
03234 
03235                         // Process references and files, currently that means only the files, prepending absolute paths:
03236                 $dataValue = $this->copyRecord_procFilesRefs($dsConf, $uid, $dataValue);
03237 
03238                         // If references are set for this field, set flag so they can be corrected later (in ->remapListedDBRecords())
03239                 if ($this->isReferenceField($dsConf) && strlen($dataValue)) {
03240                         $this->registerDBList[$table][$uid][$field] = 'FlexForm_reference';
03241                 }
03242 
03243                         // Return
03244                 return array('value' => $dataValue);
03245         }
03246 
03258         function copyRecord_procFilesRefs($conf, $uid, $value)  {
03259 
03260                         // Prepend absolute paths to files:
03261                 if ($conf['type']=='group' && $conf['internal_type']=='file')   {
03262 
03263                                 // Get an array with files as values:
03264                         if ($conf['MM'])        {
03265                                 $theFileValues = array();
03266 
03267                                 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
03268                                 $dbAnalysis->start('', 'files', $conf['MM'], $uid);
03269 
03270                                 foreach($dbAnalysis->itemArray as $somekey => $someval) {
03271                                         if ($someval['id'])     {
03272                                                 $theFileValues[] = $someval['id'];
03273                                         }
03274                                 }
03275                         } else {
03276                                 $theFileValues = t3lib_div::trimExplode(',',$value,1);
03277                         }
03278 
03279                                 // Traverse this array of files:
03280                         $uploadFolder = $conf['uploadfolder'];
03281                         $dest = $this->destPathFromUploadFolder($uploadFolder);
03282                         $newValue = array();
03283 
03284                         foreach($theFileValues as $file)        {
03285                                 if (trim($file))        {
03286                                         $realFile = $dest.'/'.trim($file);
03287                                         if (@is_file($realFile))        {
03288                                                 $newValue[] = $realFile;
03289                                         }
03290                                 }
03291                         }
03292 
03293                                 // Implode the new filelist into the new value (all files have absolute paths now which means they will get copied when entering TCEmain as new values...)
03294                         $value = implode(',',$newValue);
03295                 }
03296 
03297                         // Return the new value:
03298                 return $value;
03299         }
03300 
03309         function copyPages($uid,$destPid)       {
03310 
03311                         // Initialize:
03312                 $uid = intval($uid);
03313                 $destPid = intval($destPid);
03314 
03315                         // Finding list of tables to copy.
03316                 $copyTablesArray = $this->admin ? $this->compileAdminTables() : explode(',',$this->BE_USER->groupData['tables_modify']);        // These are the tables, the user may modify
03317                 if (!strstr($this->copyWhichTables,'*'))        {               // If not all tables are allowed then make a list of allowed tables: That is the tables that figure in both allowed tables AND the copyTable-list
03318                         foreach($copyTablesArray as $k => $table)       {
03319                                 if (!$table || !t3lib_div::inList($this->copyWhichTables.',pages',$table))      {       // pages are always going...
03320                                         unset($copyTablesArray[$k]);
03321                                 }
03322                         }
03323                 }
03324                 $copyTablesArray = array_unique($copyTablesArray);
03325 
03326                         // Begin to copy pages if we're allowed to:
03327                 if ($this->admin || in_array('pages',$copyTablesArray)) {
03328 
03329                                 // Copy this page we're on. And set first-flag (this will trigger that the record is hidden if that is configured)!
03330                         $this->copySpecificPage($uid,$destPid,$copyTablesArray,1);
03331                         $theNewRootID = $this->copyMappingArray['pages'][$uid];         // This is the new ID of the rootpage of the copy-action. This ID is excluded when the list is gathered lateron
03332 
03333                                 // If we're going to copy recursively...:
03334                         if ($theNewRootID && $this->copyTree)   {
03335 
03336                                         // Get ALL subpages to copy:
03337                                 $CPtable = $this->int_pageTreeInfo(Array(), $uid, intval($this->copyTree), $theNewRootID);
03338 
03339                                         // Now copying the subpages:
03340                                 foreach($CPtable as $thePageUid => $thePagePid) {
03341                                         $newPid = $this->copyMappingArray['pages'][$thePagePid];
03342                                         if (isset($newPid))     {
03343                                                 $this->copySpecificPage($thePageUid,$newPid,$copyTablesArray);
03344                                         } else {
03345                                                 $this->log('pages',$uid,5,0,1,'Something went wrong during copying branch');
03346                                                 break;
03347                                         }
03348                                 }
03349                         }       // else the page was not copied. Too bad...
03350                 } else {
03351                         $this->log('pages',$uid,5,0,1,'Attempt to copy page without permission to this table');
03352                 }
03353         }
03354 
03364         function copySpecificPage($uid,$destPid,$copyTablesArray,$first=0)      {
03365                 global $TCA;
03366 
03367                         // Copy the page itself:
03368                 $this->copyRecord('pages',$uid,$destPid,$first);
03369                 $theNewRootID = $this->copyMappingArray['pages'][$uid]; // The new uid
03370 
03371                         // If a new page was created upon the copy operation we will proceed with all the tables ON that page:
03372                 if ($theNewRootID)      {
03373                         foreach($copyTablesArray as $table)     {
03374                                 if ($table && is_array($TCA[$table]) && $table!='pages')        {       // all records under the page is copied.
03375                                         $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, 'pid='.intval($uid).$this->deleteClause($table), '', ($TCA[$table]['ctrl']['sortby'] ? $TCA[$table]['ctrl']['sortby'].' DESC' : ''));
03376                                         while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres))     {
03377                                                 $this->copyRecord($table,$row['uid'], $theNewRootID);   // Copying each of the underlying records...
03378                                         }
03379                                 }
03380                         }
03381                 }
03382         }
03383 
03394         function versionizeRecord($table,$id,$label)    {
03395                 global $TCA;
03396 
03397                 $id = intval($id);
03398 
03399                 if ($TCA[$table] && $TCA[$table]['ctrl']['versioning'] && $id>0)        {
03400                         if ($this->doesRecordExist($table,$id,'show') && $this->doesRecordExist($table,$id,'edit'))     {
03401 
03402                                         // Select main record:
03403                                 $row = $this->recordInfo($table,$id,'pid,t3ver_id');
03404                                 if (is_array($row))     {
03405                                         if ($row['pid']>=0)     {
03406 
03407                                                         // Look for next version number:
03408                                                 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
03409                                                         't3ver_id',
03410                                                         $table,
03411                                                         '(t3ver_oid='.$id.' || uid='.$id.')'.$this->deleteClause($table),
03412                                                         '',
03413                                                         't3ver_id DESC',
03414                                                         '1'
03415                                                 );
03416                                                 list($highestVerNumber) = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
03417 
03418                                                         // Look for version number of the current:
03419                                                 $subVer = $row['t3ver_id'].'.'.($highestVerNumber+1);
03420 
03421                                                         // Set up the values to override when making a raw-copy:
03422                                                 $overrideArray = array(
03423                                                         't3ver_id' => $highestVerNumber+1,
03424                                                         't3ver_oid' => $id,
03425                                                         't3ver_label' => ($label ? $label : $subVer.' / '.date('d-m-Y H:m:s'))
03426                                                 );
03427                                                 if ($TCA[$table]['ctrl']['editlock'])   {
03428                                                         $overrideArray[$TCA[$table]['ctrl']['editlock']] = 0;
03429                                                 }
03430 
03431                                                         // Create raw-copy and return result:
03432                                                 return $this->copyRecord_raw($table,$id,-1,$overrideArray);
03433                                         } else $this->log($table,$id,0,0,1,'Record you wanted to versionize was already a version in archive (pid=-1)!');
03434                                 } else $this->log($table,$id,0,0,1,'Record you wanted to versionize didnt exist!');
03435                         } else $this->log($table,$id,0,0,1,'You didnt have correct permissions to make a new version (copy) of this record "'.$table.'" / '.$id);
03436                 } else $this->log($table,$id,0,0,1,'Versioning is not supported for this table "'.$table.'" / '.$id);
03437         }
03438 
03447         function versionizePages($uid,$label)   {
03448                 global $TCA;
03449 
03450                 $uid = intval($uid);
03451 
03452                         // Finding list of tables ALLOWED to be copied
03453                 $allowedTablesArray = $this->admin ? $this->compileAdminTables() : explode(',',$this->BE_USER->groupData['tables_modify']);     // These are the tables, the user may modify
03454 
03455                         // Make list of tables that should come along with a new version of the page:
03456                 $verTablesArray = array();
03457                 $allTables = array_keys($TCA);
03458                 foreach($allTables as $tN)      {
03459                         if ($tN!='pages' && $TCA[$tN]['ctrl']['versioning_followPages'] && ($this->admin || in_array($tN, $allowedTablesArray)))        {
03460                                 $verTablesArray[] = $tN;
03461                         }
03462                 }
03463 
03464                         // Begin to copy pages if we're allowed to:
03465                 if ($this->admin || in_array('pages',$allowedTablesArray))      {
03466 
03467                                 // Versionize this page:
03468                         $theNewRootID = $this->versionizeRecord('pages',$uid,$label);
03469                         $this->rawCopyPageContent($uid,$theNewRootID,$verTablesArray);
03470 
03471                                 // If we're going to copy recursively...:
03472                         if ($theNewRootID && $this->versionizeTree > 0) {
03473 
03474                                         // Get ALL subpages to copy:
03475                                 $CPtable = $this->int_pageTreeInfo(Array(), $uid, intval($this->versionizeTree), $theNewRootID);
03476 
03477                                         // Now copying the subpages:
03478                                 foreach($CPtable as $thePageUid => $thePagePid) {
03479                                         $newPid = $this->copyMappingArray['pages'][$thePagePid];
03480                                         if (isset($newPid))     {
03481                                                 $theNewRootID = $this->copyRecord_raw('pages',$thePageUid,$newPid);
03482                                                 $this->rawCopyPageContent($thePageUid,$theNewRootID,$verTablesArray);
03483                                         } else {
03484                                                 $this->log('pages',$uid,0,0,1,'Something went wrong during copying branch (for versioning)');
03485                                                 break;
03486                                         }
03487                                 }
03488                         }       // else the page was not copied. Too bad...
03489                 } else {
03490                         $this->log('pages',$uid,0,0,1,'Attempt to versionize page without permission to this table');
03491                 }
03492         }
03493 
03504         function rawCopyPageContent($old_pid,$new_pid,$copyTablesArray) {
03505                 global $TCA;
03506 
03507                 if ($new_pid)   {
03508                         foreach($copyTablesArray as $table)     {
03509                                 if ($table && is_array($TCA[$table]) && $table!='pages')        {       // all records under the page is copied.
03510                                         $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, 'pid='.intval($old_pid).$this->deleteClause($table));
03511                                         while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres))     {
03512                                                 $this->copyRecord_raw($table,$row['uid'],$new_pid);     // Copying each of the underlying records (method RAW)
03513                                         }
03514                                 }
03515                         }
03516                 }
03517         }
03518 
03529         function version_swap($table,$id,$swapWith,$swapContent)        {
03530                 global $TCA;
03531 
03532                 /*
03533                 Version ID swapping principles:
03534                   - Version from archive (future/past, called "swap version") will get the uid of the "t3ver_oid", the official element with uid = "t3ver_oid" will get the new versions old uid. PIDs are swapped also
03535 
03536                         uid             pid                     uid             t3ver_oid       pid
03537                 1:      13              123      -->    -13             247                     123             (Original has negated UID, and sets t3ver_oid to the final UID (which is nice to know for recovery). PID is unchanged at this point)
03538                 2:      247             -1       -->    13              13                      123             (Swap version gets original UID, correct t3ver_oid (not required for online version) and is moved to the final PID (123))
03539                 3:      -13             123      -->    247             13                      -1              (Original gets the swap versions old UID, has t3ver_oid set correctly (important) and the ver. repository PID set right.)
03540 
03541                         13 is online UID,
03542                         247 is specific versions UID
03543                         123 is the PID of the original record
03544                         -1 is the versioning repository PID
03545 
03546                         Recovery Process:
03547                                 Search for negative UID (here "-13"):
03548                                         YES: Step 1 completed, but at least step 3 didn't.
03549                                                 Search for the negativ UIDs positive (here: "13")
03550                                                         YES: Step 2 completed: Rollback: "t3ver_oid" of the -uid record shows the original UID of the swap record. Use that to change back UID and pid to -1. After that, proceed with recovery for step 1 (see below)
03551                                                         NO: Only Step 1 completed! Rollback: Just change uid "-13" to "13" and "t3ver_oid" to "13" (not important)
03552                                         NO: No problems.
03553                 */
03554 
03555                         // First, check if we may actually edit this record:
03556                 if ($this->checkRecordUpdateAccess($table,$id)) {
03557 
03558                                 // Find fields to select:
03559                         $keepFields = array();  // Keep-fields can be used for other fields than "sortby" if needed in the future...
03560                         $selectFields = array('uid','pid','t3ver_oid');
03561                         if ($TCA[$table]['ctrl']['sortby'])     {
03562                                 $selectFields[] = $keepFields[] = $TCA[$table]['ctrl']['sortby'];
03563                         }
03564                         $selectFields = array_unique($selectFields);
03565 
03566                                 // Select the two versions:
03567                         $curVersion = t3lib_BEfunc::getRecord($table,$id,implode(',',$selectFields));
03568                         $swapVersion = t3lib_BEfunc::getRecord($table,$swapWith,implode(',',$selectFields));
03569 
03570                         if (is_array($curVersion) && is_array($swapVersion))    {
03571                                 if (!is_array(t3lib_BEfunc::getRecord($table,-$id,'uid')))      {
03572 
03573                                                 // Add "keepfields"
03574                                         $swapVerBaseArray = array();
03575                                         foreach($keepFields as $fN)     {
03576                                                 $swapVerBaseArray[$fN] = $curVersion[$fN];
03577                                         }
03578 #debug($swapVerBaseArray);
03579                                                 // Check if the swapWith record really IS a version of the original!
03580                                         if ($swapVersion['pid']==-1 && $swapVersion['t3ver_oid']==$id)  {
03581 #debug($curVersion,'$curVersion');
03582 #debug($swapVersion,'$swapVersion');
03583                                                 $sqlErrors=array();
03584 
03585                                                         // Step 1:
03586                                                 $sArray = array();
03587                                                 $sArray['uid'] = -intval($id);
03588                                                 $sArray['t3ver_oid'] = intval($swapWith);
03589                                                 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table,'uid='.intval($id),$sArray);
03590                                                 if ($GLOBALS['TYPO3_DB']->sql_error())  $sqlErrors[]=$GLOBALS['TYPO3_DB']->sql_error();
03591 
03592                                                         // Step 2:
03593                                                 $sArray = $swapVerBaseArray;
03594                                                 $sArray['uid'] = intval($id);
03595                                                 $sArray['t3ver_oid'] = intval($id);
03596                                                 $sArray['pid'] = intval($curVersion['pid']);
03597                                                 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table,'uid='.intval($swapWith),$sArray);
03598                                                 if ($GLOBALS['TYPO3_DB']->sql_error())  $sqlErrors[]=$GLOBALS['TYPO3_DB']->sql_error();
03599 
03600                                                         // Step 3:
03601                                                 $sArray = array();
03602                                                 $sArray['uid'] = intval($swapWith);
03603                                                 $sArray['t3ver_oid'] = intval($id);
03604                                                 $sArray['pid'] = -1;
03605                                                 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table,'uid=-'.intval($id),$sArray);
03606                                                 if ($GLOBALS['TYPO3_DB']->sql_error())  $sqlErrors[]=$GLOBALS['TYPO3_DB']->sql_error();
03607 
03608                                                 if (!count($sqlErrors)) {
03609                                                         $this->log($table,$id,0,0,0,'Swapping successful for table "'.$table.'" uid '.$id.'=>'.$swapWith);
03610 
03611                                                                 // SWAPPING pids for subrecords:
03612                                                         if ($table=='pages' && $swapContent)    {
03613 
03614                                                                 // Collect table names that should be copied along with the tables:
03615                                                                 foreach($TCA as $tN => $tCfg)   {
03616                                                                         if ($TCA[$tN]['ctrl']['versioning_followPages'] || ($tN=='pages' && $swapContent==='ALL'))      {               // THIS produces the problem that some records might be left inside a versionized branch. Question is; Should ALL records swap pids, not only the versioning_followPages ones?
03617                                                                                 $temporaryPid = -($id+1000000);
03618 
03619                                                                                 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($tN,'pid='.intval($id),array('pid'=>$temporaryPid));
03620                                                                                 if ($GLOBALS['TYPO3_DB']->sql_error())  $sqlErrors[]=$GLOBALS['TYPO3_DB']->sql_error();
03621 
03622                                                                                 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($tN,'pid='.intval($swapWith),array('pid'=>$id));
03623                                                                                 if ($GLOBALS['TYPO3_DB']->sql_error())  $sqlErrors[]=$GLOBALS['TYPO3_DB']->sql_error();
03624 
03625                                                                                 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($tN,'pid='.intval($temporaryPid),array('pid'=>$swapWith));
03626                                                                                 if ($GLOBALS['TYPO3_DB']->sql_error())  $sqlErrors[]=$GLOBALS['TYPO3_DB']->sql_error();
03627 
03628                                                                                 if (count($sqlErrors))  {
03629                                                                                         $this->log($table,$id,0,0,1,'During Swapping: SQL errors happend: '.implode('; ',$sqlErrors));
03630                                                                                 }
03631                                                                         }
03632                                                                 }
03633                                                         }
03634                                                                 // Clear cache:
03635                                                         $this->clear_cache($table,$id);
03636 
03637                                                 } else $this->log($table,$id,0,0,1,'During Swapping: SQL errors happend: '.implode('; ',$sqlErrors));
03638                                         } else $this->log($table,$id,0,0,1,'In swap version, either pid was not -1 or the t3ver_oid didn\'t match the id of the online version as it must!');
03639                                 } else $this->log($table,$id,0,0,1,'Error: A record with a negative UID existed - that indicates some inconsistency in the database from prior versioning actions!');
03640                         } else $this->log($table,$id,0,0,1,'Error: Either online or swap version could not be selected!');
03641                 } else $this->log($table,$id,0,0,1,'Error: You cannot swap versions for a record you do not have access to edit!');
03642         }
03643 
03653         function int_pageTreeInfo($CPtable,$pid,$counter, $rootID)      {
03654                 if ($counter)   {
03655                         $addW =  !$this->admin ? ' AND '.$this->BE_USER->getPagePermsClause($this->pMap['show']) : '';
03656                         $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'pid='.intval($pid).$this->deleteClause('pages').$addW, '', 'sorting DESC');
03657                         while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres))      {
03658                                 if ($row['uid']!=$rootID)       {
03659                                         $CPtable[$row['uid']] = $pid;
03660                                         if ($counter-1) {       // If the uid is NOT the rootID of the copyaction and if we are supposed to walk further down
03661                                                 $CPtable = $this->int_pageTreeInfo($CPtable,$row['uid'],$counter-1, $rootID);
03662                                         }
03663                                 }
03664                         }
03665                 }
03666                 return $CPtable;
03667         }
03668 
03674         function compileAdminTables()   {
03675                 global $TCA;
03676                 reset ($TCA);
03677                 $listArr = array();
03678                 while (list($table)=each($TCA)) {
03679                         $listArr[]=$table;
03680                 }
03681                 return $listArr;
03682         }
03683 
03691         function fixUniqueInPid($table,$uid)    {
03692                 global $TCA;
03693                 if ($TCA[$table])       {
03694                         t3lib_div::loadTCA($table);
03695                         reset ($TCA[$table]['columns']);
03696                         $curData=$this->recordInfo($table,$uid,'*');
03697                         $newData=array();
03698                         while (list($field,$conf)=each($TCA[$table]['columns']))        {
03699                                 if ($conf['config']['type']=='input')   {
03700                                         $evalCodesArray = t3lib_div::trimExplode(',',$conf['config']['eval'],1);
03701                                         if (in_array('uniqueInPid',$evalCodesArray))    {
03702                                                 $newV = $this->getUnique($table,$field,$curData[$field],$uid,$curData['pid']);
03703                                                 if (strcmp($newV,$curData[$field]))     {
03704                                                         $newData[$field]=$newV;
03705                                                 }
03706                                         }
03707                                 }
03708                         }
03709                                 // IF there are changed fields, then update the database
03710                         if (count($newData))    {
03711                                 $this->updateDB($table,$uid,$newData);
03712                         }
03713                 }
03714         }
03715 
03727         function fixCopyAfterDuplFields($table,$uid,$prevUid,$update, $newData=array()) {
03728                 global $TCA;
03729                 if ($TCA[$table] && $TCA[$table]['ctrl']['copyAfterDuplFields'])        {
03730                         t3lib_div::loadTCA($table);
03731                         $prevData=$this->recordInfo($table,$prevUid,'*');
03732                         $theFields = t3lib_div::trimExplode(',',$TCA[$table]['ctrl']['copyAfterDuplFields'],1);
03733                         reset($theFields);
03734                         while(list(,$field)=each($theFields))   {
03735                                 if ($TCA[$table]['columns'][$field] && ($update || !isset($newData[$field])))   {
03736                                         $newData[$field]=$prevData[$field];
03737                                 }
03738                         }
03739                         if ($update && count($newData)) {
03740                                 $this->updateDB($table,$uid,$newData);
03741                         }
03742                 }
03743                 return $newData;
03744         }
03745 
03752         function extFileFields ($table) {
03753                 global $TCA;
03754                 $listArr=array();
03755                 t3lib_div::loadTCA($table);
03756                 if ($TCA[$table]['columns'])    {
03757                         reset($TCA[$table]['columns']);
03758                         while (list($field,$configArr)=each($TCA[$table]['columns']))   {
03759                                 if ($configArr['config']['type']=='group' && $configArr['config']['internal_type']=='file')     {
03760                                         $listArr[]=$field;
03761                                 }
03762                         }
03763                 }
03764                 return $listArr;
03765         }
03766 
03778         function getCopyHeader($table,$pid,$field,$value,$count,$prevTitle='')  {
03779                 global $TCA;
03780 
03781                         // Set title value to check for:
03782                 if ($count)     {
03783                         $checkTitle = $value.rtrim(' '.sprintf($this->prependLabel($table),$count));
03784                 }       else {
03785                         $checkTitle = $value;
03786                 }
03787 
03788                         // Do check:
03789                 if ($prevTitle != $checkTitle || $count<100)    {
03790                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, 'pid='.intval($pid).' AND '.$field.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($checkTitle, $table).$this->deleteClause($table), '', '', '1');
03791                         if ($GLOBALS['TYPO3_DB']->sql_num_rows($res))   {
03792                                 return $this->getCopyHeader($table,$pid,$field,$value,$count+1,$checkTitle);
03793                         }
03794                 }
03795 
03796                         // Default is to just return the current input title if no other was returned before:
03797                 return $checkTitle;
03798         }
03799 
03807         function prependLabel($table)   {
03808                 global $TCA;
03809                 if (is_object($GLOBALS['LANG']))        {
03810                         $label = $GLOBALS['LANG']->sL($TCA[$table]['ctrl']['prependAtCopy']);
03811                 } else {
03812                         list($label) = explode('|',$TCA[$table]['ctrl']['prependAtCopy']);
03813                 }
03814                 return $label;
03815         }
03816 
03824         function resolvePid($table,$pid)        {
03825                 global $TCA;
03826                 $pid=intval($pid);
03827                 if ($pid < 0)   {
03828                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('pid', $table, 'uid='.abs($pid));
03829                         $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
03830                         $pid = intval($row['pid']);
03831                 }
03832                 return $pid;
03833         }
03834 
03842         function clearPrefixFromValue($table,$value)    {
03843                 global $TCA;
03844                 $regex = sprintf(quotemeta($this->prependLabel($table)),'[0-9]*').'$';
03845                 return @ereg_replace($regex,'',$value);
03846         }
03847 
03853         function remapListedDBRecords() {
03854                 global $TCA;
03855 #debug($this->registerDBList);
03856 #debug($this->copyMappingArray_merged);
03857                 if (count($this->registerDBList))       {
03858                         reset($this->registerDBList);
03859                         while(list($table,$records)=each($this->registerDBList))        {
03860                                 t3lib_div::loadTCA($table);
03861                                 reset($records);
03862                                 while(list($uid,$fields)=each($records))        {
03863                                         $newData = array();
03864                                         $theUidToUpdate = $this->copyMappingArray_merged[$table][$uid];
03865 
03866                                         foreach($fields as $fieldName => $value)        {
03867                                                 $conf = $TCA[$table]['columns'][$fieldName]['config'];
03868 
03869                                                 switch($conf['type'])   {
03870                                                         case 'group':
03871                                                         case 'select':
03872                                                                 $vArray = $this->remapListedDBRecords_procDBRefs($conf, $value, $theUidToUpdate);
03873                                                                 if (is_array($vArray))  {
03874                                                                         $newData[$fieldName] = implode(',',$vArray);
03875                                                                 }
03876                                                         break;
03877                                                         case 'flex':
03878                                                                 if ($value=='FlexForm_reference')       {
03879                                                                         $origRecordRow = $this->recordInfo($table,$theUidToUpdate,'*'); // This will fetch the new row for the element
03880 
03881                                                                         if (is_array($origRecordRow))   {
03882 
03883                                                                                         // Get current data structure and value array:
03884                                                                                 $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $origRecordRow, $table);
03885                                                                                 $currentValueArray = t3lib_div::xml2array($origRecordRow[$fieldName]);
03886 #debug($dataStructArray);
03887 #debug($currentValueArray);
03888 #debug($origRecordRow);
03889 #debug($currentValueArray['data']);
03890                                                                                         // Do recursive processing of the XML data:
03891                                                                                 $currentValueArray['data'] = $this->checkValue_flex_procInData(
03892                                                                                                         $currentValueArray['data'],
03893                                                                                                         array(),        // Not used.
03894                                                                                                         array(),        // Not used.
03895                                                                                                         $dataStructArray,
03896                                                                                                         array($table,$theUidToUpdate,$fieldName),       // Parameters.
03897                                                                                                         'remapListedDBRecords_flexFormCallBack'
03898                                                                                                 );
03899 #debug($currentValueArray['data']);
03900                                                                                         // The return value should be compiled back into XML, ready to insert directly in the field (as we call updateDB() directly later):
03901                                                                                 if (is_array($currentValueArray['data']))       {
03902                                                                                         $newData[$fieldName] =
03903                                                                                                 '<?xml version="1.0" encoding="'.$GLOBALS['LANG']->charSet.'" standalone="yes" ?>'.chr(10).
03904                                                                                                 $this->checkValue_flexArray2Xml($currentValueArray);
03905                                                                                 }
03906                                                                         }
03907                                                                 }
03908                                                         break;
03909                                                         default:
03910                                                                 debug('Field type should not appear here: '. $conf['type']);
03911                                                         break;
03912                                                 }
03913                                         }
03914 
03915                                         if (count($newData))    {       // If any fields were changed, those fields are updated!
03916                                                 $this->updateDB($table,$theUidToUpdate,$newData);
03917 #debug($this->recordInfo($table,$theUidToUpdate,'*'),'Stored result:');
03918         //                                      debug($newData);
03919                                         }
03920                                 }
03921                         }
03922                 }
03923         }
03924 
03936         function remapListedDBRecords_flexFormCallBack($pParams, $dsConf, $dataValue, $dataValue_ext1, $dataValue_ext2) {
03937 
03938                         // Extract parameters:
03939                 list($table,$uid,$field)        = $pParams;
03940 
03941                         // If references are set for this field, set flag so they can be corrected later:
03942                 if ($this->isReferenceField($dsConf) && strlen($dataValue)) {
03943                         $vArray = $this->remapListedDBRecords_procDBRefs($dsConf, $dataValue, $uid);
03944                         if (is_array($vArray))  {
03945                                 $dataValue = implode(',',$vArray);
03946                         }
03947                 }
03948 
03949                         // Return
03950                 return array('value' => $dataValue);
03951         }
03952 
03962         function remapListedDBRecords_procDBRefs($conf, $value, $MM_localUid)   {
03963 
03964                         // Initialize variables
03965                 $set = FALSE;   // Will be set true if an upgrade should be done...
03966                 $allowedTables = $conf['type']=='group' ? $conf['allowed'] : $conf['foreign_table'].','.$conf['neg_foreign_table'];             // Allowed tables for references.
03967                 $prependName = $conf['type']=='group' ? $conf['prepend_tname'] : '';    // Table name to prepend the UID
03968                 $dontRemapTables = t3lib_div::trimExplode(',',$conf['dontRemapTablesOnCopy'],1);        // Which tables that should possibly not be remapped
03969 
03970                         // Convert value to list of references:
03971                 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
03972                 $dbAnalysis->registerNonTableValues = ($conf['type']=='select' && $conf['allowNonIdValues']) ? 1 : 0;
03973                 $dbAnalysis->start($value, $allowedTables, $conf['MM'], $MM_localUid);
03974 
03975                         // Traverse those references and map IDs:
03976                 foreach($dbAnalysis->itemArray as $k => $v)     {
03977                         $mapID = $this->copyMappingArray_merged[$v['table']][$v['id']];
03978                         if ($mapID && !in_array($v['table'],$dontRemapTables))  {
03979                                 $dbAnalysis->itemArray[$k]['id'] = $mapID;
03980                                 $set = TRUE;
03981                         }
03982                 }
03983 
03984                         // If a change has been done, set the new value(s)
03985                 if ($set)       {
03986                         if ($conf['MM'])        {
03987                                 $dbAnalysis->writeMM($conf['MM'], $theUidToUpdate, $prependName);
03988                         } else {
03989                                 $vArray = $dbAnalysis->getValueArray($prependName);
03990                                 if ($conf['type']=='select')    {
03991                                         $vArray = $dbAnalysis->convertPosNeg($vArray, $conf['foreign_table'], $conf['neg_foreign_table']);
03992                                 }
03993                                 return $vArray;
03994                         }
03995                 }
03996         }
03997 
04007         function extFileFunctions($table,$field,$filelist,$func)        {
04008                 global $TCA;
04009                 t3lib_div::loadTCA($table);
04010                 $uploadFolder = $TCA[$table]['columns'][$field]['config']['uploadfolder'];
04011                 if ($uploadFolder && trim($filelist))   {
04012                         $uploadPath = $this->destPathFromUploadFolder($uploadFolder);
04013                         $fileArray = explode(',',$filelist);
04014                         while (list(,$theFile)=each($fileArray))        {
04015                                 $theFile=trim($theFile);
04016                                 if ($theFile)   {
04017                                         switch($func)   {
04018                                                 case 'deleteAll':
04019                                                         if (@is_file($uploadPath.'/'.$theFile)) {
04020                                                                 unlink ($uploadPath.'/'.$theFile);
04021                                                         } else {
04022                                                                 $this->log($table,0,3,0,100,"Delete: Referenced file that was supposed to be deleted together with it's record didn't exist");
04023                                                         }
04024                                                 break;
04025                                         }
04026                                 }
04027                         }
04028                 }
04029         }
04030 
04039         function deleteRecord($table,$uid, $noRecordCheck)      {
04040                         // This function may not be used to delete pages-records unless the underlying records are already deleted
04041                         // If $noRecordCheck is set, then the function does not check permissions
04042                 global $TCA;
04043                 $uid = intval($uid);
04044                 if ($TCA[$table] && $uid)       {
04045                         $deleteRow = $TCA[$table]['ctrl']['delete'];
04046                         if ($noRecordCheck || $this->doesRecordExist($table,$uid,'delete'))     {
04047                                 if ($deleteRow) {
04048                                         $updateFields = array(
04049                                                 $deleteRow => 1
04050                                         );
04051 
04052                                                 // If the table is sorted, then the sorting number is set very high
04053                                         if ($TCA[$table]['ctrl']['sortby'])     {
04054                                                 $updateFields[$TCA[$table]['ctrl']['sortby']] = 1000000000;
04055                                         }
04056 
04057                                         $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid='.intval($uid), $updateFields);
04058                                 } else {
04059 
04060                                                 // Fetches all fields that holds references to files
04061                                         $fileFieldArr = $this->extFileFields($table);
04062                                         if (count($fileFieldArr))       {
04063                                                 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(implode(',',$fileFieldArr), $table, 'uid='.intval($uid));
04064                                                 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres))        {
04065                                                         $fArray = $fileFieldArr;
04066 
04067                                                         foreach($fArray as $theField)   {       // MISSING: Support for MM file relations!
04068                                                                 $this->extFileFunctions($table,$theField,$row[$theField],'deleteAll');          // This deletes files that belonged to this record.
04069                                                         }
04070                                                 } else {
04071                                                         $this->log($table,$uid,3,0,100,'Delete: Zero rows in result when trying to read filenames from record which should be deleted');
04072                                                 }
04073                                         }
04074 
04075                                         $GLOBALS['TYPO3_DB']->exec_DELETEquery($table, 'uid='.intval($uid));
04076                                 }
04077 
04078                                 if (!$GLOBALS['TYPO3_DB']->sql_error()) {
04079                                         $this->log($table,$uid,3,0,0,'');
04080                                 } else {
04081                                         $this->log($table,$uid,3,0,100,$GLOBALS['TYPO3_DB']->sql_error());
04082                                 }
04083 
04084                                 $this->clear_cache($table,$uid);        // clear cache
04085                         } else {
04086                                 $this->log($table,$uid,3,0,1,'Attempt to delete record without delete-permissions');
04087                         }
04088                 }
04089         }
04090 
04097         function deletePages($uid)      {
04098                 if ($this->doesRecordExist('pages',$uid,'delete'))      {       // If we may at all delete this page
04099                         if ($this->deleteTree)  {
04100                                 $brExist = $this->doesBranchExist('',$uid,$this->pMap['delete'],1);     // returns the branch
04101                                 if ($brExist != -1)     {       // Checks if we had permissions
04102                                         if ($this->noRecordsFromUnallowedTables($brExist.$uid)) {
04103                                                 $uidArray = explode(',',$brExist);
04104                                                 while (list(,$listUid)=each($uidArray)) {
04105                                                         if (trim($listUid))     {
04106                                                                 $this->deleteSpecificPage($listUid);
04107                                                         }
04108                                                 }
04109                                                 $this->deleteSpecificPage($uid);
04110                                         } else {
04111                                                 $this->log('pages',$uid,3,0,1,'Attempt to delete records from disallowed tables');
04112                                         }
04113                                 } else {
04114                                         $this->log('pages',$uid,3,0,1,'Attempt to delete pages in branch without permissions');
04115                                 }
04116                         } else {
04117                                 $brExist = $this->doesBranchExist('',$uid,$this->pMap['delete'],1);     // returns the branch
04118                                 if ($brExist == '')     {       // Checks if branch exists
04119                                         if ($this->noRecordsFromUnallowedTables($uid))  {
04120                                                 $this->deleteSpecificPage($uid);
04121                                         } else {
04122                                                 $this->log('pages',$uid,3,0,1,'Attempt to delete records from disallowed tables');
04123                                         }
04124                                 } else {
04125                                         $this->log('pages',$uid,3,0,1,'Attempt to delete page which has subpages');
04126                                 }
04127                         }
04128                 } else {
04129                         $this->log('pages',$uid,3,0,1,'Attempt to delete page without permissions');
04130                 }
04131         }
04132 
04139         function deleteSpecificPage($uid)       {
04140                 // internal function !!
04141                 global $TCA;
04142                 reset ($TCA);
04143                 $uid = intval($uid);
04144                 if ($uid)       {
04145                         while (list($table)=each($TCA)) {
04146                                 if ($table!='pages')    {
04147                                         $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, 'pid='.intval($uid).$this->deleteClause($table));
04148                                         while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres))     {
04149                                                 $this->deleteRecord($table,$row['uid'], 1);
04150                                         }
04151                                 }
04152                         }
04153                         $this->deleteRecord('pages',$uid, 1);
04154                 }
04155         }
04156 
04163         function noRecordsFromUnallowedTables($inList)  {
04164                 // used by the deleteFunctions to check if there are records from disallowed tables under the pages to be deleted. Return true, if permission granted
04165                 global $TCA;
04166                 reset ($TCA);
04167                 $inList = trim($this->rmComma(trim($inList)));
04168                 if ($inList && !$this->admin)   {
04169                         while (list($table) = each($TCA))       {
04170                                 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('count(*)', $table, 'pid IN ('.$inList.')');
04171                                 $count = $GLOBALS['TYPO3_DB']->sql_fetch_row($mres);
04172                                 if ($count[0] && ($this->tableReadOnly($table) || !$this->checkModifyAccessList($table)))       {
04173                                         return false;
04174                                 }
04175                         }
04176                 }
04177                 return true;
04178         }
04179 
04180 
04181 
04182 
04183 
04184 
04185 
04186 
04187 
04188 
04189 
04190 
04191 
04192 
04193 
04194 
04195 
04196 
04197 
04198 
04199 
04200 
04201 
04202 
04203 
04204 
04205         /*********************************************
04206          *
04207          * MISC FUNCTIONS
04208          *
04209          ********************************************/
04210 
04225         function getSortNumber($table,$uid,$pid)        {
04226                 global $TCA;
04227                 if ($TCA[$table] && $TCA[$table]['ctrl']['sortby'])     {
04228                         $sortRow = $TCA[$table]['ctrl']['sortby'];
04229                         if ($pid>=0)    {       // Sorting number is in the top
04230                                 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($sortRow.',pid,uid', $table, 'pid='.intval($pid).$this->deleteClause($table), '', $sortRow.' ASC', '1');          // Fetches the first record under this pid
04231                                 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {       // There was a page
04232                                         if ($row['uid']==$uid)  {       // The top record was the record it self, so we return its current sortnumber
04233                                                 return $row[$sortRow];
04234                                         }
04235                                         if ($row[$sortRow] < 1) {       // If the pages sortingnumber < 1 we must resort the records under this pid
04236                                                 $this->resorting($table,$pid,$sortRow,0);
04237                                                 return $this->sortIntervals;
04238                                         } else {
04239                                                 return floor($row[$sortRow]/2);
04240                                         }
04241                                 } else {        // No pages, so we choose the default value as sorting-number
04242                                         return $this->sortIntervals;
04243                                 }
04244                         } else {        // Sorting number is inside the list
04245                                 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($sortRow.',pid,uid', $table, 'uid='.abs($pid).$this->deleteClause($table));               // Fetches the record which is supposed to be the prev record
04246                                 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {       // There was a record
04247                                         if ($row['uid']==$uid)  {       // If the record happends to be it self
04248                                                 $sortNumber = $row[$sortRow];
04249                                         } else {
04250                                                 $subres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
04251                                                                                 $sortRow.',pid,uid',
04252                                                                                 $table,
04253                                                                                 'pid='.intval($row['pid']).' AND '.$sortRow.'>='.intval($row[$sortRow]).$this->deleteClause($table),
04254                                                                                 '',
04255                                                                                 $sortRow.' ASC',
04256                                                                                 '2'
04257                                                                         );              // Fetches the next record in order to calculate the in between sortNumber
04258                                                 if ($GLOBALS['TYPO3_DB']->sql_num_rows($subres)==2)     {       // There was a record afterwards
04259                                                         $GLOBALS['TYPO3_DB']->sql_fetch_assoc($subres);                         // Forward to the second result...
04260                                                         $subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($subres);       // There was a record afterwards
04261                                                         $sortNumber = $row[$sortRow]+ floor(($subrow[$sortRow]-$row[$sortRow])/2);      // The sortNumber is found in between these values
04262                                                         if ($sortNumber<=$row[$sortRow] || $sortNumber>=$subrow[$sortRow])      {       // The sortNumber happend NOT to be between the two surrounding numbers, so we'll have to resort the list
04263                                                                 $sortNumber = $this->resorting($table,$row['pid'],$sortRow,  $row['uid']);      // By this special param, resorting reserves and returns the sortnumber after the uid
04264                                                         }
04265                                                 } else {        // If after the last record in the list, we just add the sortInterval to the last sortvalue
04266                                                         $sortNumber = $row[$sortRow]+$this->sortIntervals;
04267                                                 }
04268                                         }
04269                                         return Array('pid' => $row['pid'], 'sortNumber' => $sortNumber);
04270                                 } else {
04271                                         $propArr = $this->getRecordProperties($table,$uid);
04272                                         $this->log($table,$uid,4,0,1,"Attempt to move record '%s' (%s) to after a non-existing record (uid=%s)",1,array($propArr['header'],$table.':'.$uid,abs($pid)),$propArr['pid']); // OK, dont insert $propArr['event_pid'] here...
04273                                         return false;   // There MUST be a page or else this cannot work
04274                                 }
04275                         }
04276                 }
04277         }
04278 
04290         function resorting($table,$pid,$sortRow, $return_SortNumber_After_This_Uid) {
04291                 global $TCA;
04292                 if ($TCA[$table] && $sortRow && $TCA[$table]['ctrl']['sortby']==$sortRow)       {
04293                         $returnVal = 0;
04294                         $intervals = $this->sortIntervals;
04295                         $i = $intervals*2;
04296 
04297                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, 'pid='.intval($pid).$this->deleteClause($table), '', $sortRow.' ASC');
04298                         while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
04299                                 $uid=intval($row['uid']);
04300                                 if ($uid)       {
04301                                         $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid='.intval($uid), array($sortRow=>$i));
04302                                         if ($uid==$return_SortNumber_After_This_Uid)    {               // This is used to return a sortingValue if the list is resorted because of inserting records inside the list and not in the top
04303                                                 $i = $i+$intervals;
04304                                                 $returnVal=$i;
04305                                         }
04306                                 } else {die ('Fatal ERROR!! No Uid at resorting.');}
04307                                 $i = $i+$intervals;
04308                         }
04309                         return $returnVal;
04310                 }
04311         }
04312 
04319         function rmComma ($input)       {
04320                 return ereg_replace(',$','',$input);
04321         }
04322 
04329         function convNumEntityToByteValue($input)       {
04330                 $token = md5(microtime());
04331                 $parts = explode($token,ereg_replace('(&#([0-9]+);)',$token.'\2'.$token,$input));
04332 
04333                 foreach($parts as $k => $v)     {
04334                         if ($k%2)       {
04335                                 $v = intval($v);
04336                                 if ($v > 32)    {       // Just to make sure that control bytes are not converted.
04337                                         $parts[$k] =chr(intval($v));
04338                                 }
04339                         }
04340                 }
04341 
04342                 return implode('',$parts);
04343         }
04344 
04351         function destPathFromUploadFolder ($folder)     {
04352                 return PATH_site.$folder;
04353         }
04354 
04362         function destNotInsideSelf ($dest,$id)  {
04363                 $loopCheck = 100;
04364                 $dest = intval($dest);
04365                 $id = intval($id);
04366                 if ($dest==$id) {
04367                         return false;
04368                 }
04369                 while ($dest!=0 && $loopCheck>0)        {
04370                         $loopCheck--;
04371                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('pid, uid', 'pages', 'uid='.intval($dest).$this->deleteClause('pages'));
04372                         if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
04373                                 if ($row['pid']==$id)   {
04374                                         return false;
04375                                 }
04376                         } else {
04377                                 return false;
04378                         }
04379                 }
04380                 return true;
04381         }
04382 
04388         function getExcludeListArray()  {
04389                 global $TCA;
04390                 $list = array();
04391                 reset($TCA);
04392                 while (list($table)=each($TCA)) {
04393                         t3lib_div::loadTCA($table);
04394                         while (list($field,$config)=each($TCA[$table]['columns']))      {
04395                                 if ($config['exclude'] && !t3lib_div::inList($this->BE_USER->groupData['non_exclude_fields'],$table.':'.$field))        {
04396                                         $list[]=$table.'-'.$field;
04397                                 }
04398                         }
04399                 }
04400                 return $list;
04401         }
04402 
04412         function doesPageHaveUnallowedTables($page_uid,$doktype)        {
04413                 global $TCA, $PAGES_TYPES;
04414                 $page_uid = intval($page_uid);
04415                 if (!$page_uid) {
04416                         return FALSE;   // Not a number. Probably a new page
04417                 }
04418 
04419                 $allowedTableList = isset($PAGES_TYPES[$doktype]['allowedTables']) ? $PAGES_TYPES[$doktype]['allowedTables'] : $PAGES_TYPES['default']['allowedTables'];
04420                 $allowedArray = t3lib_div::trimExplode(',',$allowedTableList,1);
04421                 if (strstr($allowedTableList,'*'))      {       // If all tables is OK the return true
04422                         return FALSE;   // OK...
04423                 }
04424 
04425                 reset ($TCA);
04426                 $tableList = array();
04427                 while (list($table)=each($TCA)) {
04428                         if (!in_array($table,$allowedArray))    {       // If the table is not in the allowed list, check if there are records...
04429                                 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('count(*)', $table, 'pid='.intval($page_uid));
04430                                 $count = $GLOBALS['TYPO3_DB']->sql_fetch_row($mres);
04431                                 if ($count[0])  {
04432                                         $tableList[]=$table;
04433                                 }
04434                         }
04435                 }
04436                 return implode(',',$tableList);
04437         }
04438 
04445         function deleteClause($table)   {
04446                         // Returns the proper delete-clause if any for a table from TCA
04447                 global $TCA;
04448                 if ($TCA[$table]['ctrl']['delete'])     {
04449                         return ' AND '.$table.'.'.$TCA[$table]['ctrl']['delete'].'=0';
04450                 } else {
04451                         return '';
04452                 }
04453         }
04454 
04461         function tableReadOnly($table)  {
04462                         // returns true if table is readonly
04463                 global $TCA;
04464                 return ($TCA[$table]['ctrl']['readOnly'] ? 1 : 0);
04465         }
04466 
04473         function tableAdminOnly($table) {
04474                         // returns true if table is admin-only
04475                 global $TCA;
04476                 return ($TCA[$table]['ctrl']['adminOnly'] ? 1 : 0);
04477         }
04478 
04487         function getInterfacePagePositionID($uid)       {
04488                 global $TCA;
04489                 $perms_clause = $this->BE_USER->getPagePermsClause(1);
04490                 $deleted = $TCA['pages']['ctrl']['delete'] ? 'AND A.'.$TCA['pages']['ctrl']['delete'].'=0 AND pages.'.$TCA['pages']['ctrl']['delete'].'=0 ' : '';
04491 
04492                         // This fetches a list of 1 or 2 pages, where - if 2 - the 2nd is the page BEFORE this ($uid). If 1 then the page ($uid) is at the top itself
04493                 $subres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
04494                                         'pages.uid, pages.pid',
04495                                         'pages A, pages',
04496                                         'A.pid=pages.pid AND A.uid=\''.$uid.'\'
04497                                                 '.$deleted.'
04498                                                 AND pages.sorting<=A.sorting
04499                                                 AND '.$perms_clause,
04500                                         '',
04501                                         'pages.sorting DESC',
04502                                         '2'
04503                                 );
04504                 if ($GLOBALS['TYPO3_DB']->sql_num_rows($subres)==2)     {       // There was a record before
04505                         $GLOBALS['TYPO3_DB']->sql_fetch_assoc($subres);         // forwards to the second result
04506                         $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($subres);
04507                         return -$row['uid'];
04508                 } else {
04509                         $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($subres);
04510                         return $row['pid'];
04511                 }
04512         }
04513 
04520         function isReferenceField($conf)        {
04521                 return ($conf['type']=='group' && $conf['internal_type']=='db') ||      ($conf['type']=='select' && $conf['foreign_table']);
04522         }
04523 
04530         function getTCEMAIN_TSconfig($tscPID)   {
04531                 if (!isset($this->cachedTSconfig[$tscPID]))     {
04532                         $this->cachedTSconfig[$tscPID] = $this->BE_USER->getTSConfig('TCEMAIN',t3lib_BEfunc::getPagesTSconfig($tscPID));
04533                 }
04534                 return $this->cachedTSconfig[$tscPID]['properties'];
04535         }
04536 
04544         function getTableEntries($table,$TSconfig)      {
04545                 $tA = is_array($TSconfig['table.'][$table.'.']) ? $TSconfig['table.'][$table.'.'] : array();;
04546                 $dA = is_array($TSconfig['default.']) ? $TSconfig['default.'] : array();
04547                 return t3lib_div::array_merge_recursive_overrule($dA,$tA);
04548         }
04549 
04558         function setHistory($table,$id,$logId)          {
04559                 if (isset($this->historyRecords[$table.':'.$id]))       {
04560 
04561                         list($tscPID) = t3lib_BEfunc::getTSCpid($table,$id,'');
04562                         $TSConfig = $this->getTCEMAIN_TSconfig($tscPID);
04563 
04564                         $tE = $this->getTableEntries($table,$TSConfig);
04565                         $keepEntries = strcmp($tE['history.']['keepEntries'],'') ? t3lib_div::intInRange($tE['history.']['keepEntries'],0,200) : 10;
04566                         $maxAgeSeconds = 60*60*24*(strcmp($tE['history.']['maxAgeDays'],'') ? t3lib_div::intInRange($tE['history.']['maxAgeDays'],0,200) : 7);  // one week
04567                         $this->clearHistory($table,$id,t3lib_div::intInRange($keepEntries-1,0),$maxAgeSeconds);
04568 
04569                         if ($keepEntries)       {
04570                                 $fields_values = array();
04571                                 $fields_values['history_data'] = serialize($this->historyRecords[$table.':'.$id]);
04572                                 $fields_values['fieldlist'] = implode(',',array_keys($this->historyRecords[$table.':'.$id]['newRecord']));
04573                                 $fields_values['tstamp'] = time();
04574                                 $fields_values['tablename'] = $table;
04575                                 $fields_values['recuid'] = $id;
04576                                 $fields_values['sys_log_uid'] = $logId;
04577 
04578                                 $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_history', $fields_values);
04579                         }
04580                 }
04581         }
04582 
04595         function clearHistory($table,$id,$keepEntries=10,$maxAgeSeconds=604800)         {
04596                 $tstampLimit = $maxAgeSeconds ? time()-$maxAgeSeconds : 0;
04597 
04598                 $where = '
04599                         tablename='.$GLOBALS['TYPO3_DB']->fullQuoteStr($table, 'sys_history').'
04600                         AND recuid='.intval($id).'
04601                         AND snapshot=0';
04602 
04603                 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,tstamp', 'sys_history', $where, '', 'uid DESC', intval($keepEntries).',1');
04604                 $resRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
04605                 if ($tstampLimit && intval($resRow['tstamp'])<$tstampLimit)     {
04606                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,tstamp', 'sys_history', $where.' AND tstamp<'.intval($tstampLimit), '', 'uid DESC', '1');
04607                         $resRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
04608 
04609                         $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_history', $where.' AND uid<='.intval($resRow['uid']));
04610                 } elseif (is_array($resRow)) {
04611                         $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_history', $where.' AND uid<='.intval($resRow['uid']));
04612                 }
04613         }
04614 
04643         function log($table,$recuid,$action,$recpid,$error,$details,$details_nr=0,$data=array(),$event_pid=-1,$NEWid='') {
04644                 if ($this->enableLogging)       {
04645                         $type=1;        // Type value for tce_db.php
04646                         if (!$this->storeLogMessages)   {$details='';}
04647                         return $this->BE_USER->writelog($type,$action,$error,$details_nr,$details,$data,$table,$recuid,$recpid,$event_pid,$NEWid);
04648                 }
04649         }
04650 
04657         function printLogErrorMessages($redirect)       {
04658                 $res_log = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
04659                                         '*',
04660                                         'sys_log',
04661                                         'type=1 AND userid='.intval($this->BE_USER->user['uid']).' AND tstamp='.intval($GLOBALS['EXEC_TIME']).' AND error!=0'
04662                                 );
04663                 $errorJS = array();
04664                 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res_log)) {
04665                         $log_data = unserialize($row['log_data']);
04666                         $errorJS[] = $row[error].': '.sprintf($row['details'], $log_data[0],$log_data[1],$log_data[2],$log_data[3],$log_data[4]);
04667                 }
04668 
04669                 if (count($errorJS))    {
04670                         $error_doc = t3lib_div::makeInstance('template');
04671                         $error_doc->backPath = '';
04672 
04673                         $content.= $error_doc->startPage('tce_db.php Error output');
04674 
04675                         $lines[] = '
04676                                         <tr class="bgColor5">
04677                                                 <td colspan="2" align="center"><strong>Errors:</strong></td>
04678                                         </tr>';
04679 
04680                         foreach($errorJS as $line)      {
04681                                 $lines[] = '
04682                                         <tr class="bgColor4">
04683                                                 <td valign="top"><img'.t3lib_iconWorks::skinImg('','gfx/icon_fatalerror.gif','width="18" height="16"').' alt="" /></td>
04684                                                 <td>'.htmlspecialchars($line).'</td>
04685                                         </tr>';
04686                         }
04687 
04688                         $lines[] = '
04689                                         <tr>
04690                                                 <td colspan="2" align="center"><br />'.
04691                                                 '<form action=""><input type="submit" value="Continue" onclick="'.htmlspecialchars('document.location=\''.$redirect.'\';return false;').'"></form>'.
04692                                                 '</td>
04693                                         </tr>';
04694 
04695                         $content.= '
04696                                 <br/><br/>
04697                                 <table border="0" cellpadding="1" cellspacing="1" width="300" align="center">
04698                                         '.implode('',$lines).'
04699                                 </table>';
04700 
04701                         $content.= $error_doc->endPage();
04702                         echo $content;
04703                         exit;
04704                 }
04705         }
04706 
04719         function clear_cacheCmd($cacheCmd)      {
04720                 global $TYPO3_CONF_VARS;
04721 
04722                         // Clear cache for either ALL pages or ALL tables!
04723                 switch($cacheCmd)       {
04724                         case 'pages':
04725                                 if ($this->admin || $this->BE_USER->getTSConfigVal('options.clearCache.pages')) {
04726                                         if (t3lib_extMgm::isLoaded('cms'))      {
04727                                                 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages','');
04728                                         }
04729                                 }
04730                         break;
04731                         case 'all':
04732                                 if ($this->admin || $this->BE_USER->getTSConfigVal('options.clearCache.all'))   {
04733                                         if (t3lib_extMgm::isLoaded('cms'))      {
04734                                                 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages','');
04735                                                 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pagesection','');
04736                                         }
04737                                         $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_hash','');
04738 
04739                                                 // Clearing additional cache tables:
04740                                         if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearAllCache_additionalTables']))        {
04741                                                 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearAllCache_additionalTables'] as $tableName)        {
04742                                                         if (!ereg('[^[:alnum:]_]',$tableName) && substr($tableName,-5)=='cache')        {
04743                                                                 $GLOBALS['TYPO3_DB']->exec_DELETEquery($tableName,'');
04744                                                         } else {
04745                                                                 die('Fatal Error: Trying to flush table "'.$tableName.'" with "Clear All Cache"');
04746                                                         }
04747                                                 }
04748                                         }
04749                                 }
04750                         break;
04751                         case 'temp_CACHED':
04752                                 if ($this->admin && $TYPO3_CONF_VARS['EXT']['extCache'])        {
04753                                         $this->removeCacheFiles();
04754                                 }
04755                         break;
04756                 }
04757 
04758                         // Clear cache for a page ID!
04759                 if (t3lib_div::testInt($cacheCmd))      {
04760                         if (t3lib_extMgm::isLoaded('cms'))      {
04761 
04762                                 $list_cache = array($cacheCmd);
04763 
04764                                         // Call pre-processing function for clearing of cache for page ids:
04765                                 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearPageCacheEval']))    {
04766                                         foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearPageCacheEval'] as $funcName)     {
04767                                                 $_params = array('pageIdArray' => &$list_cache, 'cacheCmd' => $cacheCmd, 'functionID' => 'clear_cacheCmd()');
04768                                                         // Returns the array of ids to clear, false if nothing should be cleared! Never an empty array!
04769                                                 t3lib_div::callUserFunction($funcName,$_params,$this);
04770                                         }
04771                                 }
04772 
04773                                         // Delete cache for selected pages:
04774                                 if (is_array($list_cache))      {
04775                                         $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages','page_id IN ('.implode(',',$GLOBALS['TYPO3_DB']->cleanIntArray($list_cache)).')');
04776                                         $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pagesection', 'page_id IN ('.implode(',',$GLOBALS['TYPO3_DB']->cleanIntArray($list_cache)).')');  // Originally, cache_pagesection was not cleared with cache_pages!
04777                                 }
04778                         }
04779                 }
04780 
04781                         // Call post processing function for clear-cache:
04782                 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc']))    {
04783                         $_params = array('cacheCmd'=>$cacheCmd);
04784                         foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc'] as $_funcRef)     {
04785                                 t3lib_div::callUserFunction($_funcRef,$_params,$this);
04786                         }
04787                 }
04788         }
04789 
04795         function removeCacheFiles()     {
04796                 $cacheFiles=t3lib_extMgm::currentCacheFiles();
04797                 $out=0;
04798                 if (is_array($cacheFiles))      {
04799                         reset($cacheFiles);
04800                         while(list(,$cfile)=each($cacheFiles))  {
04801                                 @unlink($cfile);
04802                                 clearstatcache();
04803                                 $out++;
04804                         }
04805                 }
04806 
04807                 return $out;
04808         }
04809 }
04810 
04811 
04812 
04813 
04814 /*
04815 Log messages:
04816 [action]-[details_nr.]
04817 
04818 REMEMBER to UPDATE the real messages set in tools/log/localconf_log.php
04819 
04820 0-1:    Referer host '%s' and server host '%s' did not match!
04821 1-11:   Attempt to insert record on page '%s' (%s) where this table, %s, is not allowed
04822 1-12:   Attempt to insert a record on page '%s' (%s) from table '%s' without permissions. Or non-existing page.
04823 2-1:    Attempt to modify table '%s' without permission
04824 2-2:    Attempt to modify record '%s' (%s) without permission. Or non-existing page.
04825 2-10:   Record '%s' (%s) was updated.
04826 2-12:   SQL error: '%s' (%s)
04827 2-13:   Write-file error: '%s'
04828 4-1:    Attempt to move record '%s' (%s) to after a non-existing record (uid=%s)
04829 4-2:    Moved record '%s' (%s) to page '%s' (%s)
04830 4-3:    Moved record '%s' (%s) from page '%s' (%s)
04831 4-4:    Moved record '%s' (%s) on page '%s' (%s)
04832 4-10:   Attempt to move page '%s' (%s) to inside of its own rootline (at page '%s' (%s))
04833 4-11:   Attempt to insert record on page '%s' (%s) where this table, %s, is not allowed
04834 4-12:   Attempt to insert a record on page '%s' (%s) from table '%s' without permissions. Or non-existing page.
04835 4-13:   Attempt to move record '%s' (%s) to after another record, although the table has no sorting row.
04836 4-14:   Attempt to move record '%s' (%s) without having permissions to do so
04837 5-1:    You cannot change the 'doktype' of page '%s' to the desired value.
04838 5-2:    'doktype' of page '%s' could not be changed because the page contains records from disallowed tables; %s
04839 5-3:    Too few items in the list of values. (%s)
04840 5-10:   Could not delete file '%s' (does not exist). (%s)
04841 5-11:   Copying file '%s' failed!: No destination file (%s) possible!. (%s)
04842 5-12:   Fileextension '%' not allowed. (%s)
04843 5-13:   Filesize (%s) of file '%s' exceeds limit (%s). (%s)
04844 5-14:   The destination (%s) or the source file (%s) does not exist. (%s)
04845 5-15:   Copying to file '%s' failed! (%s)
04846 5-16:   Copying file '%s' failed!: The destination path (%s) may be write protected. Please make it write enabled!. (%s)
04847 
04848 */
04849 
04850 
04851 
04852 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tcemain.php'])   {
04853         include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tcemain.php']);
04854 }
04855 ?>


Généré par Les experts TYPO3 avec  doxygen 1.4.6