00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00163
00164
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;
00203 var $checkStoredRecords_loose=1;
00204 var $sortIntervals = 256;
00205
00206 var $deleteTree = 0;
00207 var $copyTree = 0;
00208 var $versionizeTree = 0;
00209 var $neverHideAtCopy = 0;
00210 var $reverseOrder=0;
00211 var $copyWhichTables = '*';
00212 var $stripslashes_values=1;
00213 var $storeLogMessages=1;
00214 var $enableLogging=1;
00215
00216
00217 var $checkSimilar=1;
00218 var $dontProcessTransformations=0;
00219 # 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.
00220
00221 var $pMap = Array(
00222 'show' => 1,
00223 'edit' => 2,
00224 'delete' => 4,
00225 'new' => 8,
00226 'editcontent' => 16
00227 );
00228 var $defaultPermissions = array(
00229 'user' => 'show,edit,delete,new,editcontent',
00230 'group' => 'show,edit,new,editcontent',
00231 'everybody' => ''
00232 );
00233
00234
00235 var $alternativeFileName=array();
00236 var $data_disableFields=array();
00237 var $defaultValues=array();
00238 var $overrideValues=array();
00239
00240
00241
00242
00243 var $fileFunc;
00244 var $last_log_id;
00245 var $BE_USER;
00246 var $userid;
00247 var $username;
00248 var $admin;
00249 var $exclude_array;
00250
00251 var $data = Array();
00252 var $datamap = Array();
00253 var $cmd = Array();
00254 var $cmdmap = Array();
00255 var $uploadedFileArray = array();
00256
00257 var $cachedTSconfig = array();
00258 var $substNEWwithIDs = Array();
00259 var $substNEWwithIDs_table = Array();
00260 var $recUpdateAccessCache = Array();
00261 var $recInsertAccessCache = Array();
00262 var $isRecordInWebMount_Cache=array();
00263 var $isInWebMount_Cache=array();
00264 var $pageCache = Array();
00265 var $copyMappingArray = Array();
00266 var $copyMappingArray_merged = Array();
00267 var $registerDBList=array();
00268 var $dbAnalysisStore=array();
00269 var $removeFilesStore=array();
00270 var $copiedFileMap=array();
00271
00272 var $checkValue_currentRecord=array();
00273
00274
00285 function start($data,$cmd,$altUserObject='') {
00286
00287 $this->BE_USER = is_object($altUserObject) ? $altUserObject : $GLOBALS['BE_USER'];
00288 $this->userid = $this->BE_USER->user['uid'];
00289 $this->username = $this->BE_USER->user['username'];
00290 $this->admin = $this->BE_USER->user['admin'];
00291
00292
00293 $defaultPermissions = $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPermissions'];
00294 if (isset($defaultPermissions['user'])) {$this->defaultPermissions['user'] = $defaultPermissions['user'];}
00295 if (isset($defaultPermissions['group'])) {$this->defaultPermissions['group'] = $defaultPermissions['group'];}
00296 if (isset($defaultPermissions['everybody'])) {$this->defaultPermissions['everybody'] = $defaultPermissions['everybody'];}
00297
00298
00299 $this->exclude_array = ($this->admin) ? array() : $this->getExcludeListArray();
00300
00301
00302 if (is_array($data)) {
00303 reset($data);
00304 $this->datamap = $data;
00305 }
00306 if (is_array($cmd)) {
00307 reset($cmd);
00308 $this->cmdmap = $cmd;
00309 }
00310 }
00311
00318 function setMirror($mirror) {
00319 if (is_array($mirror)) {
00320 reset($mirror);
00321 while(list($table,$uid_array)=each($mirror)) {
00322 if (isset($this->datamap[$table])) {
00323 reset($uid_array);
00324 while (list($id,$uidList) = each($uid_array)) {
00325 if (isset($this->datamap[$table][$id])) {
00326 $theIdsInArray = t3lib_div::trimExplode(',',$uidList,1);
00327 while(list(,$copyToUid)=each($theIdsInArray)) {
00328 $this->datamap[$table][$copyToUid] = $this->datamap[$table][$id];
00329 }
00330 }
00331 }
00332 }
00333 }
00334 }
00335 }
00336
00343 function setDefaultsFromUserTS($userTS) {
00344 global $TCA;
00345 if (is_array($userTS)) {
00346 foreach($userTS as $k => $v) {
00347 $k = substr($k,0,-1);
00348 if ($k && is_array($v) && isset($TCA[$k])) {
00349 if (is_array($this->defaultValues[$k])) {
00350 $this->defaultValues[$k] = array_merge($this->defaultValues[$k],$v);
00351 } else {
00352 $this->defaultValues[$k] = $v;
00353 }
00354 }
00355 }
00356 }
00357 }
00358
00366 function process_uploads($postFiles) {
00367 if (is_array($postFiles)) {
00368 reset($postFiles);
00369 $subA = current($postFiles);
00370 if (is_array($subA)) {
00371 if (is_array($subA['name']) && is_array($subA['type']) && is_array($subA['tmp_name']) && is_array($subA['size'])) {
00372
00373 $this->uploadedFileArray=array();
00374
00375
00376 foreach($subA as $key => $values) {
00377 $this->process_uploads_traverseArray($this->uploadedFileArray,$values,$key);
00378 }
00379 } else {
00380 $this->uploadedFileArray=$subA;
00381 }
00382 }
00383 }
00384 }
00385
00396 function process_uploads_traverseArray(&$outputArr,$inputArr,$keyToSet) {
00397 if (is_array($inputArr)) {
00398 foreach($inputArr as $key => $value) {
00399 $this->process_uploads_traverseArray($outputArr[$key],$inputArr[$key],$keyToSet);
00400 }
00401 } else {
00402 $outputArr[$keyToSet]=$inputArr;
00403 }
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00432 function process_datamap() {
00433 global $TCA, $TYPO3_CONF_VARS;
00434
00435
00436 $hookObjectsArr = array();
00437 if (is_array ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'])) {
00438 foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'] as $classRef) {
00439 $hookObjectsArr[] = &t3lib_div::getUserObj($classRef);
00440 }
00441 }
00442
00443
00444 $orderOfTables = Array();
00445 if (isset($this->datamap['pages'])) {
00446 $orderOfTables[]='pages';
00447 }
00448 reset($this->datamap);
00449 while (list($table,) = each($this->datamap)) {
00450 if ($table!='pages') {
00451 $orderOfTables[]=$table;
00452 }
00453 }
00454
00455
00456 foreach($orderOfTables as $table) {
00457
00458
00459
00460
00461
00462
00463 $modifyAccessList = $this->checkModifyAccessList($table);
00464 if (!$modifyAccessList) {
00465 $this->log($table,$id,2,0,1,"Attempt to modify table '%s' without permission",1,array($table));
00466 }
00467 if (isset($TCA[$table]) && !$this->tableReadOnly($table) && is_array($this->datamap[$table]) && $modifyAccessList) {
00468 if ($this->reverseOrder) {
00469 $this->datamap[$table] = array_reverse($this->datamap[$table], 1);
00470 }
00471
00472
00473
00474
00475 foreach($this->datamap[$table] as $id => $incomingFieldArray) {
00476 if (is_array($incomingFieldArray)) {
00477
00478
00479 foreach($hookObjectsArr as $hookObj) {
00480 if (method_exists($hookObj, 'processDatamap_preProcessIncomingFieldArray')) {
00481 $hookObj->processDatamap_preProcessFieldArray($incomingFieldArray, $table, $id, $this);
00482 }
00483 }
00484
00485
00486
00487
00488 $recordAccess = 0;
00489 $old_pid_value = '';
00490 if (!t3lib_div::testInt($id)) {
00491 $fieldArray = $this->newFieldArray($table);
00492 if (isset($incomingFieldArray['pid'])) {
00493
00494 $pid_value = $incomingFieldArray['pid'];
00495
00496
00497 $OK = 1;
00498 if (strstr($pid_value,'NEW')) {
00499 if (substr($pid_value,0,1)=='-') {$negFlag=-1;$pid_value=substr($pid_value,1);} else {$negFlag=1;}
00500 if (isset($this->substNEWwithIDs[$pid_value])) {
00501 $old_pid_value = $pid_value;
00502 $pid_value=intval($negFlag*$this->substNEWwithIDs[$pid_value]);
00503 } else {$OK = 0;}
00504 }
00505 $pid_value = intval($pid_value);
00506
00507
00508 if ($OK) {
00509 $sortRow = $TCA[$table]['ctrl']['sortby'];
00510 if ($pid_value>=0) {
00511 if ($sortRow) {
00512 $fieldArray[$sortRow] = $this->getSortNumber($table,0,$pid_value);
00513 }
00514 $fieldArray['pid'] = $pid_value;
00515 } else {
00516 if ($sortRow) {
00517 $tempArray=$this->getSortNumber($table,0,$pid_value);
00518 $fieldArray['pid'] = $tempArray['pid'];
00519 $fieldArray[$sortRow] = $tempArray['sortNumber'];
00520 } else {
00521 $tempdata = $this->recordInfo($table,abs($pid_value),'pid');
00522 $fieldArray['pid']=$tempdata['pid'];
00523 }
00524 }
00525 }
00526 }
00527 $theRealPid = $fieldArray['pid'];
00528
00529 if ($theRealPid>=0) {
00530 $recordAccess = $this->checkRecordInsertAccess($table,$theRealPid);
00531 } else {
00532 debug('Internal ERROR: pid should not be less than zero!');
00533 }
00534 $status = 'new';
00535 } else {
00536 $fieldArray = Array();
00537 $recordAccess = $this->checkRecordUpdateAccess($table,$id);
00538 if (!$recordAccess) {
00539 $propArr = $this->getRecordProperties($table,$id);
00540 $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']);
00541 } else {
00542 $recordAccess = $this->BE_USER->recordEditAccessInternals($table,$id);
00543 if (!$recordAccess) {
00544 $propArr = $this->getRecordProperties($table,$id);
00545 $this->log($table,$id,2,0,1,"recordEditAccessInternals() check failed. [".$this->BE_USER->errorMsg."]",2,array($propArr['header'],$table.':'.$id),$propArr['event_pid']);
00546 } else {
00547 $tempdata = $this->recordInfo($table,$id,'pid');
00548 $theRealPid = $tempdata['pid'];
00549 }
00550 }
00551 $status = 'update';
00552 }
00553
00554
00555
00556
00557 if ($recordAccess) {
00558
00559 list($tscPID) = t3lib_BEfunc::getTSCpid($table,$id,$old_pid_value ? $old_pid_value : $fieldArray['pid']);
00560 $TSConfig = $this->getTCEMAIN_TSconfig($tscPID);
00561 if ($status=='new' && $table=='pages' && is_array($TSConfig['permissions.'])) {
00562 $fieldArray = $this->setTSconfigPermissions($fieldArray,$TSConfig['permissions.']);
00563 }
00564
00565 $fieldArray = $this->fillInFieldArray($table,$id,$fieldArray,$incomingFieldArray,$theRealPid,$status,$tscPID);
00566
00567
00568
00569 $fieldArray = $this->overrideFieldArray($table,$fieldArray);
00570
00571
00572 if ($status=='new') {
00573 if ($TCA[$table]['ctrl']['crdate']) {
00574 $fieldArray[$TCA[$table]['ctrl']['crdate']]=time();
00575 }
00576 if ($TCA[$table]['ctrl']['cruser_id']) {
00577 $fieldArray[$TCA[$table]['ctrl']['cruser_id']]=$this->userid;
00578 }
00579 } elseif ($this->checkSimilar) {
00580 $fieldArray = $this->compareFieldArrayWithCurrentAndUnset($table,$id,$fieldArray);
00581 }
00582 if ($TCA[$table]['ctrl']['tstamp']) {
00583 $fieldArray[$TCA[$table]['ctrl']['tstamp']]=time();
00584 }
00585
00586
00587 foreach($hookObjectsArr as $hookObj) {
00588 if (method_exists($hookObj, 'processDatamap_postProcessFieldArray')) {
00589 $hookObj->processDatamap_postProcessFieldArray($status, $table, $id, $fieldArray, $this);
00590 }
00591 }
00592
00593
00594
00595 if (is_array($fieldArray)) {
00596 if ($status=='new') {
00597
00598 $this->insertDB($table,$id,$fieldArray);
00599 } else {
00600 $this->updateDB($table,$id,$fieldArray);
00601 }
00602 }
00603 }
00604 }
00605 }
00606 }
00607 }
00608 $this->dbAnalysisStoreExec();
00609 $this->removeRegisteredFiles();
00610 }
00611
00625 function fillInFieldArray($table,$id,$fieldArray,$incomingFieldArray,$realPid,$status,$tscPID) {
00626 global $TCA;
00627
00628
00629 t3lib_div::loadTCA($table);
00630 unset($originalLanguageRecord);
00631 unset($originalLanguage_diffStorage);
00632 $diffStorageFlag = FALSE;
00633
00634
00635 if (strstr($id,'NEW')) {
00636 $currentRecord = $checkValueRecord = $fieldArray;
00637
00638
00639
00640 if (is_array($incomingFieldArray) && is_array($checkValueRecord)) {
00641 $checkValueRecord = t3lib_div::array_merge_recursive_overrule($checkValueRecord, $incomingFieldArray);
00642 }
00643 } else {
00644 $currentRecord = $checkValueRecord = $this->recordInfo($table,$id,'*');
00645
00646
00647 if (is_array($currentRecord)
00648 && $TCA[$table]['ctrl']['transOrigDiffSourceField']
00649 && $TCA[$table]['ctrl']['languageField']
00650 && $currentRecord[$TCA[$table]['ctrl']['languageField']] > 0
00651 && $TCA[$table]['ctrl']['transOrigPointerField']
00652 && intval($currentRecord[$TCA[$table]['ctrl']['transOrigPointerField']]) > 0) {
00653
00654 $lookUpTable = $TCA[$table]['ctrl']['transOrigPointerTable'] ? $TCA[$table]['ctrl']['transOrigPointerTable'] : $table;
00655 $originalLanguageRecord = $this->recordInfo($lookUpTable,$currentRecord[$TCA[$table]['ctrl']['transOrigPointerField']],'*');
00656 $originalLanguage_diffStorage = unserialize($currentRecord[$TCA[$table]['ctrl']['transOrigDiffSourceField']]);
00657 }
00658 }
00659 $this->checkValue_currentRecord = $checkValueRecord;
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 foreach($incomingFieldArray as $field => $fieldValue) {
00671 if (!in_array($table.'-'.$field, $this->exclude_array) && !$this->data_disableFields[$table][$id][$field]) {
00672
00673
00674 $languageDeny = $TCA[$table]['ctrl']['languageField'] && !strcmp($TCA[$table]['ctrl']['languageField'], $field) && !$this->BE_USER->checkLanguageAccess($fieldValue);
00675
00676 if (!$languageDeny) {
00677
00678 if ($this->stripslashes_values) {
00679 if (is_array($fieldValue)) {
00680 t3lib_div::stripSlashesOnArray($fieldValue);
00681 } else $fieldValue = stripslashes($fieldValue);
00682 }
00683
00684 switch ($field) {
00685 case 'uid':
00686 case 'pid':
00687
00688 break;
00689 case 'perms_userid':
00690 case 'perms_groupid':
00691 case 'perms_user':
00692 case 'perms_group':
00693 case 'perms_everybody':
00694
00695 if ($table=='pages' && ($this->admin || $status=='new' || $this->pageInfo($id,'perms_userid')==$this->userid) ) {
00696 $value=intval($fieldValue);
00697 switch($field) {
00698 case 'perms_userid':
00699 $fieldArray[$field]=$value;
00700 break;
00701 case 'perms_groupid':
00702 $fieldArray[$field]=$value;
00703 break;
00704 default:
00705 if ($value>=0 && $value<pow(2,5)) {
00706 $fieldArray[$field]=$value;
00707 }
00708 break;
00709 }
00710 }
00711 break;
00712 case 't3ver_oid':
00713 case 't3ver_id':
00714
00715 break;
00716 default:
00717 if (isset($TCA[$table]['columns'][$field])) {
00718
00719 $res = $this->checkValue($table,$field,$fieldValue,$id,$status,$realPid,$tscPID);
00720 if (isset($res['value'])) {
00721 $fieldArray[$field]=$res['value'];
00722
00723
00724 if ($TCA[$table]['ctrl']['transOrigDiffSourceField']) {
00725 $originalLanguage_diffStorage[$field] = $originalLanguageRecord[$field];
00726 $diffStorageFlag = TRUE;
00727 }
00728 }
00729 }
00730
00731
00732 break;
00733 }
00734 }
00735 }
00736 }
00737
00738
00739 if ($diffStorageFlag && !isset($fieldArray[$TCA[$table]['ctrl']['transOrigDiffSourceField']])) {
00740 $fieldArray[$TCA[$table]['ctrl']['transOrigDiffSourceField']] = serialize($originalLanguage_diffStorage);
00741 }
00742
00743
00744 $types_fieldConfig = t3lib_BEfunc::getTCAtypes($table,$currentRecord);
00745 $theTypeString = t3lib_BEfunc::getTCAtypeValue($table,$currentRecord);
00746 if (is_array($types_fieldConfig)) {
00747 reset($types_fieldConfig);
00748 while(list(,$vconf) = each($types_fieldConfig)) {
00749
00750 $eFile = t3lib_parsehtml_proc::evalWriteFile($vconf['spec']['static_write'],array_merge($currentRecord,$fieldArray));
00751
00752
00753 if (!$this->dontProcessTransformations) {
00754 if (isset($fieldArray[$vconf['field']])) {
00755
00756 switch((string)$incomingFieldArray['_TRANSFORM_'.$vconf['field']]) {
00757 case 'RTE':
00758 $RTEsetup = $this->BE_USER->getTSConfig('RTE',t3lib_BEfunc::getPagesTSconfig($tscPID));
00759 $thisConfig = t3lib_BEfunc::RTEsetup($RTEsetup['properties'],$table,$vconf['field'],$theTypeString);
00760
00761
00762 $RTErelPath = is_array($eFile) ? dirname($eFile['relEditFile']) : '';
00763
00764
00765 $RTEobj = &t3lib_BEfunc::RTEgetObj();
00766 if (is_object($RTEobj)) {
00767 $fieldArray[$vconf['field']] = $RTEobj->transformContent('db',$fieldArray[$vconf['field']],$table,$vconf['field'],$currentRecord,$vconf['spec'],$thisConfig,$RTErelPath,$currentRecord['pid']);
00768 } else {
00769 debug('NO RTE OBJECT FOUND!');
00770 }
00771 break;
00772 }
00773 }
00774 }
00775
00776
00777 if (is_array($eFile)) {
00778 $mixedRec = array_merge($currentRecord,$fieldArray);
00779 $SW_fileContent = t3lib_div::getUrl($eFile['editFile']);
00780 $parseHTML = t3lib_div::makeInstance('t3lib_parsehtml_proc');
00781 $parseHTML->init('','');
00782
00783 $eFileMarker = $eFile['markerField']&&trim($mixedRec[$eFile['markerField']]) ? trim($mixedRec[$eFile['markerField']]) : '###TYPO3_STATICFILE_EDIT###';
00784 $insertContent = str_replace($eFileMarker,'',$mixedRec[$eFile['contentField']]);
00785
00786 $SW_fileNewContent = $parseHTML->substituteSubpart($SW_fileContent, $eFileMarker, chr(10).$insertContent.chr(10), 1, 1);
00787 t3lib_div::writeFile($eFile['editFile'],$SW_fileNewContent);
00788
00789
00790 if (!strstr($id,'NEW') && $eFile['statusField']) {
00791 $GLOBALS['TYPO3_DB']->exec_UPDATEquery(
00792 $table,
00793 'uid='.intval($id),
00794 array(
00795 $eFile['statusField'] => $eFile['relEditFile'].' updated '.date('d-m-Y H:i:s').', bytes '.strlen($mixedRec[$eFile['contentField']])
00796 )
00797 );
00798 }
00799 } elseif ($eFile && is_string($eFile)) {
00800 $this->log($insertTable,$id,2,0,1,"Write-file error: '%s'",13,array($eFile),$realPid);
00801 }
00802 }
00803 }
00804
00805 return $fieldArray;
00806 }
00807
00816 function checkModifyAccessList($table) {
00817 $res = ($this->admin || (!$this->tableAdminOnly($table) && t3lib_div::inList($this->BE_USER->groupData['tables_modify'],$table)));
00818 return $res;
00819 }
00820
00828 function isRecordInWebMount($table,$id) {
00829 if (!isset($this->isRecordInWebMount_Cache[$table.':'.$id])) {
00830 $recP=$this->getRecordProperties($table,$id);
00831 $this->isRecordInWebMount_Cache[$table.':'.$id]=$this->isInWebMount($recP['event_pid']);
00832 }
00833 return $this->isRecordInWebMount_Cache[$table.':'.$id];
00834 }
00835
00842 function isInWebMount($pid) {
00843 if (!isset($this->isInWebMount_Cache[$pid])) {
00844 $this->isInWebMount_Cache[$pid]=$this->BE_USER->isInWebMount($pid);
00845 }
00846
00847 return $this->isInWebMount_Cache[$pid];
00848 }
00849
00859 function checkRecordUpdateAccess($table,$id) {
00860 global $TCA;
00861 $res = 0;
00862 if ($TCA[$table] && intval($id)>0) {
00863 if (isset($this->recUpdateAccessCache[$table][$id])) {
00864 return $this->recUpdateAccessCache[$table][$id];
00865
00866 } elseif ($this->doesRecordExist($table,$id,'edit')) {
00867 $res = 1;
00868 }
00869 $this->recUpdateAccessCache[$table][$id]=$res;
00870 }
00871 return $res;
00872 }
00873
00884 function checkRecordInsertAccess($insertTable,$pid,$action=1) {
00885 global $TCA;
00886 $res = 0;
00887 $pid = intval($pid);
00888 if ($pid>=0) {
00889 if (isset($this->recInsertAccessCache[$insertTable][$pid])) {
00890 return $this->recInsertAccessCache[$insertTable][$pid];
00891 } else {
00892
00893 if ( (!$pid && $this->admin) || $this->doesRecordExist('pages',$pid,($insertTable=='pages'?$this->pMap['new']:$this->pMap['editcontent'])) ) {
00894 if ($this->isTableAllowedForThisPage($pid, $insertTable)) {
00895 $res = 1;
00896 $this->recInsertAccessCache[$insertTable][$pid]=$res;
00897 } else {
00898 $propArr = $this->getRecordProperties('pages',$pid);
00899 $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']);
00900 }
00901 } else {
00902 $propArr = $this->getRecordProperties('pages',$pid);
00903 $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']);
00904 }
00905 }
00906 }
00907 return $res;
00908 }
00909
00920 function isTableAllowedForThisPage($page_uid, $checkTable) {
00921 global $TCA, $PAGES_TYPES;
00922 $page_uid = intval($page_uid);
00923
00924
00925 if (($TCA[$checkTable]['ctrl']['rootLevel'] xor !$page_uid) && $TCA[$checkTable]['ctrl']['rootLevel']!=-1 && $checkTable!='pages') {
00926 return false;
00927 }
00928
00929
00930 if (!$page_uid) {
00931 if ($this->admin) {
00932 return true;
00933 }
00934 } else {
00935
00936 $doktype = $this->pageInfo($page_uid,'doktype');
00937 $allowedTableList = isset($PAGES_TYPES[$doktype]['allowedTables']) ? $PAGES_TYPES[$doktype]['allowedTables'] : $PAGES_TYPES['default']['allowedTables'];
00938 $allowedArray = t3lib_div::trimExplode(',',$allowedTableList,1);
00939 if (strstr($allowedTableList,'*') || in_array($checkTable,$allowedArray)) {
00940 return true;
00941 }
00942 }
00943 }
00944
00955 function doesRecordExist($table,$id,$perms) {
00956 global $TCA;
00957
00958 $res = 0;
00959 $id = intval($id);
00960
00961
00962 if (!t3lib_div::testInt($perms)) {
00963 if ($table!='pages') {
00964 switch($perms) {
00965 case 'edit':
00966 case 'delete':
00967 case 'new':
00968 $perms = 'editcontent';
00969 break;
00970 }
00971 }
00972 $perms = intval($this->pMap[$perms]);
00973 } else {
00974 $perms = intval($perms);
00975 }
00976
00977 if (!$perms) {debug('Internal ERROR: no permissions to check for non-admin user.');}
00978
00979
00980
00981 if (is_array($TCA[$table]) && $id>0 && ($this->isRecordInWebMount($table,$id) || $this->admin)) {
00982 if ($table != 'pages') {
00983
00984
00985 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,pid', $table, 'uid='.intval($id).$this->deleteClause($table));
00986 $output = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres);
00987 t3lib_BEfunc::fixVersioningPid($table,$output);
00988
00989
00990 if (is_array($output)) {
00991
00992
00993 $mres = $this->doesRecordExist_pageLookUp($output['pid'], $perms);
00994 $pageRec = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres);
00995
00996
00997 if (is_array($pageRec) || (!$output['pid'] && $this->admin)) {
00998 return TRUE;
00999 }
01000 }
01001 return FALSE;
01002 } else {
01003 $mres = $this->doesRecordExist_pageLookUp($id, $perms);
01004 return $GLOBALS['TYPO3_DB']->sql_num_rows($mres);
01005 }
01006 }
01007 }
01008
01018 function doesRecordExist_pageLookUp($id, $perms) {
01019 global $TCA;
01020
01021 return $GLOBALS['TYPO3_DB']->exec_SELECTquery(
01022 'uid',
01023 'pages',
01024 'uid='.intval($id).
01025 $this->deleteClause('pages').
01026 ($perms && !$this->admin ? ' AND '.$this->BE_USER->getPagePermsClause($perms) : '').
01027 (!$this->admin && $TCA['pages']['ctrl']['editlock'] && ($perms & (2+4+16)) ? ' AND '.$TCA['pages']['ctrl']['editlock'].'=0':'')
01028 );
01029 }
01030
01044 function doesBranchExist($inList,$pid,$perms, $recurse) {
01045 global $TCA;
01046 $pid = intval($pid);
01047 $perms = intval($perms);
01048 if ($pid>=0) {
01049 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
01050 'uid, perms_userid, perms_groupid, perms_user, perms_group, perms_everybody',
01051 'pages',
01052 'pid='.intval($pid).$this->deleteClause('pages'),
01053 '',
01054 'sorting'
01055 );
01056 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
01057 if ($this->admin || $this->BE_USER->doesUserHaveAccess($row,$perms)) {
01058 $inList.=$row['uid'].',';
01059 if ($recurse) {
01060 $inList = $this->doesBranchExist($inList, $row['uid'], $perms, $recurse);
01061 if ($inList == -1) {return -1;}
01062 }
01063 } else {
01064 return -1;
01065 }
01066 }
01067 }
01068 return $inList;
01069 }
01070
01079 function pageInfo($id,$field) {
01080 if (!isset($this->pageCache[$id])) {
01081 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'uid='.intval($id));
01082 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
01083 $this->pageCache[$id] = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
01084 }
01085 $GLOBALS['TYPO3_DB']->sql_free_result($res);
01086 }
01087 return $this->pageCache[$id][$field];
01088 }
01089
01099 function recordInfo($table,$id,$fieldList) {
01100 global $TCA;
01101 if (is_array($TCA[$table])) {
01102 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fieldList, $table, 'uid='.intval($id));
01103 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
01104 return $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
01105 }
01106 }
01107 }
01108
01116 function getRecordProperties($table,$id) {
01117 $row = ($table=='pages' && !$id) ? array('title'=>'[root-level]', 'uid' => 0, 'pid' => 0) :$this->recordInfo($table,$id,'*');
01118 t3lib_BEfunc::fixVersioningPid($table,$row);
01119 return $this->getRecordPropertiesFromRow($table,$row);
01120 }
01121
01129 function getRecordPropertiesFromRow($table,$row) {
01130 global $TCA;
01131 if ($TCA[$table]) {
01132 $out = array(
01133 'header' => $row[$TCA[$table]['ctrl']['label']],
01134 'pid' => $row['pid'],
01135 'event_pid' => ($table=='pages'?$row['uid']:$row['pid'])
01136 );
01137 return $out;
01138 }
01139 }
01140
01148 function setTSconfigPermissions($fieldArray,$TSConfig_p) {
01149 if (strcmp($TSConfig_p['userid'],'')) $fieldArray['perms_userid']=intval($TSConfig_p['userid']);
01150 if (strcmp($TSConfig_p['groupid'],'')) $fieldArray['perms_groupid']=intval($TSConfig_p['groupid']);
01151 if (strcmp($TSConfig_p['user'],'')) $fieldArray['perms_user']=t3lib_div::testInt($TSConfig_p['user']) ? $TSConfig_p['user'] : $this->assemblePermissions($TSConfig_p['user']);
01152 if (strcmp($TSConfig_p['group'],'')) $fieldArray['perms_group']=t3lib_div::testInt($TSConfig_p['group']) ? $TSConfig_p['group'] : $this->assemblePermissions($TSConfig_p['group']);
01153 if (strcmp($TSConfig_p['everybody'],'')) $fieldArray['perms_everybody']=t3lib_div::testInt($TSConfig_p['everybody']) ? $TSConfig_p['everybody'] : $this->assemblePermissions($TSConfig_p['everybody']);
01154
01155 return $fieldArray;
01156 }
01157
01164 function newFieldArray($table) {
01165 global $TCA;
01166 t3lib_div::loadTCA($table);
01167 $fieldArray=Array();
01168 if (is_array($TCA[$table]['columns'])) {
01169 reset ($TCA[$table]['columns']);
01170 while (list($field,$content)=each($TCA[$table]['columns'])) {
01171 if (isset($this->defaultValues[$table][$field])) {
01172 $fieldArray[$field] = $this->defaultValues[$table][$field];
01173 } elseif (isset($content['config']['default'])) {
01174 $fieldArray[$field] = $content['config']['default'];
01175 }
01176 }
01177 }
01178 if ($table=='pages') {
01179 $fieldArray['perms_userid'] = $this->userid;
01180 $fieldArray['perms_groupid'] = intval($this->BE_USER->firstMainGroup);
01181 $fieldArray['perms_user'] = $this->assemblePermissions($this->defaultPermissions['user']);
01182 $fieldArray['perms_group'] = $this->assemblePermissions($this->defaultPermissions['group']);
01183 $fieldArray['perms_everybody'] = $this->assemblePermissions($this->defaultPermissions['everybody']);
01184 }
01185 return $fieldArray;
01186 }
01187
01195 function overrideFieldArray($table,$data) {
01196 if (is_array($this->overrideValues[$table])) {
01197 $data = array_merge($data,$this->overrideValues[$table]);
01198 }
01199 return $data;
01200 }
01201
01208 function assemblePermissions($string) {
01209 $keyArr = t3lib_div::trimExplode(',',$string,1);
01210 $value=0;
01211 while(list(,$key)=each($keyArr)) {
01212 if ($key && isset($this->pMap[$key])) {
01213 $value |= $this->pMap[$key];
01214 }
01215 }
01216 return $value;
01217 }
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01258 function checkValue($table,$field,$value,$id,$status,$realPid,$tscPID) {
01259 global $TCA, $PAGES_TYPES;
01260 t3lib_div::loadTCA($table);
01261
01262 $res = Array();
01263 $recFID = $table.':'.$id.':'.$field;
01264
01265
01266 if ($table=='pages' && $field=='doktype') {
01267
01268 if (! ($this->admin || t3lib_div::inList($this->BE_USER->groupData['pagetypes_select'],$value))) {
01269 $propArr = $this->getRecordProperties($table,$id);
01270 $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']);
01271 return $res;
01272 };
01273 if ($status=='update') {
01274
01275 $onlyAllowedTables = isset($PAGES_TYPES[$value]['onlyAllowedTables']) ? $PAGES_TYPES[$value]['onlyAllowedTables'] : $PAGES_TYPES['default']['onlyAllowedTables'];
01276 if ($onlyAllowedTables) {
01277 $theWrongTables = $this->doesPageHaveUnallowedTables($id,$value);
01278 if ($theWrongTables) {
01279 $propArr = $this->getRecordProperties($table,$id);
01280 $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']);
01281 return $res;
01282 }
01283 }
01284 }
01285 }
01286
01287
01288 $curValueRec = $this->recordInfo($table,$id,$field);
01289 $curValue = $curValueRec[$field];
01290
01291
01292 $tcaFieldConf = $TCA[$table]['columns'][$field]['config'];
01293
01294
01295 $res = $this->checkValue_SW($res,$value,$tcaFieldConf,$table,$id,$curValue,$status,$realPid,$recFID,$field,$this->uploadedFileArray[$table][$id][$field],$tscPID);
01296
01297 return $res;
01298 }
01299
01318 function checkValue_SW($res,$value,$tcaFieldConf,$table,$id,$curValue,$status,$realPid,$recFID,$field,$uploadedFiles,$tscPID) {
01319
01320 $PP = array($table,$id,$curValue,$status,$realPid,$recFID,$tscPID);
01321
01322 switch ($tcaFieldConf['type']) {
01323 case 'text':
01324 case 'passthrough':
01325 case 'user':
01326 $res['value'] = $value;
01327 break;
01328 case 'input':
01329 $res = $this->checkValue_input($res,$value,$tcaFieldConf,$PP,$field);
01330 break;
01331 case 'check':
01332 $res = $this->checkValue_check($res,$value,$tcaFieldConf,$PP);
01333 break;
01334 case 'radio':
01335 $res = $this->checkValue_radio($res,$value,$tcaFieldConf,$PP);
01336 break;
01337 case 'group':
01338 case 'select':
01339 $res = $this->checkValue_group_select($res,$value,$tcaFieldConf,$PP,$uploadedFiles,$field);
01340 break;
01341 case 'flex':
01342 if ($field) {
01343 $res = $this->checkValue_flex($res,$value,$tcaFieldConf,$PP,$uploadedFiles,$field);
01344 }
01345 break;
01346 default:
01347 #debug(array($tcaFieldConf,$res,$value),'NON existing field type:');
01348 break;
01349 }
01350
01351 return $res;
01352 }
01353
01364 function checkValue_input($res,$value,$tcaFieldConf,$PP,$field='') {
01365 list($table,$id,$curValue,$status,$realPid,$recFID) = $PP;
01366
01367
01368 if (intval($tcaFieldConf['max'])>0) {$value = substr($value,0,intval($tcaFieldConf['max']));}
01369
01370
01371 if ($tcaFieldConf['range'] && $value!=$tcaFieldConf['checkbox']) {
01372 if (isset($tcaFieldConf['range']['upper'])&&$value>$tcaFieldConf['range']['upper']) {$value=$tcaFieldConf['range']['upper'];}
01373 if (isset($tcaFieldConf['range']['lower'])&&$value<$tcaFieldConf['range']['lower']) {$value=$tcaFieldConf['range']['lower'];}
01374 }
01375
01376
01377 $evalCodesArray = t3lib_div::trimExplode(',',$tcaFieldConf['eval'],1);
01378 $res = $this->checkValue_input_Eval($value,$evalCodesArray,$tcaFieldConf['is_in']);
01379
01380
01381 if ($field && $realPid>=0) {
01382 if ($res['value'] && in_array('uniqueInPid',$evalCodesArray)) {
01383 $res['value'] = $this->getUnique($table,$field,$res['value'],$id,$realPid);
01384 }
01385 if ($res['value'] && in_array('unique',$evalCodesArray)) {
01386 $res['value'] = $this->getUnique($table,$field,$res['value'],$id);
01387 }
01388 }
01389
01390 return $res;
01391 }
01392
01402 function checkValue_check($res,$value,$tcaFieldConf,$PP) {
01403 list($table,$id,$curValue,$status,$realPid,$recFID) = $PP;
01404
01405 $itemC = count($tcaFieldConf['items']);
01406 if (!$itemC) {$itemC=1;}
01407 $maxV = pow(2,$itemC);
01408
01409 if ($value<0) {$value=0;}
01410 if ($value>$maxV) {$value=$maxV;}
01411 $res['value'] = $value;
01412
01413 return $res;
01414 }
01415
01425 function checkValue_radio($res,$value,$tcaFieldConf,$PP) {
01426 list($table,$id,$curValue,$status,$realPid,$recFID) = $PP;
01427
01428 if (is_array($tcaFieldConf['items'])) {
01429 foreach($tcaFieldConf['items'] as $set) {
01430 if (!strcmp($set[1],$value)) {
01431 $res['value'] = $value;
01432 break;
01433 }
01434 }
01435 }
01436
01437 return $res;
01438 }
01439
01451 function checkValue_group_select($res,$value,$tcaFieldConf,$PP,$uploadedFiles,$field) {
01452 list($table,$id,$curValue,$status,$realPid,$recFID) = $PP;
01453
01454
01455 if (is_array($value)) {
01456 $value = implode(',',$value);
01457 }
01458
01459
01460
01461 $value = $this->convNumEntityToByteValue($value);
01462
01463
01464 $valueArray = $this->checkValue_group_select_explodeSelectGroupValue($value);
01465
01466
01467 if (!$tcaFieldConf['multiple']) {
01468 $valueArray = array_unique($valueArray);
01469 }
01470
01471
01472
01473
01474
01475 if ($tcaFieldConf['type']=='select' && $tcaFieldConf['authMode']) {
01476 $preCount = count($valueArray);
01477 foreach($valueArray as $kk => $vv) {
01478 if (!$this->BE_USER->checkAuthMode($table,$field,$vv,$tcaFieldConf['authMode'])) {
01479 unset($valueArray[$kk]);
01480 }
01481 }
01482
01483
01484 if ($preCount && !count($valueArray)) {
01485 return array();
01486 }
01487 }
01488
01489
01490 if ($tcaFieldConf['type']=='group') {
01491 switch($tcaFieldConf['internal_type']) {
01492 case 'file':
01493 $valueArray = $this->checkValue_group_select_file(
01494 $valueArray,
01495 $tcaFieldConf,
01496 $curValue,
01497 $uploadedFiles,
01498 $status,
01499 $table,
01500 $id,
01501 $recFID
01502 );
01503 break;
01504 case 'db':
01505 $valueArray = $this->checkValue_group_select_processDBdata($valueArray,$tcaFieldConf,$id,$status,'group');
01506 break;
01507 }
01508 }
01509
01510 if ($tcaFieldConf['type']=='select' && $tcaFieldConf['foreign_table']) {
01511 $valueArray = $this->checkValue_group_select_processDBdata($valueArray,$tcaFieldConf,$id,$status,'select');
01512 }
01513
01514
01515
01516
01517
01518 $valueArrayC = count($valueArray);
01519 $minI = isset($tcaFieldConf['minitems']) ? intval($tcaFieldConf['minitems']):0;
01520
01521
01522 $maxI = isset($tcaFieldConf['maxitems']) ? intval($tcaFieldConf['maxitems']):1;
01523 if ($valueArrayC > $maxI) {$valueArrayC=$maxI;}
01524
01525
01526 $newVal=array();
01527 foreach($valueArray as $nextVal) {
01528 if ($valueArrayC==0) {break;}
01529 $valueArrayC--;
01530 $newVal[]=$nextVal;
01531 }
01532 $res['value'] = implode(',',$newVal);
01533
01534 return $res;
01535 }
01536
01551 function checkValue_group_select_file($valueArray,$tcaFieldConf,$curValue,$uploadedFileArray,$status,$table,$id,$recFID) {
01552
01553
01554 if (is_array($uploadedFileArray) &&
01555 $uploadedFileArray['name'] &&
01556 strcmp($uploadedFileArray['tmp_name'],'none')) {
01557 $valueArray[]=$uploadedFileArray['tmp_name'];
01558 $this->alternativeFileName[$uploadedFileArray['tmp_name']] = $uploadedFileArray['name'];
01559 }
01560
01561
01562 if (!$this->fileFunc) {
01563 $this->fileFunc = t3lib_div::makeInstance('t3lib_basicFileFunctions');
01564 $this->include_filefunctions=1;
01565 }
01566
01567 $all_files = Array();
01568 $all_files['webspace']['allow'] = $tcaFieldConf['allowed'];
01569 $all_files['webspace']['deny'] = $tcaFieldConf['disallowed'] ? $tcaFieldConf['disallowed'] : '*';
01570 $all_files['ftpspace'] = $all_files['webspace'];
01571 $this->fileFunc->init('', $all_files);
01572
01573
01574 if ($tcaFieldConf['uploadfolder']) {
01575
01576 $propArr = $this->getRecordProperties($table,$id);
01577
01578
01579 $dest = $this->destPathFromUploadFolder($tcaFieldConf['uploadfolder']);
01580
01581
01582 if ($status=='update') {
01583
01584
01585 $theFileValues=array();
01586 if ($tcaFieldConf['MM']) {
01587 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
01588 $dbAnalysis->start('','files',$tcaFieldConf['MM'],$id);
01589 reset($dbAnalysis->itemArray);
01590 while (list($somekey,$someval)=each($dbAnalysis->itemArray)) {
01591 if ($someval['id']) {
01592 $theFileValues[]=$someval['id'];
01593 }
01594 }
01595 } else {
01596 $theFileValues=t3lib_div::trimExplode(',',$curValue,1);
01597 }
01598
01599
01600 if (count($theFileValues)) {
01601
01602 foreach($valueArray as $key => $theFile) {
01603 if ($theFile && !strstr(t3lib_div::fixWindowsFilePath($theFile),'/')) {
01604 $theFileValues = t3lib_div::removeArrayEntryByValue($theFileValues,$theFile);
01605 }
01606 }
01607
01608
01609 foreach($theFileValues as $key => $theFile) {
01610 $theFile = trim($theFile);
01611 if (@is_file($dest.'/'.$theFile)) {
01612 $this->removeFilesStore[]=$dest.'/'.$theFile;
01613 } elseif ($theFile) {
01614 $this->log($table,$id,5,0,1,"Could not delete file '%s' (does not exist). (%s)",10,array($dest.'/'.$theFile, $recFID),$propArr['event_pid']);
01615 }
01616 }
01617 }
01618 }
01619
01620
01621 foreach($valueArray as $key => $theFile) {
01622
01623 if (strstr(t3lib_div::fixWindowsFilePath($theFile),'/')) {
01624
01625 $maxSize = intval($tcaFieldConf['max_size']);
01626 $cmd='';
01627 $theDestFile='';
01628
01629
01630 if (@is_dir($dest) && (@is_file($theFile) || @is_uploaded_file($theFile))) {
01631
01632
01633 if (is_uploaded_file($theFile) && $theFile==$uploadedFileArray['tmp_name']) {
01634 $fileSize = $uploadedFileArray['size'];
01635 } else {
01636 $fileSize = filesize($theFile);
01637 }
01638
01639 if (!$maxSize || $fileSize<=($maxSize*1024)) {
01640
01641 $theEndFileName = isset($this->alternativeFileName[$theFile]) ? $this->alternativeFileName[$theFile] : $theFile;
01642 $fI = t3lib_div::split_fileref($theEndFileName);
01643
01644
01645 if ($this->fileFunc->checkIfAllowed($fI['fileext'], $dest, $theEndFileName)) {
01646 $theDestFile = $this->fileFunc->getUniqueName($this->fileFunc->cleanFileName($fI['file']), $dest);
01647
01648
01649 if ($theDestFile) {
01650 t3lib_div::upload_copy_move($theFile,$theDestFile);
01651 $this->copiedFileMap[$theFile] = $theDestFile;
01652 clearstatcache();
01653 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']);
01654 } 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']);
01655 } else $this->log($table,$id,5,0,1,"Fileextension '%s' not allowed. (%s)",12,array($fI['fileext'], $recFID),$propArr['event_pid']);
01656 } 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']);
01657 } 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']);
01658
01659
01660 if (@is_file($theDestFile)) {
01661 $info = t3lib_div::split_fileref($theDestFile);
01662 $valueArray[$key]=$info['file'];
01663 } else {
01664 unset($valueArray[$key]);
01665 }
01666 }
01667 }
01668
01669
01670 if ($tcaFieldConf['MM']) {
01671 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
01672 $dbAnalysis->tableArray['files']=array();
01673
01674 reset($valueArray);
01675 while (list($key,$theFile)=each($valueArray)) {
01676
01677 $dbAnalysis->itemArray[]['id']=$theFile;
01678 }
01679 if ($status=='update') {
01680 $dbAnalysis->writeMM($tcaFieldConf['MM'],$id,0);
01681 } else {
01682 $this->dbAnalysisStore[] = array($dbAnalysis, $tcaFieldConf['MM'], $id, 0);
01683 }
01684 $cc=count($dbAnalysis->itemArray);
01685 $valueArray = array($cc);
01686 }
01687 }
01688
01689 return $valueArray;
01690 }
01691
01704 function checkValue_flex($res,$value,$tcaFieldConf,$PP,$uploadedFiles,$field) {
01705 list($table,$id,$curValue,$status,$realPid,$recFID) = $PP;
01706
01707 if (is_array($value)) {
01708
01709
01710 $dataStructArray = t3lib_BEfunc::getFlexFormDS($tcaFieldConf,$this->checkValue_currentRecord,$table);
01711 #debug($this->checkValue_currentRecord);
01712 $currentValueArray = t3lib_div::xml2array($curValue);
01713 if (!is_array($currentValueArray)) $currentValueArray = array();
01714 if (is_array($currentValueArray['meta']['currentLangId'])) unset($currentValueArray['meta']['currentLangId']);
01715
01716
01717 $value['data'] = $this->checkValue_flex_procInData($value['data'],$currentValueArray['data'],$uploadedFiles['data'],$dataStructArray,$PP);
01718
01719
01720 $xmlValue = $this->checkValue_flexArray2Xml($value);
01721
01722
01723
01724
01725
01726 $storeInCharset=$GLOBALS['LANG']->charSet;
01727
01728
01729
01730 if (is_array($currentValueArray)) {
01731 $arrValue = t3lib_div::xml2array($xmlValue);
01732 $arrValue = t3lib_div::array_merge_recursive_overrule($currentValueArray,$arrValue);
01733 $xmlValue = $this->checkValue_flexArray2Xml($arrValue);
01734 }
01735
01736
01737 $deleteCMDs = t3lib_div::_GP('_DELETE_FLEX_FORMdata');
01738
01739 if (is_array($deleteCMDs[$table][$id][$field]['data'])) {
01740 $arrValue = t3lib_div::xml2array($xmlValue);
01741 $this->_DELETE_FLEX_FORMdata($arrValue['data'],$deleteCMDs[$table][$id][$field]['data']);
01742 $xmlValue = $this->checkValue_flexArray2Xml($arrValue);
01743 }
01744
01745
01746 $res['value']='';
01747 $res['value'].='<?xml version="1.0" encoding="'.$storeInCharset.'" standalone="yes" ?>'.chr(10);
01748 $res['value'].=$xmlValue;
01749 } else {
01750 $res['value']=$value;
01751 }
01752
01753 return $res;
01754 }
01755
01762 function checkValue_flexArray2Xml($array) {
01763 $output = t3lib_div::array2xml($array,'',0,'T3FlexForms',4,array('parentTagMap' => array(
01764
01765
01766
01767
01768 )));
01769 return $output;
01770 }
01771
01779 function _DELETE_FLEX_FORMdata(&$valueArrayToRemoveFrom,$deleteCMDS) {
01780 if (is_array($valueArrayToRemoveFrom) && is_array($deleteCMDS)) {
01781 foreach($deleteCMDS as $key => $value) {
01782 if (is_array($deleteCMDS[$key])) {
01783 $this->_DELETE_FLEX_FORMdata($valueArrayToRemoveFrom[$key],$deleteCMDS[$key]);
01784 } else {
01785 unset($valueArrayToRemoveFrom[$key]);
01786 }
01787 }
01788 }
01789 }
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01827 function getUnique($table,$field,$value,$id,$newPid=0) {
01828 global $TCA;
01829
01830
01831 t3lib_div::loadTCA($table);
01832 $whereAdd='';
01833 $newValue='';
01834 if (intval($newPid)) { $whereAdd.=' AND pid='.intval($newPid); } else { $whereAdd.=' AND pid>=0'; }
01835 $whereAdd.=$this->deleteClause($table);
01836
01837
01838 if (is_array($TCA[$table]) && is_array($TCA[$table]['columns'][$field])) {
01839
01840
01841 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, $field.'="'.$GLOBALS['TYPO3_DB']->quoteStr($value, $table).'" AND uid!='.intval($id).$whereAdd);
01842 $counter = 0;
01843
01844
01845 while ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
01846 $newValue = $value.$counter;
01847 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, $field.'="'.$GLOBALS['TYPO3_DB']->quoteStr($newValue, $table).'" AND uid!='.intval($id).$whereAdd);
01848 $counter++;
01849 if ($counter>100) { break; }
01850 }
01851
01852 $value = strlen($newValue) ? $newValue : $value;
01853 }
01854 return $value;
01855 }
01856
01865 function checkValue_input_Eval($value,$evalArray,$is_in) {
01866 $res = Array();
01867 $newValue = $value;
01868 $set = true;
01869
01870 foreach($evalArray as $func) {
01871 switch($func) {
01872 case 'int':
01873 case 'year':
01874 case 'date':
01875 case 'datetime':
01876 case 'time':
01877 case 'timesec':
01878 $value = intval($value);
01879 break;
01880 case 'double2':
01881 $theDec = 0;
01882 for ($a=strlen($value); $a>0; $a--) {
01883 if (substr($value,$a-1,1)=='.' || substr($value,$a-1,1)==',') {
01884 $theDec = substr($value,$a);
01885 $value = substr($value,0,$a-1);
01886 break;
01887 }
01888 }
01889 $theDec = ereg_replace('[^0-9]','',$theDec).'00';
01890 $value = intval(str_replace(' ','',$value)).'.'.substr($theDec,0,2);
01891 break;
01892 case 'md5':
01893 if (strlen($value)!=32){$set=false;}
01894 break;
01895 case 'trim':
01896 $value = trim($value);
01897 break;
01898 case 'upper':
01899 $value = strtoupper($value);
01900 # $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.
01901 break;
01902 case 'lower':
01903 $value = strtolower($value);
01904 # $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.
01905 break;
01906 case 'required':
01907 if (!$value) {$set=0;}
01908 break;
01909 case 'is_in':
01910 $c=strlen($value);
01911 if ($c) {
01912 $newVal = '';
01913 for ($a=0;$a<$c;$a++) {
01914 $char = substr($value,$a,1);
01915 if (strstr($is_in,$char)) {
01916 $newVal.=$char;
01917 }
01918 }
01919 $value = $newVal;
01920 }
01921 break;
01922 case 'nospace':
01923 $value = str_replace(' ','',$value);
01924 break;
01925 case 'alpha':
01926 $value = ereg_replace('[^a-zA-Z]','',$value);
01927 break;
01928 case 'num':
01929 $value = ereg_replace('[^0-9]','',$value);
01930 break;
01931 case 'alphanum':
01932 $value = ereg_replace('[^a-zA-Z0-9]','',$value);
01933 break;
01934 case 'alphanum_x':
01935 $value = ereg_replace('[^a-zA-Z0-9_-]','',$value);
01936 break;
01937 }
01938 }
01939 if ($set) {$res['value'] = $value;}
01940 return $res;
01941 }
01942
01953 function checkValue_group_select_processDBdata($valueArray,$tcaFieldConf,$id,$status,$type) {
01954 $tables = $type=='group'?$tcaFieldConf['allowed']:$tcaFieldConf['foreign_table'].','.$tcaFieldConf['neg_foreign_table'];
01955 $prep = $type=='group'?$tcaFieldConf['prepend_tname']:$tcaFieldConf['neg_foreign_table'];
01956
01957 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
01958 $dbAnalysis->registerNonTableValues=$tcaFieldConf['allowNonIdValues'] ? 1 : 0;
01959 $dbAnalysis->start(implode(',',$valueArray),$tables);
01960
01961 if ($tcaFieldConf['MM']) {
01962 if ($status=='update') {
01963 $dbAnalysis->writeMM($tcaFieldConf['MM'],$id,$prep);
01964 } else {
01965 $this->dbAnalysisStore[] = array($dbAnalysis,$tcaFieldConf['MM'],$id,$prep);
01966 }
01967 $cc=count($dbAnalysis->itemArray);
01968 $valueArray = array($cc);
01969 } else {
01970 $valueArray = $dbAnalysis->getValueArray($prep);
01971 if ($type=='select' && $prep) {
01972 $valueArray = $dbAnalysis->convertPosNeg($valueArray,$tcaFieldConf['foreign_table'],$tcaFieldConf['neg_foreign_table']);
01973 }
01974 }
01975
01976
01977 return $valueArray;
01978 }
01979
01986 function checkValue_group_select_explodeSelectGroupValue($value) {
01987 $valueArray = t3lib_div::trimExplode(',',$value,1);
01988 reset($valueArray);
01989 while(list($key,$newVal)=each($valueArray)) {
01990 $temp=explode('|',$newVal,2);
01991 $valueArray[$key] = str_replace(',','',str_replace('|','',rawurldecode($temp[0])));
01992 }
01993 return $valueArray;
01994 }
01995
02009 function checkValue_flex_procInData($dataPart,$dataPart_current,$uploadedFiles,$dataStructArray,$pParams,$callBackFunc='') {
02010 #debug(array($dataPart,$dataPart_current,$dataStructArray));
02011 if (is_array($dataPart)) {
02012 foreach($dataPart as $sKey => $sheetDef) {
02013 list ($dataStruct,$actualSheet) = t3lib_div::resolveSheetDefInDS($dataStructArray,$sKey);
02014 #debug(array($dataStruct,$actualSheet,$sheetDef,$actualSheet,$sKey));
02015 if (is_array($dataStruct) && $actualSheet==$sKey && is_array($sheetDef)) {
02016 foreach($sheetDef as $lKey => $lData) {
02017 $this->checkValue_flex_procInData_travDS(
02018 $dataPart[$sKey][$lKey],
02019 $dataPart_current[$sKey][$lKey],
02020 $uploadedFiles[$sKey][$lKey],
02021 $dataStruct['ROOT']['el'],
02022 $pParams,
02023 $callBackFunc
02024 );
02025 }
02026 }
02027 }
02028 }
02029
02030 return $dataPart;
02031 }
02032
02046 function checkValue_flex_procInData_travDS(&$dataValues,$dataValues_current,$uploadedFiles,$DSelements,$pParams,$callBackFunc='') {
02047 if (is_array($DSelements)) {
02048
02049
02050 foreach($DSelements as $key => $dsConf) {
02051
02052
02053 if ($DSelements[$key]['type']=='array') {
02054 if (is_array($dataValues[$key]['el'])) {
02055 if ($DSelements[$key]['section']) {
02056 foreach($dataValues[$key]['el'] as $ik => $el) {
02057 $theKey = key($el);
02058 if (is_array($dataValues[$key]['el'][$ik][$theKey]['el'])) {
02059 $this->checkValue_flex_procInData_travDS(
02060 $dataValues[$key]['el'][$ik][$theKey]['el'],
02061 $dataValues_current[$key]['el'][$ik][$theKey]['el'],
02062 $uploadedFiles[$key]['el'][$ik][$theKey]['el'],
02063 $DSelements[$key]['el'][$theKey]['el'],
02064 $pParams,
02065 $callBackFunc
02066 );
02067 }
02068 }
02069 } else {
02070 if (!isset($dataValues[$key]['el'])) $dataValues[$key]['el']=array();
02071 $this->checkValue_flex_procInData_travDS(
02072 $dataValues[$key]['el'],
02073 $dataValues_current[$key]['el'],
02074 $uploadedFiles[$key]['el'],
02075 $DSelements[$key]['el'],
02076 $pParams,
02077 $callBackFunc
02078 );
02079 }
02080 }
02081 } else {
02082 if (is_array($dsConf['TCEforms']['config']) && is_array($dataValues[$key])) {
02083 foreach($dataValues[$key] as $vKey => $data) {
02084
02085 if ($callBackFunc) {
02086 $res = $this->$callBackFunc(
02087 $pParams,
02088 $dsConf['TCEforms']['config'],
02089 $dataValues[$key][$vKey],
02090 $dataValues_current[$key][$vKey],
02091 $uploadedFiles[$key][$vKey]
02092 );
02093 } else {
02094 list($CVtable,$CVid,$CVcurValue,$CVstatus,$CVrealPid,$CVrecFID,$CVtscPID) = $pParams;
02095
02096 $res = $this->checkValue_SW(
02097 array(),
02098 $dataValues[$key][$vKey],
02099 $dsConf['TCEforms']['config'],
02100 $CVtable,
02101 $CVid,
02102 $dataValues_current[$key][$vKey],
02103 $CVstatus,
02104 $CVrealPid,
02105 $CVrecFID,
02106 '',
02107 $uploadedFiles[$key][$vKey],
02108 array(),
02109 $CVtscPID
02110 );
02111
02112
02113 if ($dataValues[$key]['_TRANSFORM_'.$vKey] == 'RTE' && !$this->dontProcessTransformations) {
02114
02115
02116 unset($dataValues[$key]['_TRANSFORM_'.$vKey]);
02117
02118 if (isset($res['value'])) {
02119
02120
02121 list(,,$recFieldName) = explode(':', $CVrecFID);
02122 $theTypeString = t3lib_BEfunc::getTCAtypeValue($CVtable,$this->checkValue_currentRecord);
02123 $specConf = t3lib_BEfunc::getSpecConfParts('',$dsConf['TCEforms']['defaultExtras']);
02124
02125
02126 $RTEsetup = $this->BE_USER->getTSConfig('RTE',t3lib_BEfunc::getPagesTSconfig($CVtscPID));
02127 $thisConfig = t3lib_BEfunc::RTEsetup($RTEsetup['properties'],$CVtable,$recFieldName,$theTypeString);
02128
02129
02130 $RTEobj = &t3lib_BEfunc::RTEgetObj();
02131 if (is_object($RTEobj)) {
02132 $res['value'] = $RTEobj->transformContent('db',$res['value'],$CVtable,$recFieldName,$this->checkValue_currentRecord,$specConf,$thisConfig,'',$CVrealPid);
02133 } else {
02134 debug('NO RTE OBJECT FOUND!');
02135 }
02136 }
02137 }
02138 }
02139
02140
02141 if (isset($res['value'])) {
02142 $dataValues[$key][$vKey] = $res['value'];
02143 }
02144 }
02145 }
02146 }
02147 }
02148 }
02149 }
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02186 function updateDB($table,$id,$fieldArray) {
02187 global $TCA;
02188
02189 if (is_array($fieldArray) && is_array($TCA[$table]) && intval($id)) {
02190 unset($fieldArray['uid']);
02191
02192 if (count($fieldArray)) {
02193
02194
02195 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid='.intval($id), $fieldArray);
02196
02197
02198 if (!$GLOBALS['TYPO3_DB']->sql_error()) {
02199 if ($this->checkStoredRecords) {
02200 $newRow = $this->checkStoredRecord($table,$id,$fieldArray,2);
02201 }
02202
02203
02204 $propArr = $this->getRecordPropertiesFromRow($table,$newRow);
02205 $theLogId = $this->log($table,$id,2,$recpid,0,"Record '%s' (%s) was updated.",10,array($propArr['header'],$table.':'.$id),$propArr['event_pid']);
02206
02207
02208 $this->setHistory($table,$id,$theLogId);
02209
02210
02211 $this->clear_cache($table,$id);
02212
02213
02214 if ($table=='pages') unset($this->pageCache[$id]);
02215 } else {
02216 $this->log($table,$id,2,0,2,"SQL error: '%s' (%s)",12,array($GLOBALS['TYPO3_DB']->sql_error(),$table.':'.$id));
02217 }
02218 }
02219 }
02220 }
02221
02232 function compareFieldArrayWithCurrentAndUnset($table,$id,$fieldArray) {
02233
02234
02235 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'uid='.intval($id));
02236 $currentRecord = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
02237
02238
02239 if (is_array($currentRecord)) {
02240
02241
02242 $c = 0;
02243 $cRecTypes = array();
02244 foreach($currentRecord as $col => $val) {
02245 $cRecTypes[$col] = $GLOBALS['TYPO3_DB']->sql_field_type($res,$c);
02246 $c++;
02247 }
02248
02249
02250 $GLOBALS['TYPO3_DB']->sql_free_result($res);
02251
02252
02253 foreach($fieldArray as $col => $val) {
02254 if (
02255 #!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!]
02256 !strcmp($val,$currentRecord[$col]) ||
02257 ($cRecTypes[$col]=='int' && $currentRecord[$col]==0 && !strcmp($val,''))
02258 ) {
02259 unset($fieldArray[$col]);
02260 } else {
02261 $this->historyRecords[$table.':'.$id]['oldRecord'][$col] = $currentRecord[$col];
02262 $this->historyRecords[$table.':'.$id]['newRecord'][$col] = $fieldArray[$col];
02263 }
02264 }
02265 } else {
02266 $fieldArray = array();
02267 }
02268
02269 return $fieldArray;
02270 }
02271
02282 function insertDB($table,$id,$fieldArray,$newVersion=FALSE) {
02283 global $TCA;
02284
02285 if (is_array($fieldArray) && is_array($TCA[$table]) && isset($fieldArray['pid'])) {
02286 unset($fieldArray['uid']);
02287
02288 if (count($fieldArray)) {
02289
02290
02291 $GLOBALS['TYPO3_DB']->exec_INSERTquery($table, $fieldArray);
02292
02293
02294 if (!$GLOBALS['TYPO3_DB']->sql_error()) {
02295
02296
02297 $NEW_id = $id;
02298 $id = $GLOBALS['TYPO3_DB']->sql_insert_id();
02299 $this->substNEWwithIDs[$NEW_id] = $id;
02300 $this->substNEWwithIDs_table[$NEW_id] = $table;
02301
02302
02303 if ($this->checkStoredRecords) {
02304 $newRow = $this->checkStoredRecord($table,$id,$fieldArray,1);
02305 }
02306
02307 if ($newVersion) {
02308 $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);
02309 } else {
02310
02311 if ($table=='pages') {
02312 $thePositionID = $this->getInterfacePagePositionID($id);
02313 } else {
02314 $thePositionID = 0;
02315 }
02316 $propArr = $this->getRecordPropertiesFromRow($table,$newRow);
02317 $page_propArr = $this->getRecordProperties('pages',$propArr['pid']);
02318 $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);
02319
02320
02321 $this->clear_cache($table,$id);
02322 }
02323 } else {
02324 $this->log($table,$id,1,0,2,"SQL error: '%s' (%s)",12,array($GLOBALS['TYPO3_DB']->sql_error(),$table.':'.$id));
02325 }
02326 }
02327 }
02328 }
02329
02340 function checkStoredRecord($table,$id,$fieldArray,$action) {
02341 global $TCA;
02342
02343 $id = intval($id);
02344 if (is_array($TCA[$table]) && $id) {
02345 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'uid='.intval($id));
02346 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
02347
02348
02349 $errorString = array();
02350 foreach($fieldArray as $key => $value) {
02351 if ($this->checkStoredRecords_loose && !$value && !$row[$key]) {
02352
02353 } elseif (strcmp($value,$row[$key])) {
02354 $errorString[] = $key;
02355 }
02356 }
02357
02358
02359 if (count($errorString)) {
02360 $this->log($table,$id,$action,0,102,'These fields are not properly updated in database: ('.implode(',',$errorString).') Probably value mismatch with fieldtype.');
02361 }
02362
02363
02364 return $row;
02365 }
02366 $GLOBALS['TYPO3_DB']->sql_free_result($res);
02367 }
02368 }
02369
02375 function dbAnalysisStoreExec() {
02376 reset($this->dbAnalysisStore);
02377 while(list($k,$v)=each($this->dbAnalysisStore)) {
02378 $id = $this->substNEWwithIDs[$v[2]];
02379 if ($id) {
02380 $v[2] = $id;
02381 $v[0]->writeMM($v[1],$v[2],$v[3]);
02382 }
02383 }
02384 }
02385
02391 function removeRegisteredFiles() {
02392 reset($this->removeFilesStore);
02393 while(list($k,$v)=each($this->removeFilesStore)) {
02394 unlink($v);
02395
02396 }
02397 }
02398
02408 function clear_cache($table,$uid) {
02409 global $TCA;
02410
02411 $uid = intval($uid);
02412 if (is_array($TCA[$table]) && $uid > 0) {
02413
02414
02415 list($tscPID) = t3lib_BEfunc::getTSCpid($table,$uid,'');
02416 $TSConfig = $this->getTCEMAIN_TSconfig($tscPID);
02417
02418 if (!$TSConfig['clearCache_disable']) {
02419
02420 if (t3lib_extMgm::isLoaded('cms')) {
02421 if ($table=='pages') {
02422
02423
02424 $res_tmp = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
02425 'A.pid AS pid, B.uid AS uid',
02426 'pages AS A, pages AS B',
02427 'A.uid='.intval($uid).' AND B.pid=A.pid AND B.deleted=0'
02428 );
02429
02430 $list_cache = array();
02431 $pid_tmp = 0;
02432 while ($row_tmp = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res_tmp)) {
02433 $list_cache[] = $row_tmp['uid'];
02434 $pid_tmp = $row_tmp['pid'];
02435
02436
02437 if ($TSConfig['clearCache_pageSiblingChildren']) {
02438 $res_tmp2 = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
02439 'uid',
02440 'pages',
02441 'pid='.intval($row_tmp['uid']).' AND deleted=0'
02442 );
02443 while ($row_tmp2 = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res_tmp2)) {
02444 $list_cache[] = $row_tmp2['uid'];
02445 }
02446 }
02447 }
02448
02449
02450 $list_cache[] = $pid_tmp;
02451
02452
02453 if ($TSConfig['clearCache_pageGrandParent']) {
02454 $res_tmp = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
02455 'pid',
02456 'pages',
02457 'uid='.intval($pid_tmp)
02458 );
02459 if ($row_tmp = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res_tmp)) {
02460 $list_cache[] = $row_tmp['pid'];
02461 }
02462 }
02463
02464
02465 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages','page_id IN ('.implode(',',$GLOBALS['TYPO3_DB']->cleanIntArray($list_cache)).')');
02466 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pagesection', 'page_id IN ('.implode(',',$GLOBALS['TYPO3_DB']->cleanIntArray($list_cache)).')');
02467 } else {
02468 $uid_page = $this->getPID($table,$uid);
02469 if ($uid_page>0) {
02470 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages', 'page_id='.intval($uid_page));
02471 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pagesection', 'page_id='.intval($uid_page));
02472 }
02473 }
02474 }
02475 }
02476
02477
02478 if ($TSConfig['clearCacheCmd']) {
02479 $Commands = t3lib_div::trimExplode(',',strtolower($TSConfig['clearCacheCmd']),1);
02480 $Commands = array_unique($Commands);
02481 foreach($Commands as $cmdPart) {
02482 $this->clear_cacheCmd($cmdPart);
02483 }
02484 }
02485
02486
02487 global $TYPO3_CONF_VARS;
02488 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc'])) {
02489 $_params = array('table' => $table,'uid' => $uid,'uid_page' => $uid_page,'TSConfig' => $TSConfig);
02490 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc'] as $_funcRef) {
02491 t3lib_div::callUserFunction($_funcRef,$_params,$this);
02492 }
02493 }
02494 }
02495 }
02496
02504 function getPID($table,$uid) {
02505 $res_tmp = $GLOBALS['TYPO3_DB']->exec_SELECTquery('pid', $table, 'uid='.intval($uid));
02506 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res_tmp)) {
02507 return $row['pid'];
02508 }
02509 }
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02547 function process_cmdmap() {
02548 global $TCA;
02549
02550
02551 reset ($this->cmdmap);
02552 while (list($table,) = each($this->cmdmap)) {
02553
02554
02555 $modifyAccessList = $this->checkModifyAccessList($table);
02556 if (!$modifyAccessList) {
02557 $this->log($table,$id,2,0,1,"Attempt to modify table '%s' without permission",1,array($table));
02558 }
02559
02560
02561 if (isset($TCA[$table]) && !$this->tableReadOnly($table) && is_array($this->cmdmap[$table]) && $modifyAccessList) {
02562
02563
02564 foreach($this->cmdmap[$table] as $id => $incomingCmdArray) {
02565 if (is_array($incomingCmdArray)) {
02566
02567
02568 reset($incomingCmdArray);
02569 $command = key($incomingCmdArray);
02570 $value = current($incomingCmdArray);
02571
02572
02573 $this->copyMappingArray = Array();
02574
02575
02576 switch ($command) {
02577 case 'move':
02578 $this->moveRecord($table,$id,$value);
02579 break;
02580 case 'copy':
02581 if ($table == 'pages') {
02582 $this->copyPages($id,$value);
02583 } else {
02584 $this->copyRecord($table,$id,$value,1);
02585 }
02586 break;
02587 case 'localize':
02588 $this->copyRecord_localize($table,$id,$value);
02589 break;
02590 case 'version':
02591 switch ((string)$value['action']) {
02592 case 'new':
02593 $this->versionizeTree = t3lib_div::intInRange($value['treeLevels'],-1,4);
02594 if ($table == 'pages' && $this->versionizeTree>=0) {
02595 $this->versionizePages($id,$value['label']);
02596 } else {
02597 $this->versionizeRecord($table,$id,$value['label']);
02598 }
02599 break;
02600 case 'swap':
02601 $this->version_swap($table,$id,$value['swapWith'],$value['swapContent']);
02602 break;
02603 }
02604 break;
02605 case 'delete':
02606 if ($table == 'pages') {
02607 $this->deletePages($id);
02608 } else {
02609 $this->deleteRecord($table,$id, 0);
02610 }
02611 break;
02612 }
02613
02614 $this->copyMappingArray_merged= t3lib_div::array_merge_recursive_overrule($this->copyMappingArray_merged,$this->copyMappingArray);
02615 }
02616 }
02617 }
02618 }
02619
02620 #debug($this->copyMappingArray_merged,'$this->copyMappingArray_merged');
02621 #debug($this->registerDBList,'$this->registerDBList');
02622
02623
02624 $this->remapListedDBRecords();
02625 }
02626
02635 function moveRecord($table,$uid,$destPid) {
02636 global $TCA;
02637
02638
02639 $sortRow = $TCA[$table]['ctrl']['sortby'];
02640 $destPid = intval($destPid);
02641 $origDestPid = $destPid;
02642
02643 if ($TCA[$table]) {
02644 $propArr = $this->getRecordProperties($table,$uid);
02645 $resolvedPid = $this->resolvePid($table,$destPid);
02646
02647
02648
02649 if ($table!='pages' || $resolvedPid==$propArr['pid']) {
02650 $mayMoveAccess = $this->checkRecordUpdateAccess($table,$uid);
02651 } else {
02652 $mayMoveAccess = $this->doesRecordExist($table,$uid,'delete');
02653 }
02654
02655
02656 if ($table!='pages' || $resolvedPid!=$propArr['pid']) {
02657 $mayInsertAccess = $this->checkRecordInsertAccess($table,$resolvedPid,4);
02658 } else {
02659 $mayInsertAccess = $this->checkRecordUpdateAccess($table,$uid);
02660 }
02661
02662
02663 if ($destPid<0 && !$sortRow) {
02664 $destPid = $resolvedPid;
02665 }
02666
02667
02668 $updateFields = array();
02669 if ($TCA[$table]['ctrl']['tstamp']) {
02670 $updateFields[$TCA[$table]['ctrl']['tstamp']] = time();
02671 }
02672
02673
02674 if ($mayMoveAccess) {
02675 if ($destPid>=0) {
02676 if ($mayInsertAccess) {
02677 if ($table!='pages' || $this->destNotInsideSelf ($destPid,$uid)) {
02678 $this->clear_cache($table,$uid);
02679
02680 $updateFields['pid'] = $destPid;
02681
02682
02683 if ($sortRow) {
02684 $sortNumber = $this->getSortNumber($table,$uid,$destPid);
02685 $updateFields[$sortRow] = $sortNumber;
02686 }
02687
02688
02689 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid='.intval($uid), $updateFields);
02690
02691
02692 $newPropArr = $this->getRecordProperties($table,$uid);
02693 $oldpagePropArr = $this->getRecordProperties('pages',$propArr['pid']);
02694 $newpagePropArr = $this->getRecordProperties('pages',$destPid);
02695
02696 if ($destPid!=$propArr['pid']) {
02697 $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']);
02698 $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);
02699 } else {
02700 $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);
02701 }
02702 $this->clear_cache($table,$uid);
02703 $this->fixUniqueInPid($table,$uid);
02704
02705 if ($origDestPid<0) {$this->fixCopyAfterDuplFields($table,$uid,abs($origDestPid),1);}
02706 } else {
02707 $destPropArr = $this->getRecordProperties('pages',$destPid);
02708 $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']);
02709 }
02710 }
02711 } else {
02712 if ($sortRow) {
02713 $sortInfo = $this->getSortNumber($table,$uid,$destPid);
02714 $destPid = $sortInfo['pid'];
02715 if (is_array($sortInfo)) {
02716 if ($mayInsertAccess) {
02717 if ($table!='pages' || $this->destNotInsideSelf($destPid,$uid)) {
02718 $this->clear_cache($table,$uid);
02719
02720
02721 $updateFields['pid'] = $destPid;
02722 $updateFields[$sortRow] = $sortInfo['sortNumber'];
02723 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid='.intval($uid), $updateFields);
02724
02725
02726 if ($table=='pages') {
02727 $thePositionID = $this->getInterfacePagePositionID($uid);
02728 } else {
02729 $thePositionID = 0;
02730 }
02731 $this->log($table,$uid,4,$thePositionID,0,'');
02732
02733
02734 $newPropArr = $this->getRecordProperties($table,$uid);
02735 $oldpagePropArr = $this->getRecordProperties('pages',$propArr['pid']);
02736 if ($destPid!=$propArr['pid']) {
02737 $newpagePropArr = $this->getRecordProperties('pages',$destPid);
02738 $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']);
02739 $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);
02740 } else {
02741 $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);
02742 }
02743
02744
02745 $this->clear_cache($table,$uid);
02746
02747
02748 $this->fixUniqueInPid($table,$uid);
02749
02750
02751 if ($origDestPid<0) {$this->fixCopyAfterDuplFields($table,$uid,abs($origDestPid),1);}
02752 } else {
02753 $destPropArr = $this->getRecordProperties('pages',$destPid);
02754 $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']);
02755 }
02756 }
02757 }
02758 } else {
02759 $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']);
02760 }
02761 }
02762 } else {
02763 $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']);
02764 }
02765 }
02766 }
02767
02779 function copyRecord($table,$uid,$destPid,$first=0,$overrideValues=array(),$excludeFields='') {
02780 global $TCA;
02781
02782 $uid = intval($uid);
02783 if ($TCA[$table] && $uid) {
02784 t3lib_div::loadTCA($table);
02785 if ($this->doesRecordExist($table,$uid,'show')) {
02786 $data = Array();
02787
02788 $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));
02789
02790 $row = $this->recordInfo($table,$uid,'*');
02791 if (is_array($row)) {
02792
02793
02794 $theNewID = uniqid('NEW');
02795 $enableField = isset($TCA[$table]['ctrl']['enablecolumns']) ? $TCA[$table]['ctrl']['enablecolumns']['disabled'] : '';
02796 $headerField = $TCA[$table]['ctrl']['label'];
02797
02798
02799 $defaultData = $this->newFieldArray($table);
02800
02801
02802
02803 $copyAfterFields = $destPid<0 ? $this->fixCopyAfterDuplFields($table,$uid,abs($destPid),0) : array();
02804
02805
02806 $tscPID = t3lib_BEfunc::getTSconfig_pidValue($table,$uid,$destPid);
02807 $TSConfig = $this->getTCEMAIN_TSconfig($tscPID);
02808 $tE = $this->getTableEntries($table,$TSConfig);
02809
02810
02811 foreach($row as $field => $value) {
02812 if (!in_array($field,$nonFields)) {
02813
02814
02815 $conf = $TCA[$table]['columns'][$field]['config'];
02816
02817
02818 if ($field=='pid') {
02819 $value = $destPid;
02820 } elseif (isset($overrideValues[$field])) {
02821 $value = $overrideValues[$field];
02822 } elseif (isset($copyAfterFields[$field])) {
02823 $value = $copyAfterFields[$field];
02824 } elseif ($TCA[$table]['ctrl']['setToDefaultOnCopy'] && t3lib_div::inList($TCA[$table]['ctrl']['setToDefaultOnCopy'],$field)) {
02825 $value = $defaultData[$field];
02826 } else {
02827
02828 if ($first && $field==$enableField && $TCA[$table]['ctrl']['hideAtCopy'] && !$this->neverHideAtCopy && !$tE['disableHideAtCopy']) {
02829 $value=1;
02830 }
02831
02832 if ($first && $field==$headerField && $TCA[$table]['ctrl']['prependAtCopy'] && !$tE['disablePrependAtCopy']) {
02833 $value = $this->getCopyHeader($table,$this->resolvePid($table,$destPid),$field,$this->clearPrefixFromValue($table,$value),0);
02834 }
02835
02836 $value = $this->copyRecord_procBasedOnFieldType($table,$uid,$field,$value,$row,$conf);
02837 }
02838
02839
02840 $data[$table][$theNewID][$field] = $value;
02841 }
02842
02843
02844 if ($TCA[$table]['ctrl']['editlock']) {
02845 $data[$table][$theNewID][$TCA[$table]['ctrl']['editlock']] = 0;
02846 }
02847 }
02848
02849
02850 $copyTCE = t3lib_div::makeInstance('t3lib_TCEmain');
02851 $copyTCE->stripslashes_values = 0;
02852 $copyTCE->copyTree = $this->copyTree;
02853 $copyTCE->cachedTSconfig = $this->cachedTSconfig;
02854 $copyTCE->dontProcessTransformations=1;
02855
02856
02857 $copyTCE->start($data,'',$this->BE_USER);
02858 $copyTCE->process_datamap();
02859
02860
02861 $theNewSQLID = $copyTCE->substNEWwithIDs[$theNewID];
02862 if ($theNewSQLID) {
02863 $this->copyMappingArray[$table][$uid] = $theNewSQLID;
02864 }
02865
02866
02867 $this->cachedTSconfig = $copyTCE->cachedTSconfig;
02868 unset($copyTCE);
02869 } else $this->log($table,$uid,3,0,1,'Attempt to copy record that did not exist!');
02870 } else $this->log($table,$uid,3,0,1,'Attempt to copy record without permission');
02871 }
02872 }
02873
02888 function copyRecord_raw($table,$uid,$pid,$overrideArray=array()) {
02889 global $TCA;
02890
02891 $uid = intval($uid);
02892 if ($TCA[$table] && $uid) {
02893 t3lib_div::loadTCA($table);
02894 if ($this->doesRecordExist($table,$uid,'show')) {
02895
02896
02897 $nonFields = array('uid','pid','t3ver_id','t3ver_oid','t3ver_label','perms_userid','perms_groupid','perms_user','perms_group','perms_everybody');
02898
02899
02900 $row = $this->recordInfo($table,$uid,'*');
02901 if (is_array($row)) {
02902
02903
02904 $row = array_merge($row,$overrideArray);
02905
02906
02907 foreach($row as $field => $value) {
02908 if (!in_array($field,$nonFields)) {
02909
02910
02911 $conf = $TCA[$table]['columns'][$field]['config'];
02912 if (is_array($conf)) {
02913
02914 $value = $this->copyRecord_procBasedOnFieldType($table,$uid,$field,$value,$row,$conf);
02915 }
02916
02917
02918 $row[$field] = $value;
02919 }
02920 }
02921
02922
02923 $row['pid'] = $pid;
02924
02925
02926 $theNewSQLID = $this->insertNewCopyVersion($table,$row,$pid);
02927 if ($theNewSQLID) {
02928 return $this->copyMappingArray[$table][$uid] = $theNewSQLID;
02929 }
02930 } else $this->log($table,$uid,3,0,1,'Attempt to rawcopy/versionize record that did not exist!');
02931 } else $this->log($table,$uid,3,0,1,'Attempt to rawcopy/versionize record without copy permission');
02932 }
02933 }
02934
02944 function insertNewCopyVersion($table,$fieldArray,$realPid) {
02945 global $TCA;
02946
02947 $id = uniqid('NEW');
02948
02949
02950
02951 $this->checkValue_currentRecord = $fieldArray;
02952
02953
02954 foreach($fieldArray as $field => $fieldValue) {
02955 if (isset($TCA[$table]['columns'][$field])) {
02956
02957 $res = $this->checkValue($table,$field,$fieldValue,$id,'new',$realPid,0);
02958 if (isset($res['value'])) {
02959 $fieldArray[$field] = $res['value'];
02960 }
02961 }
02962 }
02963
02964
02965 if ($TCA[$table]['ctrl']['crdate']) {
02966 $fieldArray[$TCA[$table]['ctrl']['crdate']]=time();
02967 }
02968 if ($TCA[$table]['ctrl']['cruser_id']) {
02969 $fieldArray[$TCA[$table]['ctrl']['cruser_id']]=$this->userid;
02970 }
02971 if ($TCA[$table]['ctrl']['tstamp']) {
02972 $fieldArray[$TCA[$table]['ctrl']['tstamp']]=time();
02973 }
02974
02975
02976 $this->insertDB($table,$id,$fieldArray, TRUE);
02977
02978
02979 return $this->substNEWwithIDs[$id];
02980 }
02981
02995 function copyRecord_procBasedOnFieldType($table,$uid,$field,$value,$row,$conf) {
02996 global $TCA;
02997
02998
02999 $value = $this->copyRecord_procFilesRefs($conf, $uid, $value);
03000
03001
03002
03003 if ($this->isReferenceField($conf)) {
03004 $allowedTables = $conf['type']=='group' ? $conf['allowed'] : $conf['foreign_table'].','.$conf['neg_foreign_table'];
03005 $prependName = $conf['type']=='group' ? $conf['prepend_tname'] : $conf['neg_foreign_table'];
03006 if ($conf['MM']) {
03007 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
03008 $dbAnalysis->start('',$allowedTables,$conf['MM'],$uid);
03009 $value = implode(',',$dbAnalysis->getValueArray($prependName));
03010 }
03011 if ($value) {
03012 $this->registerDBList[$table][$uid][$field] = $value;
03013 }
03014 }
03015
03016
03017 if ($conf['type']=='flex') {
03018
03019
03020 $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $row, $table);
03021 $currentValueArray = t3lib_div::xml2array($value);
03022
03023
03024 if (is_array($currentValueArray)) {
03025 $currentValueArray['data'] = $this->checkValue_flex_procInData(
03026 $currentValueArray['data'],
03027 array(),
03028 array(),
03029 $dataStructArray,
03030 array($table,$uid,$field),
03031 'copyRecord_flexFormCallBack'
03032 );
03033 $value = $currentValueArray;
03034 }
03035 }
03036
03037 return $value;
03038 }
03039
03048 function copyRecord_localize($table,$uid,$language) {
03049 global $TCA;
03050
03051 $uid = intval($uid);
03052
03053 if ($TCA[$table] && $uid) {
03054 t3lib_div::loadTCA($table);
03055
03056 if ($TCA[$table]['ctrl']['languageField'] && $TCA[$table]['ctrl']['transOrigPointerField']) {
03057 if ($langRec = t3lib_BEfunc::getRecord('sys_language',intval($language),'uid,title')) {
03058 if ($this->doesRecordExist($table,$uid,'show')) {
03059
03060 $row = $this->recordInfo($table,$uid,'*');
03061 if (is_array($row)) {
03062 if ($row[$TCA[$table]['ctrl']['languageField']] <= 0) {
03063 if ($row[$TCA[$table]['ctrl']['transOrigPointerField']] == 0) {
03064 if (!t3lib_BEfunc::getRecordsByField($table,$TCA[$table]['ctrl']['transOrigPointerField'],$uid,'AND pid='.intval($row['pid']).' AND '.$TCA[$table]['ctrl']['languageField'].'='.$langRec['uid'])) {
03065
03066
03067 $overrideValues = array();
03068 $excludeFields = array();
03069
03070
03071 $overrideValues[$TCA[$table]['ctrl']['languageField']] = $langRec['uid'];
03072 $overrideValues[$TCA[$table]['ctrl']['transOrigPointerField']] = $uid;
03073
03074
03075 foreach($TCA[$table]['columns'] as $fN => $fCfg) {
03076 if ($fCfg['l10n_mode']=='prefixLangTitle') {
03077 if ($fCfg['config']['type']=='text' || $fCfg['config']['type']=='input') {
03078 $overrideValues[$fN] = '[Translate to '.$langRec['title'].':] '.$row[$fN];
03079 }
03080 } elseif (t3lib_div::inList('exclude,noCopy,mergeIfNotBlank',$fCfg['l10n_mode']) && $fN!=$TCA[$table]['ctrl']['languageField'] && $fN!=$TCA[$table]['ctrl']['transOrigPointerField']) {
03081 $excludeFields[] = $fN;
03082 }
03083 }
03084
03085 $this->copyRecord($table,$uid,-$uid,1,$overrideValues,implode(',',$excludeFields));
03086 } else $this->log($table,$uid,3,0,1,'Localization failed; There already was a localization for this language of the record!');
03087 } else $this->log($table,$uid,3,0,1,'Localization failed; Source record contained a reference to an original default record (which is strange)!');
03088 } else $this->log($table,$uid,3,0,1,'Localization failed; Source record had another language than "Default" or "All" defined!');
03089 } else $this->log($table,$uid,3,0,1,'Attempt to localize record that did not exist!');
03090 } else $this->log($table,$uid,3,0,1,'Attempt to localize record without permission');
03091 } else $this->log($table,$uid,3,0,1,'Sys language UID "'.$language.'" not found valid!');
03092 } else $this->log($table,$uid,3,0,1,'Localization failed; "languageField" and "transOrigPointerField" must be defined for the table!');
03093 }
03094 }
03095
03107 function copyRecord_flexFormCallBack($pParams, $dsConf, $dataValue, $dataValue_ext1, $dataValue_ext2) {
03108
03109
03110 list($table, $uid, $field) = $pParams;
03111
03112
03113 $dataValue = $this->copyRecord_procFilesRefs($dsConf, $uid, $dataValue);
03114
03115
03116 if ($this->isReferenceField($dsConf) && strlen($dataValue)) {
03117 $this->registerDBList[$table][$uid][$field] = 'FlexForm_reference';
03118 }
03119
03120
03121 return array('value' => $dataValue);
03122 }
03123
03135 function copyRecord_procFilesRefs($conf, $uid, $value) {
03136
03137
03138 if ($conf['type']=='group' && $conf['internal_type']=='file') {
03139
03140
03141 if ($conf['MM']) {
03142 $theFileValues = array();
03143
03144 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
03145 $dbAnalysis->start('', 'files', $conf['MM'], $uid);
03146
03147 foreach($dbAnalysis->itemArray as $somekey => $someval) {
03148 if ($someval['id']) {
03149 $theFileValues[] = $someval['id'];
03150 }
03151 }
03152 } else {
03153 $theFileValues = t3lib_div::trimExplode(',',$value,1);
03154 }
03155
03156
03157 $uploadFolder = $conf['uploadfolder'];
03158 $dest = $this->destPathFromUploadFolder($uploadFolder);
03159 $newValue = array();
03160
03161 foreach($theFileValues as $file) {
03162 if (trim($file)) {
03163 $realFile = $dest.'/'.trim($file);
03164 if (@is_file($realFile)) {
03165 $newValue[] = $realFile;
03166 }
03167 }
03168 }
03169
03170
03171 $value = implode(',',$newValue);
03172 }
03173
03174
03175 return $value;
03176 }
03177
03186 function copyPages($uid,$destPid) {
03187
03188
03189 $uid = intval($uid);
03190 $destPid = intval($destPid);
03191
03192
03193 $copyTablesArray = $this->admin ? $this->compileAdminTables() : explode(',',$this->BE_USER->groupData['tables_modify']);
03194 if (!strstr($this->copyWhichTables,'*')) {
03195 foreach($copyTablesArray as $k => $table) {
03196 if (!$table || !t3lib_div::inList($this->copyWhichTables.',pages',$table)) {
03197 unset($copyTablesArray[$k]);
03198 }
03199 }
03200 }
03201 $copyTablesArray = array_unique($copyTablesArray);
03202
03203
03204 if ($this->admin || in_array('pages',$copyTablesArray)) {
03205
03206
03207 $this->copySpecificPage($uid,$destPid,$copyTablesArray,1);
03208 $theNewRootID = $this->copyMappingArray['pages'][$uid];
03209
03210
03211 if ($theNewRootID && $this->copyTree) {
03212
03213
03214 $CPtable = $this->int_pageTreeInfo(Array(), $uid, intval($this->copyTree), $theNewRootID);
03215
03216
03217 foreach($CPtable as $thePageUid => $thePagePid) {
03218 $newPid = $this->copyMappingArray['pages'][$thePagePid];
03219 if (isset($newPid)) {
03220 $this->copySpecificPage($thePageUid,$newPid,$copyTablesArray);
03221 } else {
03222 $this->log('pages',$uid,5,0,1,'Something went wrong during copying branch');
03223 break;
03224 }
03225 }
03226 }
03227 } else {
03228 $this->log('pages',$uid,5,0,1,'Attempt to copy page without permission to this table');
03229 }
03230 }
03231
03241 function copySpecificPage($uid,$destPid,$copyTablesArray,$first=0) {
03242 global $TCA;
03243
03244
03245 $this->copyRecord('pages',$uid,$destPid,$first);
03246 $theNewRootID = $this->copyMappingArray['pages'][$uid];
03247
03248
03249 if ($theNewRootID) {
03250 foreach($copyTablesArray as $table) {
03251 if ($table && is_array($TCA[$table]) && $table!='pages') {
03252 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, 'pid='.intval($uid).$this->deleteClause($table), '', ($TCA[$table]['ctrl']['sortby'] ? $TCA[$table]['ctrl']['sortby'].' DESC' : ''));
03253 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
03254 $this->copyRecord($table,$row['uid'], $theNewRootID);
03255 }
03256 }
03257 }
03258 }
03259 }
03260
03271 function versionizeRecord($table,$id,$label) {
03272 global $TCA;
03273
03274 $id = intval($id);
03275
03276 if ($TCA[$table] && $TCA[$table]['ctrl']['versioning'] && $id>0) {
03277 if ($this->doesRecordExist($table,$id,'show') && $this->doesRecordExist($table,$id,'edit')) {
03278
03279
03280 $row = $this->recordInfo($table,$id,'pid,t3ver_id');
03281 if (is_array($row)) {
03282 if ($row['pid']>=0) {
03283
03284
03285 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
03286 't3ver_id',
03287 $table,
03288 '(t3ver_oid='.$id.' || uid='.$id.')'.$this->deleteClause($table),
03289 '',
03290 't3ver_id DESC',
03291 '1'
03292 );
03293 list($highestVerNumber) = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
03294
03295
03296 $subVer = $row['t3ver_id'].'.'.($highestVerNumber+1);
03297
03298
03299 $overrideArray = array(
03300 't3ver_id' => $highestVerNumber+1,
03301 't3ver_oid' => $id,
03302 't3ver_label' => ($label ? $label : $subVer.' / '.date('d-m-Y H:m:s'))
03303 );
03304 if ($TCA[$table]['ctrl']['editlock']) {
03305 $overrideArray[$TCA[$table]['ctrl']['editlock']] = 0;
03306 }
03307
03308
03309 return $this->copyRecord_raw($table,$id,-1,$overrideArray);
03310 } else $this->log($table,$id,0,0,1,'Record you wanted to versionize was already a version in archive (pid=-1)!');
03311 } else $this->log($table,$id,0,0,1,'Record you wanted to versionize didnt exist!');
03312 } else $this->log($table,$id,0,0,1,'You didnt have correct permissions to make a new version (copy) of this record "'.$table.'" / '.$id);
03313 } else $this->log($table,$id,0,0,1,'Versioning is not supported for this table "'.$table.'" / '.$id);
03314 }
03315
03324 function versionizePages($uid,$label) {
03325 global $TCA;
03326
03327 $uid = intval($uid);
03328
03329
03330 $allowedTablesArray = $this->admin ? $this->compileAdminTables() : explode(',',$this->BE_USER->groupData['tables_modify']);
03331
03332
03333 $verTablesArray = array();
03334 $allTables = array_keys($TCA);
03335 foreach($allTables as $tN) {
03336 if ($tN!='pages' && $TCA[$tN]['ctrl']['versioning_followPages'] && ($this->admin || in_array($tN, $allowedTablesArray))) {
03337 $verTablesArray[] = $tN;
03338 }
03339 }
03340
03341
03342 if ($this->admin || in_array('pages',$allowedTablesArray)) {
03343
03344
03345 $theNewRootID = $this->versionizeRecord('pages',$uid,$label);
03346 $this->rawCopyPageContent($uid,$theNewRootID,$verTablesArray);
03347
03348
03349 if ($theNewRootID && $this->versionizeTree > 0) {
03350
03351
03352 $CPtable = $this->int_pageTreeInfo(Array(), $uid, intval($this->versionizeTree), $theNewRootID);
03353
03354
03355 foreach($CPtable as $thePageUid => $thePagePid) {
03356 $newPid = $this->copyMappingArray['pages'][$thePagePid];
03357 if (isset($newPid)) {
03358 $theNewRootID = $this->copyRecord_raw('pages',$thePageUid,$newPid);
03359 $this->rawCopyPageContent($thePageUid,$theNewRootID,$verTablesArray);
03360 } else {
03361 $this->log('pages',$uid,0,0,1,'Something went wrong during copying branch (for versioning)');
03362 break;
03363 }
03364 }
03365 }
03366 } else {
03367 $this->log('pages',$uid,0,0,1,'Attempt to versionize page without permission to this table');
03368 }
03369 }
03370
03381 function rawCopyPageContent($old_pid,$new_pid,$copyTablesArray) {
03382 global $TCA;
03383
03384 if ($new_pid) {
03385 foreach($copyTablesArray as $table) {
03386 if ($table && is_array($TCA[$table]) && $table!='pages') {
03387 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, 'pid='.intval($old_pid).$this->deleteClause($table));
03388 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
03389 $this->copyRecord_raw($table,$row['uid'],$new_pid);
03390 }
03391 }
03392 }
03393 }
03394 }
03395
03406 function version_swap($table,$id,$swapWith,$swapContent) {
03407 global $TCA;
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433 if ($this->checkRecordUpdateAccess($table,$id)) {
03434
03435
03436 $keepFields = array();
03437 $selectFields = array('uid','pid','t3ver_oid');
03438 if ($TCA[$table]['ctrl']['sortby']) {
03439 $selectFields[] = $keepFields[] = $TCA[$table]['ctrl']['sortby'];
03440 }
03441 $selectFields = array_unique($selectFields);
03442
03443
03444 $curVersion = t3lib_BEfunc::getRecord($table,$id,implode(',',$selectFields));
03445 $swapVersion = t3lib_BEfunc::getRecord($table,$swapWith,implode(',',$selectFields));
03446
03447 if (is_array($curVersion) && is_array($swapVersion)) {
03448 if (!is_array(t3lib_BEfunc::getRecord($table,-$id,'uid'))) {
03449
03450
03451 $swapVerBaseArray = array();
03452 foreach($keepFields as $fN) {
03453 $swapVerBaseArray[$fN] = $curVersion[$fN];
03454 }
03455 #debug($swapVerBaseArray);
03456
03457 if ($swapVersion['pid']==-1 && $swapVersion['t3ver_oid']==$id) {
03458 #debug($curVersion,'$curVersion');
03459 #debug($swapVersion,'$swapVersion');
03460 $sqlErrors=array();
03461
03462
03463 $sArray = array();
03464 $sArray['uid'] = -intval($id);
03465 $sArray['t3ver_oid'] = intval($swapWith);
03466 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table,'uid='.intval($id),$sArray);
03467 if ($GLOBALS['TYPO3_DB']->sql_error()) $sqlErrors[]=$GLOBALS['TYPO3_DB']->sql_error();
03468
03469
03470 $sArray = $swapVerBaseArray;
03471 $sArray['uid'] = intval($id);
03472 $sArray['t3ver_oid'] = intval($id);
03473 $sArray['pid'] = intval($curVersion['pid']);
03474 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table,'uid='.intval($swapWith),$sArray);
03475 if ($GLOBALS['TYPO3_DB']->sql_error()) $sqlErrors[]=$GLOBALS['TYPO3_DB']->sql_error();
03476
03477
03478 $sArray = array();
03479 $sArray['uid'] = intval($swapWith);
03480 $sArray['t3ver_oid'] = intval($id);
03481 $sArray['pid'] = -1;
03482 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table,'uid=-'.intval($id),$sArray);
03483 if ($GLOBALS['TYPO3_DB']->sql_error()) $sqlErrors[]=$GLOBALS['TYPO3_DB']->sql_error();
03484
03485 if (!count($sqlErrors)) {
03486 $this->log($table,$id,0,0,0,'Swapping successful for table "'.$table.'" uid '.$id.'=>'.$swapWith);
03487
03488
03489 if ($table=='pages' && $swapContent) {
03490
03491
03492 foreach($TCA as $tN => $tCfg) {
03493 if ($TCA[$tN]['ctrl']['versioning_followPages'] || ($tN=='pages' && $swapContent==='ALL')) {
03494 $temporaryPid = -($id+1000000);
03495
03496 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($tN,'pid='.intval($id),array('pid'=>$temporaryPid));
03497 if ($GLOBALS['TYPO3_DB']->sql_error()) $sqlErrors[]=$GLOBALS['TYPO3_DB']->sql_error();
03498
03499 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($tN,'pid='.intval($swapWith),array('pid'=>$id));
03500 if ($GLOBALS['TYPO3_DB']->sql_error()) $sqlErrors[]=$GLOBALS['TYPO3_DB']->sql_error();
03501
03502 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($tN,'pid='.intval($temporaryPid),array('pid'=>$swapWith));
03503 if ($GLOBALS['TYPO3_DB']->sql_error()) $sqlErrors[]=$GLOBALS['TYPO3_DB']->sql_error();
03504
03505 if (count($sqlErrors)) {
03506 $this->log($table,$id,0,0,1,'During Swapping: SQL errors happend: '.implode('; ',$sqlErrors));
03507 }
03508 }
03509 }
03510 }
03511
03512 $this->clear_cache($table,$id);
03513
03514 } else $this->log($table,$id,0,0,1,'During Swapping: SQL errors happend: '.implode('; ',$sqlErrors));
03515 } 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!');
03516 } 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!');
03517 } else $this->log($table,$id,0,0,1,'Error: Either online or swap version could not be selected!');
03518 } else $this->log($table,$id,0,0,1,'Error: You cannot swap versions for a record you do not have access to edit!');
03519 }
03520
03530 function int_pageTreeInfo($CPtable,$pid,$counter, $rootID) {
03531 if ($counter) {
03532 $addW = !$this->admin ? ' AND '.$this->BE_USER->getPagePermsClause($this->pMap['show']) : '';
03533 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'pid='.intval($pid).$this->deleteClause('pages').$addW, '', 'sorting DESC');
03534 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
03535 if ($row['uid']!=$rootID) {
03536 $CPtable[$row['uid']] = $pid;
03537 if ($counter-1) {
03538 $CPtable = $this->int_pageTreeInfo($CPtable,$row['uid'],$counter-1, $rootID);
03539 }
03540 }
03541 }
03542 }
03543 return $CPtable;
03544 }
03545
03551 function compileAdminTables() {
03552 global $TCA;
03553 reset ($TCA);
03554 $listArr = array();
03555 while (list($table)=each($TCA)) {
03556 $listArr[]=$table;
03557 }
03558 return $listArr;
03559 }
03560
03568 function fixUniqueInPid($table,$uid) {
03569 global $TCA;
03570 if ($TCA[$table]) {
03571 t3lib_div::loadTCA($table);
03572 reset ($TCA[$table]['columns']);
03573 $curData=$this->recordInfo($table,$uid,'*');
03574 $newData=array();
03575 while (list($field,$conf)=each($TCA[$table]['columns'])) {
03576 if ($conf['config']['type']=='input') {
03577 $evalCodesArray = t3lib_div::trimExplode(',',$conf['config']['eval'],1);
03578 if (in_array('uniqueInPid',$evalCodesArray)) {
03579 $newV = $this->getUnique($table,$field,$curData[$field],$uid,$curData['pid']);
03580 if (strcmp($newV,$curData[$field])) {
03581 $newData[$field]=$newV;
03582 }
03583 }
03584 }
03585 }
03586
03587 if (count($newData)) {
03588 $this->updateDB($table,$uid,$newData);
03589 }
03590 }
03591 }
03592
03604 function fixCopyAfterDuplFields($table,$uid,$prevUid,$update, $newData=array()) {
03605 global $TCA;
03606 if ($TCA[$table] && $TCA[$table]['ctrl']['copyAfterDuplFields']) {
03607 t3lib_div::loadTCA($table);
03608 $prevData=$this->recordInfo($table,$prevUid,'*');
03609 $theFields = t3lib_div::trimExplode(',',$TCA[$table]['ctrl']['copyAfterDuplFields'],1);
03610 reset($theFields);
03611 while(list(,$field)=each($theFields)) {
03612 if ($TCA[$table]['columns'][$field] && ($update || !isset($newData[$field]))) {
03613 $newData[$field]=$prevData[$field];
03614 }
03615 }
03616 if ($update && count($newData)) {
03617 $this->updateDB($table,$uid,$newData);
03618 }
03619 }
03620 return $newData;
03621 }
03622
03629 function extFileFields ($table) {
03630 global $TCA;
03631 $listArr=array();
03632 t3lib_div::loadTCA($table);
03633 if ($TCA[$table]['columns']) {
03634 reset($TCA[$table]['columns']);
03635 while (list($field,$configArr)=each($TCA[$table]['columns'])) {
03636 if ($configArr['config']['type']=='group' && $configArr['config']['internal_type']=='file') {
03637 $listArr[]=$field;
03638 }
03639 }
03640 }
03641 return $listArr;
03642 }
03643
03655 function getCopyHeader($table,$pid,$field,$value,$count,$prevTitle='') {
03656 global $TCA;
03657
03658
03659 if ($count) {
03660 $checkTitle = $value.rtrim(' '.sprintf($this->prependLabel($table),$count));
03661 } else {
03662 $checkTitle = $value;
03663 }
03664
03665
03666 if ($prevTitle != $checkTitle || $count<100) {
03667 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, 'pid='.intval($pid).' AND '.$field.'="'.$GLOBALS['TYPO3_DB']->quoteStr($checkTitle, $table).'"'.$this->deleteClause($table), '', '', '1');
03668 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
03669 return $this->getCopyHeader($table,$pid,$field,$value,$count+1,$checkTitle);
03670 }
03671 }
03672
03673
03674 return $checkTitle;
03675 }
03676
03684 function prependLabel($table) {
03685 global $TCA;
03686 if (is_object($GLOBALS['LANG'])) {
03687 $label = $GLOBALS['LANG']->sL($TCA[$table]['ctrl']['prependAtCopy']);
03688 } else {
03689 list($label) = explode('|',$TCA[$table]['ctrl']['prependAtCopy']);
03690 }
03691 return $label;
03692 }
03693
03701 function resolvePid($table,$pid) {
03702 global $TCA;
03703 $pid=intval($pid);
03704 if ($pid < 0) {
03705 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('pid', $table, 'uid='.abs($pid));
03706 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
03707 $pid = intval($row['pid']);
03708 }
03709 return $pid;
03710 }
03711
03719 function clearPrefixFromValue($table,$value) {
03720 global $TCA;
03721 $regex = sprintf(quotemeta($this->prependLabel($table)),'[0-9]*').'$';
03722 return @ereg_replace($regex,'',$value);
03723 }
03724
03730 function remapListedDBRecords() {
03731 global $TCA;
03732 #debug($this->registerDBList);
03733 #debug($this->copyMappingArray_merged);
03734 if (count($this->registerDBList)) {
03735 reset($this->registerDBList);
03736 while(list($table,$records)=each($this->registerDBList)) {
03737 t3lib_div::loadTCA($table);
03738 reset($records);
03739 while(list($uid,$fields)=each($records)) {
03740 $newData = array();
03741 $theUidToUpdate = $this->copyMappingArray_merged[$table][$uid];
03742
03743 foreach($fields as $fieldName => $value) {
03744 $conf = $TCA[$table]['columns'][$fieldName]['config'];
03745
03746 switch($conf['type']) {
03747 case 'group':
03748 case 'select':
03749 $vArray = $this->remapListedDBRecords_procDBRefs($conf, $value, $theUidToUpdate);
03750 if (is_array($vArray)) {
03751 $newData[$fieldName] = implode(',',$vArray);
03752 }
03753 break;
03754 case 'flex':
03755 if ($value=='FlexForm_reference') {
03756 $origRecordRow = $this->recordInfo($table,$theUidToUpdate,'*');
03757
03758 if (is_array($origRecordRow)) {
03759
03760
03761 $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $origRecordRow, $table);
03762 $currentValueArray = t3lib_div::xml2array($origRecordRow[$fieldName]);
03763 #debug($dataStructArray);
03764 #debug($currentValueArray);
03765 #debug($origRecordRow);
03766 #debug($currentValueArray['data']);
03767
03768 $currentValueArray['data'] = $this->checkValue_flex_procInData(
03769 $currentValueArray['data'],
03770 array(),
03771 array(),
03772 $dataStructArray,
03773 array($table,$theUidToUpdate,$fieldName),
03774 'remapListedDBRecords_flexFormCallBack'
03775 );
03776 #debug($currentValueArray['data']);
03777
03778 if (is_array($currentValueArray['data'])) {
03779 $newData[$fieldName] =
03780 '<?xml version="1.0" encoding="'.$GLOBALS['LANG']->charSet.'" standalone="yes" ?>'.chr(10).
03781 $this->checkValue_flexArray2Xml($currentValueArray);
03782 }
03783 }
03784 }
03785 break;
03786 default:
03787 debug('Field type should not appear here: '. $conf['type']);
03788 break;
03789 }
03790 }
03791
03792 if (count($newData)) {
03793 $this->updateDB($table,$theUidToUpdate,$newData);
03794 #debug($this->recordInfo($table,$theUidToUpdate,'*'),'Stored result:');
03795
03796 }
03797 }
03798 }
03799 }
03800 }
03801
03813 function remapListedDBRecords_flexFormCallBack($pParams, $dsConf, $dataValue, $dataValue_ext1, $dataValue_ext2) {
03814
03815
03816 list($table,$uid,$field) = $pParams;
03817
03818
03819 if ($this->isReferenceField($dsConf) && strlen($dataValue)) {
03820 $vArray = $this->remapListedDBRecords_procDBRefs($dsConf, $dataValue, $uid);
03821 if (is_array($vArray)) {
03822 $dataValue = implode(',',$vArray);
03823 }
03824 }
03825
03826
03827 return array('value' => $dataValue);
03828 }
03829
03839 function remapListedDBRecords_procDBRefs($conf, $value, $MM_localUid) {
03840
03841
03842 $set = FALSE;
03843 $allowedTables = $conf['type']=='group' ? $conf['allowed'] : $conf['foreign_table'].','.$conf['neg_foreign_table'];
03844 $prependName = $conf['type']=='group' ? $conf['prepend_tname'] : '';
03845 $dontRemapTables = t3lib_div::trimExplode(',',$conf['dontRemapTablesOnCopy'],1);
03846
03847
03848 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
03849 $dbAnalysis->registerNonTableValues = ($conf['type']=='select' && $conf['allowNonIdValues']) ? 1 : 0;
03850 $dbAnalysis->start($value, $allowedTables, $conf['MM'], $MM_localUid);
03851
03852
03853 foreach($dbAnalysis->itemArray as $k => $v) {
03854 $mapID = $this->copyMappingArray_merged[$v['table']][$v['id']];
03855 if ($mapID && !in_array($v['table'],$dontRemapTables)) {
03856 $dbAnalysis->itemArray[$k]['id'] = $mapID;
03857 $set = TRUE;
03858 }
03859 }
03860
03861
03862 if ($set) {
03863 if ($conf['MM']) {
03864 $dbAnalysis->writeMM($conf['MM'], $theUidToUpdate, $prependName);
03865 } else {
03866 $vArray = $dbAnalysis->getValueArray($prependName);
03867 if ($conf['type']=='select') {
03868 $vArray = $dbAnalysis->convertPosNeg($vArray, $conf['foreign_table'], $conf['neg_foreign_table']);
03869 }
03870 return $vArray;
03871 }
03872 }
03873 }
03874
03884 function extFileFunctions($table,$field,$filelist,$func) {
03885 global $TCA;
03886 t3lib_div::loadTCA($table);
03887 $uploadFolder = $TCA[$table]['columns'][$field]['config']['uploadfolder'];
03888 if ($uploadFolder && trim($filelist)) {
03889 $uploadPath = $this->destPathFromUploadFolder($uploadFolder);
03890 $fileArray = explode(',',$filelist);
03891 while (list(,$theFile)=each($fileArray)) {
03892 $theFile=trim($theFile);
03893 if ($theFile) {
03894 switch($func) {
03895 case 'deleteAll':
03896 if (@is_file($uploadPath.'/'.$theFile)) {
03897 unlink ($uploadPath.'/'.$theFile);
03898 } else {
03899 $this->log($table,0,3,0,100,"Delete: Referenced file that was supposed to be deleted together with it's record didn't exist");
03900 }
03901 break;
03902 }
03903 }
03904 }
03905 }
03906 }
03907
03916 function deleteRecord($table,$uid, $noRecordCheck) {
03917
03918
03919 global $TCA;
03920 $uid = intval($uid);
03921 if ($TCA[$table] && $uid) {
03922 $deleteRow = $TCA[$table]['ctrl']['delete'];
03923 if ($noRecordCheck || $this->doesRecordExist($table,$uid,'delete')) {
03924 if ($deleteRow) {
03925 $updateFields = array(
03926 $deleteRow => 1
03927 );
03928
03929
03930 if ($TCA[$table]['ctrl']['sortby']) {
03931 $updateFields[$TCA[$table]['ctrl']['sortby']] = 1000000000;
03932 }
03933
03934 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid='.intval($uid), $updateFields);
03935 } else {
03936
03937
03938 $fileFieldArr = $this->extFileFields($table);
03939 if (count($fileFieldArr)) {
03940 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(implode(',',$fileFieldArr), $table, 'uid='.intval($uid));
03941 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
03942 $fArray = $fileFieldArr;
03943
03944 foreach($fArray as $theField) {
03945 $this->extFileFunctions($table,$theField,$row[$theField],'deleteAll');
03946 }
03947 } else {
03948 $this->log($table,$uid,3,0,100,'Delete: Zero rows in result when trying to read filenames from record which should be deleted');
03949 }
03950 }
03951
03952 $GLOBALS['TYPO3_DB']->exec_DELETEquery($table, 'uid='.intval($uid));
03953 }
03954
03955 if (!$GLOBALS['TYPO3_DB']->sql_error()) {
03956 $this->log($table,$uid,3,0,0,'');
03957 } else {
03958 $this->log($table,$uid,3,0,100,$GLOBALS['TYPO3_DB']->sql_error());
03959 }
03960
03961 $this->clear_cache($table,$uid);
03962 } else {
03963 $this->log($table,$uid,3,0,1,'Attempt to delete record without delete-permissions');
03964 }
03965 }
03966 }
03967
03974 function deletePages($uid) {
03975 if ($this->doesRecordExist('pages',$uid,'delete')) {
03976 if ($this->deleteTree) {
03977 $brExist = $this->doesBranchExist('',$uid,$this->pMap['delete'],1);
03978 if ($brExist != -1) {
03979 if ($this->noRecordsFromUnallowedTables($brExist.$uid)) {
03980 $uidArray = explode(',',$brExist);
03981 while (list(,$listUid)=each($uidArray)) {
03982 if (trim($listUid)) {
03983 $this->deleteSpecificPage($listUid);
03984 }
03985 }
03986 $this->deleteSpecificPage($uid);
03987 } else {
03988 $this->log('pages',$uid,3,0,1,'Attempt to delete records from disallowed tables');
03989 }
03990 } else {
03991 $this->log('pages',$uid,3,0,1,'Attempt to delete pages in branch without permissions');
03992 }
03993 } else {
03994 $brExist = $this->doesBranchExist('',$uid,$this->pMap['delete'],1);
03995 if ($brExist == '') {
03996 if ($this->noRecordsFromUnallowedTables($uid)) {
03997 $this->deleteSpecificPage($uid);
03998 } else {
03999 $this->log('pages',$uid,3,0,1,'Attempt to delete records from disallowed tables');
04000 }
04001 } else {
04002 $this->log('pages',$uid,3,0,1,'Attempt to delete page which has subpages');
04003 }
04004 }
04005 } else {
04006 $this->log('pages',$uid,3,0,1,'Attempt to delete page without permissions');
04007 }
04008 }
04009
04016 function deleteSpecificPage($uid) {
04017
04018 global $TCA;
04019 reset ($TCA);
04020 $uid = intval($uid);
04021 if ($uid) {
04022 while (list($table)=each($TCA)) {
04023 if ($table!='pages') {
04024 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, 'pid='.intval($uid).$this->deleteClause($table));
04025 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($mres)) {
04026 $this->deleteRecord($table,$row['uid'], 1);
04027 }
04028 }
04029 }
04030 $this->deleteRecord('pages',$uid, 1);
04031 }
04032 }
04033
04040 function noRecordsFromUnallowedTables($inList) {
04041
04042 global $TCA;
04043 reset ($TCA);
04044 $inList = trim($this->rmComma(trim($inList)));
04045 if ($inList && !$this->admin) {
04046 while (list($table) = each($TCA)) {
04047 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('count(*)', $table, 'pid IN ('.$inList.')');
04048 $count = $GLOBALS['TYPO3_DB']->sql_fetch_row($mres);
04049 if ($count[0] && ($this->tableReadOnly($table) || !$this->checkModifyAccessList($table))) {
04050 return false;
04051 }
04052 }
04053 }
04054 return true;
04055 }
04056
04057
04058
04059
04060
04061
04062
04063
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084
04085
04086
04087
04102 function getSortNumber($table,$uid,$pid) {
04103 global $TCA;
04104 if ($TCA[$table] && $TCA[$table]['ctrl']['sortby']) {
04105 $sortRow = $TCA[$table]['ctrl']['sortby'];
04106 if ($pid>=0) {
04107 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($sortRow.',pid,uid', $table, 'pid='.intval($pid).$this->deleteClause($table), '', $sortRow.' ASC', '1');
04108 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
04109 if ($row['uid']==$uid) {
04110 return $row[$sortRow];
04111 }
04112 if ($row[$sortRow] < 1) {
04113 $this->resorting($table,$pid,$sortRow,0);
04114 return $this->sortIntervals;
04115 } else {
04116 return floor($row[$sortRow]/2);
04117 }
04118 } else {
04119 return $this->sortIntervals;
04120 }
04121 } else {
04122 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($sortRow.',pid,uid', $table, 'uid='.abs($pid).$this->deleteClause($table));
04123 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
04124 if ($row['uid']==$uid) {
04125 $sortNumber = $row[$sortRow];
04126 } else {
04127 $subres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
04128 $sortRow.',pid,uid',
04129 $table,
04130 'pid='.intval($row['pid']).' AND '.$sortRow.'>='.intval($row[$sortRow]).$this->deleteClause($table),
04131 '',
04132 $sortRow.' ASC',
04133 '2'
04134 );
04135 if ($GLOBALS['TYPO3_DB']->sql_num_rows($subres)==2) {
04136 $GLOBALS['TYPO3_DB']->sql_fetch_assoc($subres);
04137 $subrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($subres);
04138 $sortNumber = $row[$sortRow]+ floor(($subrow[$sortRow]-$row[$sortRow])/2);
04139 if ($sortNumber<=$row[$sortRow] || $sortNumber>=$subrow[$sortRow]) {
04140 $sortNumber = $this->resorting($table,$row['pid'],$sortRow, $row['uid']);
04141 }
04142 } else {
04143 $sortNumber = $row[$sortRow]+$this->sortIntervals;
04144 }
04145 }
04146 return Array('pid' => $row['pid'], 'sortNumber' => $sortNumber);
04147 } else {
04148 $propArr = $this->getRecordProperties($table,$uid);
04149 $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']);
04150 return false;
04151 }
04152 }
04153 }
04154 }
04155
04167 function resorting($table,$pid,$sortRow, $return_SortNumber_After_This_Uid) {
04168 global $TCA;
04169 if ($TCA[$table] && $sortRow && $TCA[$table]['ctrl']['sortby']==$sortRow) {
04170 $returnVal = 0;
04171 $intervals = $this->sortIntervals;
04172 $i = $intervals*2;
04173
04174 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', $table, 'pid='.intval($pid).$this->deleteClause($table), '', $sortRow.' ASC');
04175 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
04176 $uid=intval($row['uid']);
04177 if ($uid) {
04178 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid='.intval($uid), array($sortRow=>$i));
04179 if ($uid==$return_SortNumber_After_This_Uid) {
04180 $i = $i+$intervals;
04181 $returnVal=$i;
04182 }
04183 } else {die ('Fatal ERROR!! No Uid at resorting.');}
04184 $i = $i+$intervals;
04185 }
04186 return $returnVal;
04187 }
04188 }
04189
04196 function rmComma ($input) {
04197 return ereg_replace(',$','',$input);
04198 }
04199
04206 function convNumEntityToByteValue($input) {
04207 $token = md5(microtime());
04208 $parts = explode($token,ereg_replace('(&#([0-9]+);)',$token.'\2'.$token,$input));
04209
04210 foreach($parts as $k => $v) {
04211 if ($k%2) {
04212 $v = intval($v);
04213 if ($v > 32) {
04214 $parts[$k] =chr(intval($v));
04215 }
04216 }
04217 }
04218
04219 return implode('',$parts);
04220 }
04221
04228 function destPathFromUploadFolder ($folder) {
04229 return PATH_site.$folder;
04230 }
04231
04239 function destNotInsideSelf ($dest,$id) {
04240 $loopCheck = 100;
04241 $dest = intval($dest);
04242 $id = intval($id);
04243 if ($dest==$id) {
04244 return false;
04245 }
04246 while ($dest!=0 && $loopCheck>0) {
04247 $loopCheck--;
04248 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('pid, uid', 'pages', 'uid='.intval($dest).$this->deleteClause('pages'));
04249 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
04250 if ($row['pid']==$id) {
04251 return false;
04252 }
04253 } else {
04254 return false;
04255 }
04256 }
04257 return true;
04258 }
04259
04265 function getExcludeListArray() {
04266 global $TCA;
04267 $list = array();
04268 reset($TCA);
04269 while (list($table)=each($TCA)) {
04270 t3lib_div::loadTCA($table);
04271 while (list($field,$config)=each($TCA[$table]['columns'])) {
04272 if ($config['exclude'] && !t3lib_div::inList($this->BE_USER->groupData['non_exclude_fields'],$table.':'.$field)) {
04273 $list[]=$table.'-'.$field;
04274 }
04275 }
04276 }
04277 return $list;
04278 }
04279
04289 function doesPageHaveUnallowedTables($page_uid,$doktype) {
04290 global $TCA, $PAGES_TYPES;
04291 $page_uid = intval($page_uid);
04292 if (!$page_uid) {
04293 return FALSE;
04294 }
04295
04296 $allowedTableList = isset($PAGES_TYPES[$doktype]['allowedTables']) ? $PAGES_TYPES[$doktype]['allowedTables'] : $PAGES_TYPES['default']['allowedTables'];
04297 $allowedArray = t3lib_div::trimExplode(',',$allowedTableList,1);
04298 if (strstr($allowedTableList,'*')) {
04299 return FALSE;
04300 }
04301
04302 reset ($TCA);
04303 $tableList = array();
04304 while (list($table)=each($TCA)) {
04305 if (!in_array($table,$allowedArray)) {
04306 $mres = $GLOBALS['TYPO3_DB']->exec_SELECTquery('count(*)', $table, 'pid='.intval($page_uid));
04307 $count = $GLOBALS['TYPO3_DB']->sql_fetch_row($mres);
04308 if ($count[0]) {
04309 $tableList[]=$table;
04310 }
04311 }
04312 }
04313 return implode(',',$tableList);
04314 }
04315
04322 function deleteClause($table) {
04323
04324 global $TCA;
04325 if ($TCA[$table]['ctrl']['delete']) {
04326 return ' AND NOT '.$table.'.'.$TCA[$table]['ctrl']['delete'];
04327 } else {
04328 return '';
04329 }
04330 }
04331
04338 function tableReadOnly($table) {
04339
04340 global $TCA;
04341 return ($TCA[$table]['ctrl']['readOnly'] ? 1 : 0);
04342 }
04343
04350 function tableAdminOnly($table) {
04351
04352 global $TCA;
04353 return ($TCA[$table]['ctrl']['adminOnly'] ? 1 : 0);
04354 }
04355
04364 function getInterfacePagePositionID($uid) {
04365 global $TCA;
04366 $perms_clause = $this->BE_USER->getPagePermsClause(1);
04367 $deleted = $TCA['pages']['ctrl']['delete'] ? 'AND NOT A.'.$TCA['pages']['ctrl']['delete'].' AND NOT pages.'.$TCA['pages']['ctrl']['delete'].' ' : '';
04368
04369
04370 $subres = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
04371 'pages.uid, pages.pid',
04372 'pages AS A, pages',
04373 'A.pid=pages.pid AND A.uid="'.$uid.'"
04374 '.$deleted.'
04375 AND pages.sorting<=A.sorting
04376 AND '.$perms_clause,
04377 '',
04378 'pages.sorting DESC',
04379 '2'
04380 );
04381 if ($GLOBALS['TYPO3_DB']->sql_num_rows($subres)==2) {
04382 $GLOBALS['TYPO3_DB']->sql_fetch_assoc($subres);
04383 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($subres);
04384 return -$row['uid'];
04385 } else {
04386 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($subres);
04387 return $row['pid'];
04388 }
04389 }
04390
04397 function isReferenceField($conf) {
04398 return ($conf['type']=='group' && $conf['internal_type']=='db') || ($conf['type']=='select' && $conf['foreign_table']);
04399 }
04400
04407 function getTCEMAIN_TSconfig($tscPID) {
04408 if (!isset($this->cachedTSconfig[$tscPID])) {
04409 $this->cachedTSconfig[$tscPID] = $this->BE_USER->getTSConfig('TCEMAIN',t3lib_BEfunc::getPagesTSconfig($tscPID));
04410 }
04411 return $this->cachedTSconfig[$tscPID]['properties'];
04412 }
04413
04421 function getTableEntries($table,$TSconfig) {
04422 $tA = is_array($TSconfig['table.'][$table.'.']) ? $TSconfig['table.'][$table.'.'] : array();;
04423 $dA = is_array($TSconfig['default.']) ? $TSconfig['default.'] : array();
04424 return t3lib_div::array_merge_recursive_overrule($dA,$tA);
04425 }
04426
04435 function setHistory($table,$id,$logId) {
04436 if (isset($this->historyRecords[$table.':'.$id])) {
04437
04438 list($tscPID) = t3lib_BEfunc::getTSCpid($table,$id,'');
04439 $TSConfig = $this->getTCEMAIN_TSconfig($tscPID);
04440
04441 $tE = $this->getTableEntries($table,$TSConfig);
04442 $keepEntries = strcmp($tE['history.']['keepEntries'],'') ? t3lib_div::intInRange($tE['history.']['keepEntries'],0,200) : 10;
04443 $maxAgeSeconds = 60*60*24*(strcmp($tE['history.']['maxAgeDays'],'') ? t3lib_div::intInRange($tE['history.']['maxAgeDays'],0,200) : 7);
04444 $this->clearHistory($table,$id,t3lib_div::intInRange($keepEntries-1,0),$maxAgeSeconds);
04445
04446 if ($keepEntries) {
04447 $fields_values = array();
04448 $fields_values['history_data'] = serialize($this->historyRecords[$table.':'.$id]);
04449 $fields_values['fieldlist'] = implode(',',array_keys($this->historyRecords[$table.':'.$id]['newRecord']));
04450 $fields_values['tstamp'] = time();
04451 $fields_values['tablename'] = $table;
04452 $fields_values['recuid'] = $id;
04453 $fields_values['sys_log_uid'] = $logId;
04454
04455 $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_history', $fields_values);
04456 }
04457 }
04458 }
04459
04472 function clearHistory($table,$id,$keepEntries=10,$maxAgeSeconds=604800) {
04473 $tstampLimit = $maxAgeSeconds ? time()-$maxAgeSeconds : 0;
04474
04475 $where = '
04476 tablename="'.$GLOBALS['TYPO3_DB']->quoteStr($table, 'sys_history').'"
04477 AND recuid='.intval($id).'
04478 AND snapshot=0';
04479
04480 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,tstamp', 'sys_history', $where, '', 'uid DESC', intval($keepEntries).',1');
04481 $resRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
04482 if ($tstampLimit && intval($resRow['tstamp'])<$tstampLimit) {
04483 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,tstamp', 'sys_history', $where.' AND tstamp<'.intval($tstampLimit), '', 'uid DESC', '1');
04484 $resRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
04485
04486 $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_history', $where.' AND uid<='.intval($resRow['uid']));
04487 } elseif (is_array($resRow)) {
04488 $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_history', $where.' AND uid<='.intval($resRow['uid']));
04489 }
04490 }
04491
04520 function log($table,$recuid,$action,$recpid,$error,$details,$details_nr=0,$data=array(),$event_pid=-1,$NEWid='') {
04521 if ($this->enableLogging) {
04522 $type=1;
04523 if (!$this->storeLogMessages) {$details='';}
04524 return $this->BE_USER->writelog($type,$action,$error,$details_nr,$details,$data,$table,$recuid,$recpid,$event_pid,$NEWid);
04525 }
04526 }
04527
04534 function printLogErrorMessages($redirect) {
04535 $res_log = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
04536 '*',
04537 'sys_log',
04538 'type=1 AND userid='.intval($this->BE_USER->user['uid']).' AND tstamp='.intval($GLOBALS['EXEC_TIME']).' AND error!=0'
04539 );
04540 $errorJS = array();
04541 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res_log)) {
04542 $log_data = unserialize($row['log_data']);
04543 $errorJS[] = $row[error].': '.sprintf($row['details'], $log_data[0],$log_data[1],$log_data[2],$log_data[3],$log_data[4]);
04544 }
04545
04546 if (count($errorJS)) {
04547 $error_doc = t3lib_div::makeInstance('template');
04548 $error_doc->backPath = '';
04549
04550 $content.= $error_doc->startPage('tce_db.php Error output');
04551
04552 $lines[] = '
04553 <tr class="bgColor5">
04554 <td colspan="2" align="center"><strong>Errors:</strong></td>
04555 </tr>';
04556
04557 foreach($errorJS as $line) {
04558 $lines[] = '
04559 <tr class="bgColor4">
04560 <td valign="top"><img'.t3lib_iconWorks::skinImg('','gfx/icon_fatalerror.gif','width="18" height="16"').' alt="" /></td>
04561 <td>'.htmlspecialchars($line).'</td>
04562 </tr>';
04563 }
04564
04565 $lines[] = '
04566 <tr>
04567 <td colspan="2" align="center"><br />'.
04568 '<form action=""><input type="submit" value="Continue" onclick="'.htmlspecialchars('document.location=\''.$redirect.'\';return false;').'"></form>'.
04569 '</td>
04570 </tr>';
04571
04572 $content.= '
04573 <br/><br/>
04574 <table border="0" cellpadding="1" cellspacing="1" width="300" align="center">
04575 '.implode('',$lines).'
04576 </table>';
04577
04578 $content.= $error_doc->endPage();
04579 echo $content;
04580 exit;
04581 }
04582 }
04583
04596 function clear_cacheCmd($cacheCmd) {
04597 global $TYPO3_CONF_VARS;
04598
04599
04600 switch($cacheCmd) {
04601 case 'pages':
04602 if ($this->admin || $this->BE_USER->getTSConfigVal('options.clearCache.pages')) {
04603 if (t3lib_extMgm::isLoaded('cms')) {
04604 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages','');
04605 }
04606 }
04607 break;
04608 case 'all':
04609 if ($this->admin || $this->BE_USER->getTSConfigVal('options.clearCache.all')) {
04610 if (t3lib_extMgm::isLoaded('cms')) {
04611 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages','');
04612 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pagesection','');
04613 }
04614 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_hash','');
04615
04616
04617 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearAllCache_additionalTables'])) {
04618 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearAllCache_additionalTables'] as $tableName) {
04619 if (!ereg('[^[:alnum:]_]',$tableName) && substr($tableName,-5)=='cache') {
04620 $GLOBALS['TYPO3_DB']->exec_DELETEquery($tableName,'');
04621 } else {
04622 die('Fatal Error: Trying to flush table "'.$tableName.'" with "Clear All Cache"');
04623 }
04624 }
04625 }
04626 }
04627 break;
04628 case 'temp_CACHED':
04629 if ($this->admin && $TYPO3_CONF_VARS['EXT']['extCache']) {
04630 $this->removeCacheFiles();
04631 }
04632 break;
04633 }
04634
04635
04636 if (t3lib_div::testInt($cacheCmd)) {
04637 if (t3lib_extMgm::isLoaded('cms')) {
04638 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages', 'page_id='.intval($cacheCmd));
04639 }
04640 }
04641
04642
04643 if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc'])) {
04644 $_params = array('cacheCmd'=>$cacheCmd);
04645 foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc'] as $_funcRef) {
04646 t3lib_div::callUserFunction($_funcRef,$_params,$this);
04647 }
04648 }
04649 }
04650
04656 function removeCacheFiles() {
04657 $cacheFiles=t3lib_extMgm::currentCacheFiles();
04658 $out=0;
04659 if (is_array($cacheFiles)) {
04660 reset($cacheFiles);
04661 while(list(,$cfile)=each($cacheFiles)) {
04662 @unlink($cfile);
04663 clearstatcache();
04664 $out++;
04665 }
04666 }
04667
04668 return $out;
04669 }
04670 }
04671
04672
04673
04674
04675
04676
04677
04678
04679
04680
04681
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693
04694
04695
04696
04697
04698
04699
04700
04701
04702
04703
04704
04705
04706
04707
04708
04709
04710
04711
04712
04713 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tcemain.php']) {
04714 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_tcemain.php']);
04715 }
04716 ?>