Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00063 require_once(PATH_t3lib.'class.t3lib_tcemain.php'); 00064 require_once(PATH_t3lib.'class.t3lib_flexformtools.php'); 00065 //require_once(PATH_typo3.'sysext/indexed_search/class.lexer.php'); // Disabled until Kasper finishes this feature. Apart from that, t3lib classes should never require stuff from extensions. 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 00090 var $words_strings = array(); 00091 var $words = array(); 00092 00093 var $hashVersion = 1; // Number which we can increase if a change in the code means we will have to force a re-generation of the index. 00094 00095 00105 function updateRefIndexTable($table,$uid,$testOnly=FALSE) { 00106 00107 // First, secure that the index table is not updated with workspace tainted relations: 00108 $this->WSOL = FALSE; 00109 00110 // Init: 00111 $result = array( 00112 'keptNodes' => 0, 00113 'deletedNodes' => 0, 00114 'addedNodes' => 0 00115 ); 00116 00117 // Get current index from Database: 00118 $currentRels = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00119 '*', 00120 'sys_refindex', 00121 'tablename='.$GLOBALS['TYPO3_DB']->fullQuoteStr($table,'sys_refindex'). 00122 ' AND recuid='.intval($uid), 00123 '','','','hash' 00124 ); 00125 00126 // First, test to see if the record exists (including deleted-flagged) 00127 if (t3lib_BEfunc::getRecordRaw($table,'uid='.intval($uid),'uid')) { 00128 00129 // Then, get relations: 00130 $relations = $this->generateRefIndexData($table,$uid); 00131 00132 if (is_array($relations)) { 00133 00134 // Traverse the generated index: 00135 foreach($relations as $k => $datRec) { 00136 $relations[$k]['hash'] = md5(implode(' 00137 00138 // First, check if already indexed and if so, unset that row (so in the end we know which rows to remove!) 00139 if (isset($currentRels[$relations[$k]['hash']])) { 00140 unset($currentRels[$relations[$k]['hash']]); 00141 $result['keptNodes']++; 00142 $relations[$k]['_ACTION'] = 'KEPT'; 00143 } else { 00144 // If new, add it: 00145 if (!$testOnly) $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_refindex',$relations[$k]); 00146 $result['addedNodes']++; 00147 $relations[$k]['_ACTION'] = 'ADDED'; 00148 } 00149 } 00150 00151 $result['relations'] = $relations; 00152 } else return FALSE; // Weird mistake I would say... 00153 00154 // Words: 00155 if (!$testOnly) $this->wordIndexing($table,$uid); 00156 } 00157 00158 // If any old are left, remove them: 00159 if (count($currentRels)) { 00160 $hashList = array_keys($currentRels); 00161 if (count($hashList)) { 00162 $result['deletedNodes'] = count($hashList); 00163 $result['deletedNodes_hashList'] = implode(',',$hashList); 00164 if (!$testOnly) $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_refindex','hash IN ('.implode(',',$GLOBALS['TYPO3_DB']->fullQuoteArray($hashList,'sys_refindex')).')'); 00165 } 00166 } 00167 00168 return $result; 00169 } 00170 00179 function generateRefIndexData($table,$uid) { 00180 global $TCA; 00181 00182 if (isset($TCA[$table])) { 00183 // Get raw record from DB: 00184 list($record) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*',$table,'uid='.intval($uid)); 00185 00186 if (is_array($record)) { 00187 00188 // Initialize: 00189 $this->words_strings = array(); 00190 $this->words = array(); 00191 00192 // Deleted: 00193 $deleted = $TCA[$table]['ctrl']['delete'] ? ($record[$TCA[$table]['ctrl']['delete']]?1:0) : 0; 00194 00195 // Get all relations from record: 00196 $dbrels = $this->getRelations($table,$record); 00197 00198 // Traverse those relations, compile records to insert in table: 00199 $this->relations = array(); 00200 foreach($dbrels as $fieldname => $dat) { 00201 00202 // Based on type, 00203 switch((string)$dat['type']) { 00204 case 'db': 00205 $this->createEntryData_dbRels($table,$uid,$fieldname,'',$deleted,$dat['itemArray']); 00206 break; 00207 case 'file': 00208 $this->createEntryData_fileRels($table,$uid,$fieldname,'',$deleted,$dat['newValueFiles']); 00209 break; 00210 case 'flex': 00211 // DB references: 00212 if (is_array($dat['flexFormRels']['db'])) { 00213 foreach($dat['flexFormRels']['db'] as $flexpointer => $subList) { 00214 $this->createEntryData_dbRels($table,$uid,$fieldname,$flexpointer,$deleted,$subList); 00215 } 00216 } 00217 // File references (NOT TESTED!) 00218 if (is_array($dat['flexFormRels']['file'])) { // Not tested 00219 foreach($dat['flexFormRels']['file'] as $flexpointer => $subList) { 00220 $this->createEntryData_fileRels($table,$uid,$fieldname,$flexpointer,$deleted,$subList); 00221 } 00222 } 00223 // Soft references in flexforms (NOT TESTED!) 00224 if (is_array($dat['flexFormRels']['softrefs'])) { 00225 foreach($dat['flexFormRels']['softrefs'] as $flexpointer => $subList) { 00226 $this->createEntryData_softreferences($table,$uid,$fieldname,$flexpointer,$deleted,$subList['keys']); 00227 } 00228 } 00229 break; 00230 } 00231 00232 // Softreferences in the field: 00233 if (is_array($dat['softrefs'])) { 00234 $this->createEntryData_softreferences($table,$uid,$fieldname,'',$deleted,$dat['softrefs']['keys']); 00235 } 00236 } 00237 00238 // Word indexing: 00239 t3lib_div::loadTCA($table); 00240 foreach($TCA[$table]['columns'] as $field => $conf) { 00241 if (t3lib_div::inList('input,text',$conf['config']['type']) && strcmp($record[$field],'') && !t3lib_div::testInt($record[$field])) { 00242 $this->words_strings[$field] = $record[$field]; 00243 } 00244 } 00245 00246 return $this->relations; 00247 } 00248 } 00249 } 00250 00268 function createEntryData($table,$uid,$field,$flexpointer,$deleted,$ref_table,$ref_uid,$ref_string='',$sort=-1,$softref_key='',$softref_id='') { 00269 return array( 00270 'tablename' => $table, 00271 'recuid' => $uid, 00272 'field' => $field, 00273 'flexpointer' => $flexpointer, 00274 'softref_key' => $softref_key, 00275 'softref_id' => $softref_id, 00276 'sorting' => $sort, 00277 'deleted' => $deleted, 00278 'ref_table' => $ref_table, 00279 'ref_uid' => $ref_uid, 00280 'ref_string' => $ref_string, 00281 ); 00282 } 00283 00295 function createEntryData_dbRels($table,$uid,$fieldname,$flexpointer,$deleted,$items) { 00296 foreach($items as $sort => $i) { 00297 $this->relations[] = $this->createEntryData($table,$uid,$fieldname,$flexpointer,$deleted,$i['table'],$i['id'],'',$sort); 00298 } 00299 } 00300 00312 function createEntryData_fileRels($table,$uid,$fieldname,$flexpointer,$deleted,$items) { 00313 foreach($items as $sort => $i) { 00314 $filePath = $i['ID_absFile']; 00315 if (t3lib_div::isFirstPartOfStr($filePath,PATH_site)) { 00316 $filePath = substr($filePath,strlen(PATH_site)); 00317 } 00318 $this->relations[] = $this->createEntryData($table,$uid,$fieldname,$flexpointer,$deleted,'_FILE',0,$filePath,$sort); 00319 } 00320 } 00321 00333 function createEntryData_softreferences($table,$uid,$fieldname,$flexpointer,$deleted,$keys) { 00334 if (is_array($keys)) { 00335 foreach($keys as $spKey => $elements) { 00336 if (is_array($elements)) { 00337 foreach($elements as $subKey => $el) { 00338 if (is_array($el['subst'])) { 00339 switch((string)$el['subst']['type']) { 00340 case 'db': 00341 list($tableName,$recordId) = explode(':',$el['subst']['recordRef']); 00342 $this->relations[] = $this->createEntryData($table,$uid,$fieldname,$flexpointer,$deleted,$tableName,$recordId,'',-1,$spKey,$subKey); 00343 break; 00344 case 'file': 00345 $this->relations[] = $this->createEntryData($table,$uid,$fieldname,$flexpointer,$deleted,'_FILE',0,$el['subst']['relFileName'],-1,$spKey,$subKey); 00346 break; 00347 case 'string': 00348 $this->relations[] = $this->createEntryData($table,$uid,$fieldname,$flexpointer,$deleted,'_STRING',0,$el['subst']['tokenValue'],-1,$spKey,$subKey); 00349 break; 00350 } 00351 } 00352 } 00353 } 00354 } 00355 } 00356 } 00357 00358 00359 00360 00361 00362 00363 00364 00365 00366 00367 00368 00369 00370 00371 00372 /******************************* 00373 * 00374 * Get relations from table row 00375 * 00376 *******************************/ 00377 00389 function getRelations($table,$row,$onlyField='') { 00390 global $TCA; 00391 00392 // Load full table description 00393 t3lib_div::loadTCA($table); 00394 00395 // Initialize: 00396 $uid = $row['uid']; 00397 $nonFields = explode(',','uid,perms_userid,perms_groupid,perms_user,perms_group,perms_everybody,pid'); 00398 00399 $outRow = array(); 00400 foreach($row as $field => $value) { 00401 if (!in_array($field,$nonFields) && is_array($TCA[$table]['columns'][$field]) && (!$onlyField || $onlyField===$field)) { 00402 $conf = $TCA[$table]['columns'][$field]['config']; 00403 00404 // Add files 00405 if ($result = $this->getRelations_procFiles($value, $conf, $uid)) { 00406 // Creates an entry for the field with all the files: 00407 $outRow[$field] = array( 00408 'type' => 'file', 00409 'newValueFiles' => $result, 00410 ); 00411 } 00412 00413 // Add DB: 00414 if ($result = $this->getRelations_procDB($value, $conf, $uid, $table)) { 00415 // Create an entry for the field with all DB relations: 00416 $outRow[$field] = array( 00417 'type' => 'db', 00418 'itemArray' => $result, 00419 ); 00420 } 00421 00422 // For "flex" fieldtypes we need to traverse the structure looking for file and db references of course! 00423 if ($conf['type']=='flex') { 00424 00425 // Get current value array: 00426 // NOTICE: failure to resolve Data Structures can lead to integrity problems with the reference index. Please look up the note in the JavaDoc documentation for the function t3lib_BEfunc::getFlexFormDS() 00427 $dataStructArray = t3lib_BEfunc::getFlexFormDS($conf, $row, $table,'',$this->WSOL); 00428 $currentValueArray = t3lib_div::xml2array($value); 00429 00430 // Traversing the XML structure, processing files: 00431 if (is_array($currentValueArray)) { 00432 $this->temp_flexRelations = array( 00433 'db' => array(), 00434 'file' => array(), 00435 'softrefs' => array() 00436 ); 00437 00438 // Create and call iterator object: 00439 $flexObj = t3lib_div::makeInstance('t3lib_flexformtools'); 00440 $flexObj->traverseFlexFormXMLData($table,$field,$row,$this,'getRelations_flexFormCallBack'); 00441 00442 // Create an entry for the field: 00443 $outRow[$field] = array( 00444 'type' => 'flex', 00445 'flexFormRels' => $this->temp_flexRelations, 00446 ); 00447 } 00448 } 00449 00450 // Soft References: 00451 if (strlen($value) && $softRefs = t3lib_BEfunc::explodeSoftRefParserList($conf['softref'])) { 00452 $softRefValue = $value; 00453 foreach($softRefs as $spKey => $spParams) { 00454 $softRefObj = &t3lib_BEfunc::softRefParserObj($spKey); 00455 if (is_object($softRefObj)) { 00456 $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams); 00457 if (is_array($resultArray)) { 00458 $outRow[$field]['softrefs']['keys'][$spKey] = $resultArray['elements']; 00459 if (strlen($resultArray['content'])) { 00460 $softRefValue = $resultArray['content']; 00461 } 00462 } 00463 } 00464 } 00465 00466 if (is_array($outRow[$field]['softrefs']) && count($outRow[$field]['softrefs']) && strcmp($value,$softRefValue) && strstr($softRefValue,'{softref:')) { 00467 $outRow[$field]['softrefs']['tokenizedContent'] = $softRefValue; 00468 } 00469 } 00470 } 00471 } 00472 00473 return $outRow; 00474 } 00475 00487 function getRelations_flexFormCallBack($dsArr, $dataValue, $PA, $structurePath, &$pObj) { 00488 $structurePath = substr($structurePath,5).'/'; // removing "data/" in the beginning of path (which points to location in data array) 00489 00490 $dsConf = $dsArr['TCEforms']['config']; 00491 00492 // Implode parameter values: 00493 list($table, $uid, $field) = array($PA['table'],$PA['uid'],$PA['field']); 00494 00495 // Add files 00496 if ($result = $this->getRelations_procFiles($dataValue, $dsConf, $uid)) { 00497 00498 // Creates an entry for the field with all the files: 00499 $this->temp_flexRelations['file'][$structurePath] = $result; 00500 } 00501 00502 // Add DB: 00503 if ($result = $this->getRelations_procDB($dataValue, $dsConf, $uid)) { 00504 00505 // Create an entry for the field with all DB relations: 00506 $this->temp_flexRelations['db'][$structurePath] = $result; 00507 } 00508 00509 // Soft References: 00510 if (strlen($dataValue) && $softRefs = t3lib_BEfunc::explodeSoftRefParserList($dsConf['softref'])) { 00511 $softRefValue = $dataValue; 00512 foreach($softRefs as $spKey => $spParams) { 00513 $softRefObj = &t3lib_BEfunc::softRefParserObj($spKey); 00514 if (is_object($softRefObj)) { 00515 $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams, $structurePath); 00516 if (is_array($resultArray) && is_array($resultArray['elements'])) { 00517 $this->temp_flexRelations['softrefs'][$structurePath]['keys'][$spKey] = $resultArray['elements']; 00518 if (strlen($resultArray['content'])) $softRefValue = $resultArray['content']; 00519 } 00520 } 00521 } 00522 00523 if (count($this->temp_flexRelations['softrefs']) && strcmp($dataValue,$softRefValue)) { 00524 $this->temp_flexRelations['softrefs'][$structurePath]['tokenizedContent'] = $softRefValue; 00525 } 00526 } 00527 } 00528 00537 function getRelations_procFiles($value, $conf, $uid) { 00538 // Take care of files... 00539 if ($conf['type']=='group' && $conf['internal_type']=='file') { 00540 00541 // Collect file values in array: 00542 if ($conf['MM']) { 00543 $theFileValues = array(); 00544 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup'); 00545 $dbAnalysis->start('', 'files', $conf['MM'], $uid); 00546 00547 foreach($dbAnalysis->itemArray as $somekey => $someval) { 00548 if ($someval['id']) { 00549 $theFileValues[] = $someval['id']; 00550 } 00551 } 00552 } else { 00553 $theFileValues = explode(',',$value); 00554 } 00555 00556 // Traverse the files and add them: 00557 $uploadFolder = $conf['uploadfolder']; 00558 $dest = $this->destPathFromUploadFolder($uploadFolder); 00559 $newValue = array(); 00560 $newValueFiles = array(); 00561 00562 foreach($theFileValues as $file) { 00563 if (trim($file)) { 00564 $realFile = $dest.'/'.trim($file); 00565 # if (@is_file($realFile)) { // Now, the refernece index should NOT look if files exist - just faithfully include them if they are in the records! 00566 $newValueFiles[] = array( 00567 'filename' => $file, 00568 'ID' => md5($realFile), 00569 'ID_absFile' => $realFile 00570 ); // the order should be preserved here because.. (?) 00571 # } else $this->error('Missing file: '.$realFile); 00572 } 00573 } 00574 00575 return $newValueFiles; 00576 } 00577 } 00578 00588 function getRelations_procDB($value, $conf, $uid, $table = '') { 00589 00590 // DB record lists: 00591 if ($this->isReferenceField($conf)) { 00592 $allowedTables = $conf['type']=='group' ? $conf['allowed'] : $conf['foreign_table'].','.$conf['neg_foreign_table']; 00593 $prependName = $conf['type']=='group' ? $conf['prepend_tname'] : $conf['neg_foreign_table']; 00594 00595 if($conf['MM_opposite_field']) { 00596 return array(); 00597 } 00598 00599 $dbAnalysis = t3lib_div::makeInstance('t3lib_loadDBGroup'); 00600 $dbAnalysis->start($value,$allowedTables,$conf['MM'],$uid,$table,$conf); 00601 00602 return $dbAnalysis->itemArray; 00603 } 00604 } 00605 00606 00607 00608 00609 00610 00611 00612 00613 00614 00615 00616 00617 /******************************* 00618 * 00619 * Setting values 00620 * 00621 *******************************/ 00622 00636 function setReferenceValue($hash,$newValue,$returnDataArray=FALSE) { 00637 00638 if ($GLOBALS['BE_USER']->workspace===0 && $GLOBALS['BE_USER']->isAdmin()) { 00639 00640 // Get current index from Database: 00641 list($refRec) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00642 '*', 00643 'sys_refindex', 00644 'hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($hash,'sys_refindex') 00645 ); 00646 00647 // Check if reference existed. 00648 if (is_array($refRec)) { 00649 if ($GLOBALS['TCA'][$refRec['tablename']]) { 00650 00651 // Get that record from database: 00652 list($record) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*',$refRec['tablename'],'uid='.intval($refRec['recuid'])); 00653 00654 if (is_array($record)) { 00655 00656 // Get all relations from record, filter with fieldname: 00657 $dbrels = $this->getRelations($refRec['tablename'],$record,$refRec['field']); 00658 if ($dat = $dbrels[$refRec['field']]) { 00659 00660 // Initialize data array that is to be sent to TCEmain afterwards: 00661 $dataArray = array(); 00662 00663 // Based on type, 00664 switch((string)$dat['type']) { 00665 case 'db': 00666 $error = $this->setReferenceValue_dbRels($refRec,$dat['itemArray'],$newValue,$dataArray); 00667 if ($error) return $error; 00668 break; 00669 case 'file': 00670 $this->setReferenceValue_fileRels($refRec,$dat['newValueFiles'],$newValue,$dataArray); 00671 if ($error) return $error; 00672 break; 00673 case 'flex': 00674 // DB references: 00675 if (is_array($dat['flexFormRels']['db'][$refRec['flexpointer']])) { 00676 $error = $this->setReferenceValue_dbRels($refRec,$dat['flexFormRels']['db'][$refRec['flexpointer']],$newValue,$dataArray,$refRec['flexpointer']); 00677 if ($error) return $error; 00678 } 00679 // File references 00680 if (is_array($dat['flexFormRels']['file'][$refRec['flexpointer']])) { 00681 $this->setReferenceValue_fileRels($refRec,$dat['flexFormRels']['file'][$refRec['flexpointer']],$newValue,$dataArray,$refRec['flexpointer']); 00682 if ($error) return $error; 00683 } 00684 // Soft references in flexforms 00685 if ($refRec['softref_key'] && is_array($dat['flexFormRels']['softrefs'][$refRec['flexpointer']]['keys'][$refRec['softref_key']])) { 00686 $error = $this->setReferenceValue_softreferences($refRec,$dat['flexFormRels']['softrefs'][$refRec['flexpointer']],$newValue,$dataArray,$refRec['flexpointer']); 00687 if ($error) return $error; 00688 } 00689 break; 00690 } 00691 00692 // Softreferences in the field: 00693 if ($refRec['softref_key'] && is_array($dat['softrefs']['keys'][$refRec['softref_key']])) { 00694 $error = $this->setReferenceValue_softreferences($refRec,$dat['softrefs'],$newValue,$dataArray); 00695 if ($error) return $error; 00696 00697 } 00698 00699 // Data Array, now ready to sent to TCEmain 00700 if ($returnDataArray) { 00701 return $dataArray; 00702 } else { 00703 // Execute CMD array: 00704 $tce = t3lib_div::makeInstance('t3lib_TCEmain'); 00705 $tce->stripslashes_values = FALSE; 00706 $tce->dontProcessTransformations = TRUE; 00707 $tce->bypassWorkspaceRestrictions = TRUE; 00708 $tce->bypassFileHandling = TRUE; 00709 $tce->bypassAccessCheckForRecords = TRUE; // Otherwise this cannot update things in deleted records... 00710 00711 $tce->start($dataArray,array()); // check has been done previously that there is a backend user which is Admin and also in live workspace 00712 $tce->process_datamap(); 00713 00714 // Return errors if any: 00715 if (count($tce->errorLog)) { 00716 return chr(10).'TCEmain:'.implode(chr(10).'TCEmain:',$tce->errorLog); 00717 } 00718 } 00719 } 00720 } 00721 } else return 'ERROR: Tablename "'.$refRec['tablename'].'" was not in TCA!'; 00722 } else return 'ERROR: No reference record with hash="'.$hash.'" was found!'; 00723 } else return 'ERROR: BE_USER object is not admin OR not in workspace 0 (Live)'; 00724 } 00725 00736 function setReferenceValue_dbRels($refRec,$itemArray,$newValue,&$dataArray,$flexpointer='') { 00737 if (!strcmp($itemArray[$refRec['sorting']]['id'],$refRec['ref_uid']) && !strcmp($itemArray[$refRec['sorting']]['table'],$refRec['ref_table'])) { 00738 00739 // Setting or removing value: 00740 if ($newValue===NULL) { // Remove value: 00741 unset($itemArray[$refRec['sorting']]); 00742 } else { 00743 list($itemArray[$refRec['sorting']]['table'],$itemArray[$refRec['sorting']]['id']) = explode(':',$newValue); 00744 } 00745 00746 // Traverse and compile new list of records: 00747 $saveValue = array(); 00748 foreach($itemArray as $pair) { 00749 $saveValue[] = $pair['table'].'_'.$pair['id']; 00750 } 00751 00752 // Set in data array: 00753 if ($flexpointer) { 00754 $flexToolObj = t3lib_div::makeInstance('t3lib_flexformtools'); 00755 $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'] = array(); 00756 $flexToolObj->setArrayValueByPath(substr($flexpointer,0,-1),$dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'],implode(',',$saveValue)); 00757 } else { 00758 $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']] = implode(',',$saveValue); 00759 } 00760 00761 } else return 'ERROR: table:id pair "'.$refRec['ref_table'].':'.$refRec['ref_uid'].'" did not match that of the record ("'.$itemArray[$refRec['sorting']]['table'].':'.$itemArray[$refRec['sorting']]['id'].'") in sorting index "'.$refRec['sorting'].'"'; 00762 } 00763 00774 function setReferenceValue_fileRels($refRec,$itemArray,$newValue,&$dataArray,$flexpointer='') { 00775 if (!strcmp(substr($itemArray[$refRec['sorting']]['ID_absFile'],strlen(PATH_site)),$refRec['ref_string']) && !strcmp('_FILE',$refRec['ref_table'])) { 00776 00777 // Setting or removing value: 00778 if ($newValue===NULL) { // Remove value: 00779 unset($itemArray[$refRec['sorting']]); 00780 } else { 00781 $itemArray[$refRec['sorting']]['filename'] = $newValue; 00782 } 00783 00784 // Traverse and compile new list of records: 00785 $saveValue = array(); 00786 foreach($itemArray as $fileInfo) { 00787 $saveValue[] = $fileInfo['filename']; 00788 } 00789 00790 // Set in data array: 00791 if ($flexpointer) { 00792 $flexToolObj = t3lib_div::makeInstance('t3lib_flexformtools'); 00793 $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'] = array(); 00794 $flexToolObj->setArrayValueByPath(substr($flexpointer,0,-1),$dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'],implode(',',$saveValue)); 00795 } else { 00796 $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']] = implode(',',$saveValue); 00797 } 00798 00799 } else return 'ERROR: either "'.$refRec['ref_table'].'" was not "_FILE" or file PATH_site+"'.$refRec['ref_string'].'" did not match that of the record ("'.$itemArray[$refRec['sorting']]['ID_absFile'].'") in sorting index "'.$refRec['sorting'].'"'; 00800 } 00801 00812 function setReferenceValue_softreferences($refRec,$softref,$newValue,&$dataArray,$flexpointer='') { 00813 if (is_array($softref['keys'][$refRec['softref_key']][$refRec['softref_id']])) { 00814 00815 // Set new value: 00816 $softref['keys'][$refRec['softref_key']][$refRec['softref_id']]['subst']['tokenValue'] = ''.$newValue; 00817 00818 // Traverse softreferences and replace in tokenized content to rebuild it with new value inside: 00819 foreach($softref['keys'] as $sfIndexes) { 00820 foreach($sfIndexes as $data) { 00821 $softref['tokenizedContent'] = str_replace('{softref:'.$data['subst']['tokenID'].'}', $data['subst']['tokenValue'], $softref['tokenizedContent']); 00822 } 00823 } 00824 00825 // Set in data array: 00826 if (!strstr($softref['tokenizedContent'],'{softref:')) { 00827 if ($flexpointer) { 00828 $flexToolObj = t3lib_div::makeInstance('t3lib_flexformtools'); 00829 $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'] = array(); 00830 $flexToolObj->setArrayValueByPath(substr($flexpointer,0,-1),$dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']]['data'],$softref['tokenizedContent']); 00831 } else { 00832 $dataArray[$refRec['tablename']][$refRec['recuid']][$refRec['field']] = $softref['tokenizedContent']; 00833 } 00834 } else return 'ERROR: After substituting all found soft references there were still soft reference tokens in the text. (theoretically this does not have to be an error if the string "{softref:" happens to be in the field for another reason.)'; 00835 } else return 'ERROR: Soft reference parser key "'.$refRec['softref_key'].'" or the index "'.$refRec['softref_id'].'" was not found.'; 00836 } 00837 00838 00839 00840 00841 00842 00843 00844 00845 00846 00847 /******************************* 00848 * 00849 * Indexing words 00850 * 00851 *******************************/ 00852 00856 function wordIndexing($table,$uid) { 00857 return; // Disabled until Kasper finishes this feature. 00858 00859 $lexer = t3lib_div::makeInstance('tx_indexedsearch_lexer'); 00860 $words = $lexer->split2Words(implode(' ',$this->words_strings)); 00861 foreach($words as $w) { 00862 $words[]=substr($w,0,3); 00863 } 00864 $words = array_unique($words); 00865 $this->updateWordIndex($words,$table,$uid); 00866 } 00867 00876 function updateWordIndex($words,$table,$uid) { 00877 00878 // Submit words to 00879 $this->submitWords($words); 00880 00881 // Result id and remove relations: 00882 $rid = t3lib_div::md5int($table.':'.$uid); 00883 $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_refindex_rel', 'rid='.intval($rid)); 00884 00885 // Add relations: 00886 foreach($words as $w) { 00887 $insertFields = array( 00888 'rid' => $rid, 00889 'wid' => t3lib_div::md5int($w) 00890 ); 00891 00892 $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_refindex_rel', $insertFields); 00893 } 00894 00895 // Add result record: 00896 $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_refindex_res', 'rid='.intval($rid)); 00897 $insertFields = array( 00898 'rid' => $rid, 00899 'tablename' => $table, 00900 'recuid' => $uid 00901 ); 00902 $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_refindex_res', $insertFields); 00903 } 00904 00911 function submitWords($wl) { 00912 00913 $hashArr = array(); 00914 foreach($wl as $w) { 00915 $hashArr[] = t3lib_div::md5int($w); 00916 } 00917 $wl = array_flip($wl); 00918 00919 if (count($hashArr)) { 00920 $cwl = implode(',',$hashArr); 00921 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('baseword', 'sys_refindex_words', 'wid IN ('.$cwl.')'); 00922 00923 if($GLOBALS['TYPO3_DB']->sql_num_rows($res)!=count($wl)) { 00924 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00925 unset($wl[$row['baseword']]); 00926 } 00927 00928 reset($wl); 00929 while(list($key,$val)=each($wl)) { 00930 $insertFields = array( 00931 'wid' => t3lib_div::md5int($key), 00932 'baseword' => $key 00933 ); 00934 00935 // A duplicate-key error will occur here if a word is NOT unset in the unset() line. However as long as the words in $wl are NOT longer as 60 chars (the baseword varchar is 60 characters...) this is not a problem. 00936 $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_refindex_words', $insertFields); 00937 } 00938 } 00939 } 00940 } 00941 00942 00943 00944 00945 00946 00947 00948 /******************************* 00949 * 00950 * Helper functions 00951 * 00952 *******************************/ 00953 00960 function isReferenceField($conf) { 00961 return ($conf['type']=='group' && $conf['internal_type']=='db') || (($conf['type']=='select' || $conf['type']=='inline') && $conf['foreign_table']); 00962 } 00963 00970 function destPathFromUploadFolder($folder) { 00971 return PATH_site.$folder; 00972 } 00973 00980 function error($msg) { 00981 $this->errorLog[]=$msg; 00982 } 00983 00991 function updateIndex($testOnly,$cli_echo=FALSE) { 00992 global $TCA, $TYPO3_DB; 00993 00994 $errors = array(); 00995 $tableNames = array(); 00996 $recCount=0; 00997 $tableCount=0; 00998 00999 $headerContent = $testOnly ? 'Reference Index being TESTED (nothing written, use "-e" to update)' : 'Reference Index being Updated'; 01000 if ($cli_echo) echo 01001 '*******************************************'.chr(10). 01002 $headerContent.chr(10). 01003 '*******************************************'.chr(10); 01004 01005 // Traverse all tables: 01006 foreach ($TCA as $tableName => $cfg) { 01007 $tableNames[] = $tableName; 01008 $tableCount++; 01009 01010 // Traverse all records in tables, including deleted records: 01011 $allRecs = $TYPO3_DB->exec_SELECTgetRows('uid',$tableName,'1=1'); //.t3lib_BEfunc::deleteClause($tableName) 01012 $uidList = array(0); 01013 foreach ($allRecs as $recdat) { 01014 $refIndexObj = t3lib_div::makeInstance('t3lib_refindex'); 01015 $result = $refIndexObj->updateRefIndexTable($tableName,$recdat['uid'],$testOnly); 01016 $uidList[]= $recdat['uid']; 01017 $recCount++; 01018 01019 if ($result['addedNodes'] || $result['deletedNodes']) { 01020 $Err = 'Record '.$tableName.':'.$recdat['uid'].' had '.$result['addedNodes'].' added indexes and '.$result['deletedNodes'].' deleted indexes'; 01021 $errors[]= $Err; 01022 if ($cli_echo) echo $Err.chr(10); 01023 #$errors[] = t3lib_div::view_array($result); 01024 } 01025 } 01026 01027 // Searching lost indexes for this table: 01028 $where = 'tablename='.$TYPO3_DB->fullQuoteStr($tableName,'sys_refindex').' AND recuid NOT IN ('.implode(',',$uidList).')'; 01029 $lostIndexes = $TYPO3_DB->exec_SELECTgetRows('hash','sys_refindex',$where); 01030 if (count($lostIndexes)) { 01031 $Err = 'Table '.$tableName.' has '.count($lostIndexes).' lost indexes which are now deleted'; 01032 $errors[]= $Err; 01033 if ($cli_echo) echo $Err.chr(10); 01034 if (!$testOnly) $TYPO3_DB->exec_DELETEquery('sys_refindex',$where); 01035 } 01036 } 01037 01038 // Searching lost indexes for non-existing tables: 01039 $where = 'tablename NOT IN ('.implode(',',$TYPO3_DB->fullQuoteArray($tableNames,'sys_refindex')).')'; 01040 $lostTables = $TYPO3_DB->exec_SELECTgetRows('hash','sys_refindex',$where); 01041 if (count($lostTables)) { 01042 $Err = 'Index table hosted '.count($lostTables).' indexes for non-existing tables, now removed'; 01043 $errors[]= $Err; 01044 if ($cli_echo) echo $Err.chr(10); 01045 if (!$testOnly) $TYPO3_DB->exec_DELETEquery('sys_refindex',$where); 01046 } 01047 01048 $testedHowMuch = $recCount.' records from '.$tableCount.' tables were checked/updated.'.chr(10); 01049 01050 $bodyContent = $testedHowMuch.(count($errors)?implode(chr(10),$errors):'Index Integrity was perfect!'); 01051 if ($cli_echo) echo $testedHowMuch.(count($errors)?'Updates: '.count($errors):'Index Integrity was perfect!').chr(10); 01052 01053 return array($headerContent,$bodyContent,count($errors)); 01054 } 01055 } 01056 01057 01058 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_refindex.php']) { 01059 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_refindex.php']); 01060 } 01061 ?>