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
00064 require_once(PATH_t3lib.'class.t3lib_tcemain.php');
00065 require_once(PATH_t3lib.'class.t3lib_flexformtools.php');
00066
00067
00068
00083 class t3lib_refindex {
00084
00085 var $temp_flexRelations = array();
00086 var $errorLog = array();
00087 var $WSOL = FALSE;
00088 var $relations = array();
00089 var $hashVersion = 1;
00090
00091
00101 function updateRefIndexTable($table,$uid,$testOnly=FALSE) {
00102
00103
00104 $this->WSOL = FALSE;
00105
00106
00107 $result = array(
00108 'keptNodes' => 0,
00109 'deletedNodes' => 0,
00110 'addedNodes' => 0
00111 );
00112
00113
00114 $currentRels = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
00115 '*',
00116 'sys_refindex',
00117 'tablename='.$GLOBALS['TYPO3_DB']->fullQuoteStr($table,'sys_refindex').
00118 ' AND recuid='.intval($uid),
00119 '','','','hash'
00120 );
00121
00122
00123 if (t3lib_BEfunc::getRecordRaw($table,'uid='.intval($uid),'uid')) {
00124
00125
00126 $relations = $this->generateRefIndexData($table,$uid);
00127
00128 if (is_array($relations)) {
00129
00130
00131 foreach($relations as $k => $datRec) {
00132 $relations[$k]['hash'] = md5(implode('
00133
00134
00135 if (isset($currentRels[$relations[$k]['hash']])) {
00136 unset($currentRels[$relations[$k]['hash']]);
00137 $result['keptNodes']++;
00138 $relations[$k]['_ACTION'] = 'KEPT';
00139 } else {
00140
00141 if (!$testOnly) $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_refindex',$relations[$k]);
00142 $result['addedNodes']++;
00143 $relations[$k]['_ACTION'] = 'ADDED';
00144 }
00145 }
00146
00147 $result['relations'] = $relations;
00148 } else return FALSE;
00149 }
00150
00151
00152 if (count($currentRels)) {
00153 $hashList = array_keys($currentRels);
00154 if (count($hashList)) {
00155 $result['deletedNodes'] = count($hashList);
00156 $result['deletedNodes_hashList'] = implode(',',$hashList);
00157 if (!$testOnly) $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_refindex','hash IN ('.implode(',',$GLOBALS['TYPO3_DB']->fullQuoteArray($hashList,'sys_refindex')).')');
00158 }
00159 }
00160
00161 return $result;
00162 }
00163
00172 function generateRefIndexData($table,$uid) {
00173 global $TCA;
00174
00175 if (isset($TCA[$table])) {
00176
00177 list($record) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*',$table,'uid='.intval($uid));
00178
00179 if (is_array($record)) {
00180
00181
00182 $deleted = $TCA[$table]['ctrl']['delete'] ? ($record[$TCA[$table]['ctrl']['delete']]?1:0) : 0;
00183
00184
00185 $dbrels = $this->getRelations($table,$record);
00186
00187
00188 $this->relations = array();
00189 foreach($dbrels as $fieldname => $dat) {
00190
00191
00192 switch((string)$dat['type']) {
00193 case 'db':
00194 $this->createEntryData_dbRels($table,$uid,$fieldname,'',$deleted,$dat['itemArray']);
00195 break;
00196 case 'file':
00197 $this->createEntryData_fileRels($table,$uid,$fieldname,'',$deleted,$dat['newValueFiles']);
00198 break;
00199 case 'flex':
00200
00201 if (is_array($dat['flexFormRels']['db'])) {
00202 foreach($dat['flexFormRels']['db'] as $flexpointer => $subList) {
00203 $this->createEntryData_dbRels($table,$uid,$fieldname,$flexpointer,$deleted,$subList);
00204 }
00205 }
00206
00207 if (is_array($dat['flexFormRels']['file'])) {
00208 foreach($dat['flexFormRels']['file'] as $flexpointer => $subList) {
00209 $this->createEntryData_fileRels($table,$uid,$fieldname,$flexpointer,$deleted,$subList);
00210 }
00211 }
00212
00213 if (is_array($dat['flexFormRels']['softrefs'])) {
00214 foreach($dat['flexFormRels']['softrefs'] as $flexpointer => $subList) {
00215 $this->createEntryData_softreferences($table,$uid,$fieldname,$flexpointer,$deleted,$subList['keys']);
00216 }
00217 }
00218 break;
00219 }
00220
00221
00222 if (is_array($dat['softrefs'])) {
00223 $this->createEntryData_softreferences($table,$uid,$fieldname,'',$deleted,$dat['softrefs']['keys']);
00224 }
00225 }
00226
00227 return $this->relations;
00228 }
00229 }
00230 }
00231
00249 function createEntryData($table,$uid,$field,$flexpointer,$deleted,$ref_table,$ref_uid,$ref_string='',$sort=-1,$softref_key='',$softref_id='') {
00250 return array(
00251 'tablename' => $table,
00252 'recuid' => $uid,
00253 'field' => $field,
00254 'flexpointer' => $flexpointer,
00255 'softref_key' => $softref_key,
00256 'softref_id' => $softref_id,
00257 'sorting' => $sort,
00258 'deleted' => $deleted,
00259 'ref_table' => $ref_table,
00260 'ref_uid' => $ref_uid,
00261 'ref_string' => $ref_string,
00262 );
00263 }
00264
00276 function createEntryData_dbRels($table,$uid,$fieldname,$flexpointer,$deleted,$items) {
00277 foreach($items as $sort => $i) {
00278 $this->relations[] = $this->createEntryData($table,$uid,$fieldname,$flexpointer,$deleted,$i['table'],$i['id'],'',$sort);
00279 }
00280 }
00281
00293 function createEntryData_fileRels($table,$uid,$fieldname,$flexpointer,$deleted,$items) {
00294 foreach($items as $sort => $i) {
00295 $filePath = $i['ID_absFile'];
00296 if (t3lib_div::isFirstPartOfStr($filePath,PATH_site)) {
00297 $filePath = substr($filePath,strlen(PATH_site));
00298 }
00299 $this->relations[] = $this->createEntryData($table,$uid,$fieldname,$flexpointer,$deleted,'_FILE',0,$filePath,$sort);
00300 }
00301 }
00302
00314 function createEntryData_softreferences($table,$uid,$fieldname,$flexpointer,$deleted,$keys) {
00315 if (is_array($keys)) {
00316 foreach($keys as $spKey => $elements) {
00317 if (is_array($elements)) {
00318 foreach($elements as $subKey => $el) {
00319 if (is_array($el['subst'])) {
00320 switch((string)$el['subst']['type']) {
00321 case 'db':
00322 list($tableName,$recordId) = explode(':',$el['subst']['recordRef']);
00323 $this->relations[] = $this->createEntryData($table,$uid,$fieldname,$flexpointer,$deleted,$tableName,$recordId,'',-1,$spKey,$subKey);
00324 break;
00325 case 'file':
00326 $this->relations[] = $this->createEntryData($table,$uid,$fieldname,$flexpointer,$deleted,'_FILE',0,$el['subst']['relFileName'],-1,$spKey,$subKey);
00327 break;
00328 case 'string':
00329 $this->relations[] = $this->createEntryData($table,$uid,$fieldname,$flexpointer,$deleted,'_STRING',0,$el['subst']['tokenValue'],-1,$spKey,$subKey);
00330 break;
00331 }
00332 }
00333 }
00334 }
00335 }
00336 }
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00369 function getRelations($table,$row) {
00370 global $TCA;
00371
00372
00373 t3lib_div::loadTCA($table);
00374
00375
00376 $uid = $row['uid'];
00377 $nonFields = explode(',','uid,perms_userid,perms_groupid,perms_user,perms_group,perms_everybody,pid');
00378
00379 $outRow = array();
00380 foreach($row as $field => $value) {
00381 if (!in_array($field,$nonFields) && is_array($TCA[$table]['columns'][$field])) {
00382 $conf = $TCA[$table]['columns'][$field]['config'];
00383
00384
00385 if ($result = $this->getRelations_procFiles($value, $conf, $uid)) {
00386
00387 $outRow[$field] = array(
00388 'type' => 'file',
00389 'newValueFiles' => $result,
00390 );
00391 }
00392
00393
00394 if ($result = $this->getRelations_procDB($value, $conf, $uid)) {
00395
00396 $outRow[$field] = array(
00397 'type' => 'db',
00398 'itemArray' => $result,
00399 );
00400 }
00401
00402
00403 if ($conf['type']=='flex') {
00404
00405
00406 $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $row, $table,'',$this->WSOL);
00407 $currentValueArray = t3lib_div::xml2array($value);
00408
00409
00410 if (is_array($currentValueArray)) {
00411 $this->temp_flexRelations = array(
00412 'db' => array(),
00413 'file' => array(),
00414 'softrefs' => array()
00415 );
00416
00417
00418 $flexObj = t3lib_div::makeInstance('t3lib_flexformtools');
00419 $flexObj->traverseFlexFormXMLData($table,$field,$row,$this,'getRelations_flexFormCallBack');
00420
00421
00422 $outRow[$field] = array(
00423 'type' => 'flex',
00424 'flexFormRels' => $this->temp_flexRelations,
00425 );
00426 }
00427 }
00428
00429
00430 if (strlen($value) && $softRefs = t3lib_BEfunc::explodeSoftRefParserList($conf['softref'])) {
00431 $softRefValue = $value;
00432 foreach($softRefs as $spKey => $spParams) {
00433 $softRefObj = &t3lib_BEfunc::softRefParserObj($spKey);
00434 if (is_object($softRefObj)) {
00435 $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams);
00436 if (is_array($resultArray)) {
00437 $outRow[$field]['softrefs']['keys'][$spKey] = $resultArray['elements'];
00438 if (strlen($resultArray['content'])) {
00439 $softRefValue = $resultArray['content'];
00440 }
00441 }
00442 }
00443 }
00444
00445 if (is_array($outRow[$field]['softrefs']) && count($outRow[$field]['softrefs']) && strcmp($value,$softRefValue) && strstr($softRefValue,'{softref:')) {
00446 $outRow[$field]['softrefs']['tokenizedContent'] = $softRefValue;
00447 }
00448 }
00449 }
00450 }
00451
00452 return $outRow;
00453 }
00454
00466 function getRelations_flexFormCallBack($dsArr, $dataValue, $PA, $structurePath, &$pObj) {
00467 $structurePath = substr($structurePath,5).'/';
00468
00469 $dsConf = $dsArr['TCEforms']['config'];
00470
00471
00472 list($table, $uid, $field) = array($PA['table'],$PA['uid'],$PA['field']);
00473
00474
00475 if ($result = $this->getRelations_procFiles($dataValue, $dsConf, $uid)) {
00476
00477
00478 $this->temp_flexRelations['file'][$structurePath] = $result;
00479 }
00480
00481
00482 if ($result = $this->getRelations_procDB($dataValue, $dsConf, $uid)) {
00483
00484
00485 $this->temp_flexRelations['db'][$structurePath] = $result;
00486 }
00487
00488
00489 if (strlen($dataValue) && $softRefs = t3lib_BEfunc::explodeSoftRefParserList($dsConf['softref'])) {
00490 $softRefValue = $dataValue;
00491 foreach($softRefs as $spKey => $spParams) {
00492 $softRefObj = &t3lib_BEfunc::softRefParserObj($spKey);
00493 if (is_object($softRefObj)) {
00494 $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams, $structurePath);
00495 if (is_array($resultArray) && is_array($resultArray['elements'])) {
00496 $this->temp_flexRelations['softrefs'][$structurePath]['keys'][$spKey] = $resultArray['elements'];
00497 if (strlen($resultArray['content'])) $softRefValue = $resultArray['content'];
00498 }
00499 }
00500 }
00501
00502 if (count($this->temp_flexRelations['softrefs']) && strcmp($dataValue,$softRefValue)) {
00503 $this->temp_flexRelations['softrefs'][$structurePath]['tokenizedContent'] = $softRefValue;
00504 }
00505 }
00506 }
00507
00516 function getRelations_procFiles($value, $conf, $uid) {
00517
00518 if ($conf['type']=='group' && $conf['internal_type']=='file') {
00519
00520
00521 if ($conf['MM']) {
00522 $theFileValues = array();
00523 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
00524 $dbAnalysis->start('', 'files', $conf['MM'], $uid);
00525
00526 foreach($dbAnalysis->itemArray as $somekey => $someval) {
00527 if ($someval['id']) {
00528 $theFileValues[] = $someval['id'];
00529 }
00530 }
00531 } else {
00532 $theFileValues = explode(',',$value);
00533 }
00534
00535
00536 $uploadFolder = $conf['uploadfolder'];
00537 $dest = $this->destPathFromUploadFolder($uploadFolder);
00538 $newValue = array();
00539 $newValueFiles = array();
00540
00541 foreach($theFileValues as $file) {
00542 if (trim($file)) {
00543 $realFile = $dest.'/'.trim($file);
00544 if (@is_file($realFile)) {
00545 $newValueFiles[] = array(
00546 'filename' => $file,
00547 'ID' => md5($realFile),
00548 'ID_absFile' => $realFile
00549 );
00550 } else $this->error('Missing file: '.$realFile);
00551 }
00552 }
00553
00554 return $newValueFiles;
00555 }
00556 }
00557
00566 function getRelations_procDB($value, $conf, $uid) {
00567
00568
00569 if ($this->isReferenceField($conf)) {
00570 $allowedTables = $conf['type']=='group' ? $conf['allowed'] : $conf['foreign_table'].','.$conf['neg_foreign_table'];
00571 $prependName = $conf['type']=='group' ? $conf['prepend_tname'] : $conf['neg_foreign_table'];
00572
00573 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup');
00574 $dbAnalysis->start($value,$allowedTables,$conf['MM'],$uid);
00575
00576 return $dbAnalysis->itemArray;
00577 }
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00603 function isReferenceField($conf) {
00604 return ($conf['type']=='group' && $conf['internal_type']=='db') || ($conf['type']=='select' && $conf['foreign_table']);
00605 }
00606
00613 function destPathFromUploadFolder($folder) {
00614 return PATH_site.$folder;
00615 }
00616
00623 function error($msg) {
00624 $this->errorLog[]=$msg;
00625 }
00626
00634 function updateIndex($testOnly,$cli_echo=FALSE) {
00635 global $TCA, $TYPO3_DB;
00636
00637 $errors = array();
00638 $tableNames = array();
00639 $recCount=0;
00640 $tableCount=0;
00641
00642 $headerContent = $testOnly ? 'Reference Index TESTED (nothing written)' : 'Reference Index Updated';
00643 if ($cli_echo) echo
00644 '*******************************************'.chr(10).
00645 $headerContent.chr(10).
00646 '*******************************************'.chr(10);
00647
00648
00649 foreach ($TCA as $tableName => $cfg) {
00650 $tableNames[] = $tableName;
00651 $tableCount++;
00652
00653
00654 $allRecs = $TYPO3_DB->exec_SELECTgetRows('uid',$tableName,'1=1');
00655 $uidList = array(0);
00656 foreach ($allRecs as $recdat) {
00657 $refIndexObj = t3lib_div::makeInstance('t3lib_refindex');
00658 $result = $refIndexObj->updateRefIndexTable($tableName,$recdat['uid'],$testOnly);
00659 $uidList[]= $recdat['uid'];
00660 $recCount++;
00661
00662 if ($result['addedNodes'] || $result['deletedNodes']) {
00663 $Err = 'Record '.$tableName.':'.$recdat['uid'].' had '.$result['addedNodes'].' added indexes and '.$result['deletedNodes'].' deleted indexes';
00664 $errors[]= $Err;
00665 if ($cli_echo) echo $Err.chr(10);
00666 #$errors[] = t3lib_div::view_array($result);
00667 }
00668 }
00669
00670
00671 $where = 'tablename='.$TYPO3_DB->fullQuoteStr($tableName,'sys_refindex').' AND recuid NOT IN ('.implode(',',$uidList).')';
00672 $lostIndexes = $TYPO3_DB->exec_SELECTgetRows('hash','sys_refindex',$where);
00673 if (count($lostIndexes)) {
00674 $Err = 'Table '.$tableName.' has '.count($lostIndexes).' lost indexes which are now deleted';
00675 $errors[]= $Err;
00676 if ($cli_echo) echo $Err.chr(10);
00677 if (!$testOnly) $TYPO3_DB->exec_DELETEquery('sys_refindex',$where);
00678 }
00679 }
00680
00681
00682 $where = 'tablename NOT IN ('.implode(',',$TYPO3_DB->fullQuoteArray($tableNames,'sys_refindex')).')';
00683 $lostTables = $TYPO3_DB->exec_SELECTgetRows('hash','sys_refindex',$where);
00684 if (count($lostTables)) {
00685 $Err = 'Index table hosted '.count($lostTables).' indexes for non-existing tables, now removed';
00686 $errors[]= $Err;
00687 if ($cli_echo) echo $Err.chr(10);
00688 if (!$testOnly) $TYPO3_DB->exec_DELETEquery('sys_refindex',$where);
00689 }
00690
00691 $testedHowMuch = $recCount.' records from '.$tableCount.' tables were checked/updated.'.chr(10);
00692
00693 $bodyContent = $testedHowMuch.(count($errors)?implode(chr(10),$errors):'Index Integrity was perfect!');
00694 if ($cli_echo) echo $testedHowMuch.(count($errors)?'Updates: '.count($errors):'Index Integrity was perfect!').chr(10);
00695
00696 return array($headerContent,$bodyContent);
00697 }
00698 }
00699
00700
00701 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_refindex.php']) {
00702 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_refindex.php']);
00703 }
00704 ?>