|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2001-2011 Kasper Skårhøj (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 * 00017 * This script is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU General Public License for more details. 00021 * 00022 * This copyright notice MUST APPEAR in all copies of the script! 00023 ***************************************************************/ 00024 /** 00025 * Module extension (addition to function menu) 'Indexed search' for the 'indexed_search' extension. 00026 * 00027 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00028 */ 00029 /** 00030 * [CLASS/FUNCTION INDEX of SCRIPT] 00031 * 00032 * 00033 * 00034 * 106: class tx_indexedsearch_modfunc1 extends t3lib_extobjbase 00035 * 120: function modMenu() 00036 * 144: function main() 00037 * 00038 * SECTION: Drawing table of indexed pages 00039 * 248: function drawTableOfIndexedPages() 00040 * 299: function indexed_info($data, $firstColContent) 00041 * 386: function printPhashRow($row,$grouping=0,$extraGrListRows) 00042 * 527: function printPhashRowHeader() 00043 * 582: function returnNumberOfColumns() 00044 * 00045 * SECTION: Details display, phash row 00046 * 618: function showDetailsForPhash($phash) 00047 * 737: function listWords($ftrows,$header, $stopWordBoxes=FALSE, $page='') 00048 * 787: function listMetaphoneStat($ftrows,$header) 00049 * 824: function linkWordDetails($string,$wid) 00050 * 836: function linkMetaPhoneDetails($string,$metaphone) 00051 * 846: function flagsMsg($flags) 00052 * 00053 * SECTION: Details display, words / metaphone 00054 * 877: function showDetailsForWord($wid) 00055 * 936: function showDetailsForMetaphone($metaphone) 00056 * 00057 * SECTION: Helper functions 00058 * 1007: function printRemoveIndexed($phash,$alt) 00059 * 1020: function printReindex($resultRow,$alt) 00060 * 1035: function linkDetails($string,$phash) 00061 * 1044: function linkList() 00062 * 1055: function showPageDetails($string,$id) 00063 * 1065: function printExtraGrListRows($extraGrListRows) 00064 * 1082: function printRootlineInfo($row) 00065 * 1116: function makeItemTypeIcon($it,$alt='') 00066 * 1141: function utf8_to_currentCharset($string) 00067 * 00068 * SECTION: Reindexing 00069 * 1173: function reindexPhash($phash, $pageId) 00070 * 1227: function getUidRootLineForClosestTemplate($id) 00071 * 00072 * SECTION: SQL functions 00073 * 1270: function removeIndexedPhashRow($phashList,$clearPageCache=1) 00074 * 1314: function getGrListEntriesForPhash($phash,$gr_list) 00075 * 1334: function processStopWords($stopWords) 00076 * 1354: function processPageKeywords($pageKeywords, $pageUid) 00077 * 00078 * TOTAL FUNCTIONS: 30 00079 * (This index is automatically created/updated by the extension "extdeveval") 00080 * 00081 */ 00082 00083 00084 require_once(t3lib_extMgm::extPath('indexed_search').'class.indexer.php'); 00085 00086 00087 /** 00088 * Indexing class for TYPO3 frontend 00089 * 00090 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00091 * @package TYPO3 00092 * @subpackage tx_indexedsearch 00093 */ 00094 class tx_indexedsearch_modfunc1 extends t3lib_extobjbase { 00095 00096 // Internal, dynamic: 00097 var $allPhashListed = array(); // phash values accumulations for link to clear all 00098 var $external_parsers = array(); // External content parsers - objects set here with file extensions as keys. 00099 var $iconFileNameCache = array(); // File extensions - icon map/cache. 00100 00101 /** 00102 * Indexer object 00103 * 00104 * @var tx_indexedsearch_indexer 00105 */ 00106 var $indexerObj; 00107 00108 00109 /** 00110 * Initialize menu array internally 00111 * 00112 * @return void 00113 */ 00114 function modMenu() { 00115 global $LANG; 00116 00117 return array ( 00118 'depth' => array( 00119 0 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_0'), 00120 1 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_1'), 00121 2 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_2'), 00122 3 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_3'), 00123 999 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_infi'), 00124 ), 00125 'type' => array( 00126 0 => 'Overview', 00127 1 => 'Technical Details', 00128 2 => 'Words and content', 00129 ) 00130 ); 00131 } 00132 00133 /** 00134 * Produces main content of the module 00135 * 00136 * @return string HTML output 00137 */ 00138 function main() { 00139 // Initializes the module. Done in this function because we may need to re-initialize if data is submitted! 00140 global $LANG,$TYPO3_CONF_VARS; 00141 00142 // Return if no page id: 00143 if ($this->pObj->id<=0) return; 00144 00145 // Initialize max-list items 00146 $this->maxListPerPage = t3lib_div::_GP('listALL') ? 100000 : 100; 00147 00148 // Processing deletion of phash rows: 00149 if (t3lib_div::_GP('deletePhash')) { 00150 $this->removeIndexedPhashRow(t3lib_div::_GP('deletePhash')); 00151 } 00152 00153 // Processing stop-words: 00154 if (t3lib_div::_POST('_stopwords')) { 00155 $this->processStopWords(t3lib_div::_POST('stopWord')); 00156 } 00157 00158 // Processing stop-words: 00159 if (t3lib_div::_POST('_pageKeywords')) { 00160 $this->processPageKeywords(t3lib_div::_POST('pageKeyword'), t3lib_div::_POST('pageKeyword_pageUid')); 00161 } 00162 00163 // Initialize external document parsers: 00164 // Example configuration, see ext_localconf.php of this file! 00165 if (is_array($TYPO3_CONF_VARS['EXTCONF']['indexed_search']['external_parsers'])) { 00166 foreach($TYPO3_CONF_VARS['EXTCONF']['indexed_search']['external_parsers'] as $extension => $_objRef) { 00167 $this->external_parsers[$extension] = t3lib_div::getUserObj($_objRef); 00168 00169 // Init parser and if it returns false, unset its entry again: 00170 if (!$this->external_parsers[$extension]->softInit($extension)) { 00171 unset($this->external_parsers[$extension]); 00172 } 00173 } 00174 } 00175 00176 // Initialize indexer if we need it (metaphone display does...) 00177 $this->indexerObj = t3lib_div::makeInstance('tx_indexedsearch_indexer'); 00178 00179 // Set CSS styles specific for this document: 00180 $this->pObj->content = str_replace('/*###POSTCSSMARKER###*/',' 00181 TABLE.c-list TR TD { white-space: nowrap; vertical-align: top; } 00182 ',$this->pObj->content); 00183 00184 00185 // Check if details for a phash record should be shown: 00186 if (t3lib_div::_GET('phash')) { 00187 00188 // Show title / function menu: 00189 $theOutput.=$this->pObj->doc->spacer(5); 00190 $theOutput.=$this->pObj->doc->section('Details for a single result row:',$this->showDetailsForPhash(t3lib_div::_GET('phash')),0,1); 00191 00192 } elseif (t3lib_div::_GET('wid')) { 00193 // Show title / function menu: 00194 $theOutput.=$this->pObj->doc->spacer(5); 00195 $theOutput.=$this->pObj->doc->section('Details for a word:',$this->showDetailsForWord(t3lib_div::_GET('wid')),0,1); 00196 00197 } elseif (t3lib_div::_GET('metaphone')) { 00198 // Show title / function menu: 00199 $theOutput.=$this->pObj->doc->spacer(5); 00200 $theOutput.=$this->pObj->doc->section('Details for metaphone value:',$this->showDetailsForMetaphone(t3lib_div::_GET('metaphone')),0,1); 00201 00202 } elseif (t3lib_div::_GET('reindex')) { 00203 // Show title / function menu: 00204 $theOutput.=$this->pObj->doc->spacer(5); 00205 $theOutput.=$this->pObj->doc->section('Reindexing...',$this->reindexPhash(t3lib_div::_GET('reindex'),t3lib_div::_GET('reindex_id')),0,1); 00206 00207 } else { // Detail listings: 00208 // Depth function menu: 00209 $h_func = t3lib_BEfunc::getFuncMenu($this->pObj->id,'SET[type]',$this->pObj->MOD_SETTINGS['type'],$this->pObj->MOD_MENU['type'],'index.php'); 00210 $h_func.= t3lib_BEfunc::getFuncMenu($this->pObj->id,'SET[depth]',$this->pObj->MOD_SETTINGS['depth'],$this->pObj->MOD_MENU['depth'],'index.php'); 00211 00212 // Show title / function menu: 00213 $theOutput.=$this->pObj->doc->spacer(5); 00214 $theOutput.=$this->pObj->doc->section($LANG->getLL('title'),$h_func,0,1); 00215 00216 $theOutput.=$this->drawTableOfIndexedPages(); 00217 } 00218 00219 return $theOutput; 00220 } 00221 00222 00223 00224 00225 00226 00227 00228 00229 00230 00231 00232 /******************************* 00233 * 00234 * Drawing table of indexed pages 00235 * 00236 ******************************/ 00237 00238 /** 00239 * Produces a table with indexing information for each page. 00240 * 00241 * @return string HTML output 00242 */ 00243 function drawTableOfIndexedPages() { 00244 global $BACK_PATH; 00245 00246 // Drawing tree: 00247 $tree = t3lib_div::makeInstance('t3lib_pageTree'); 00248 $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1); 00249 $tree->init('AND '.$perms_clause); 00250 00251 $HTML = '<img src="'.$BACK_PATH.t3lib_iconWorks::getIcon('pages',$this->pObj->pageinfo).'" width="18" height="16" align="top" alt="" />'; 00252 $tree->tree[] = Array( 00253 'row' => $this->pObj->pageinfo, 00254 'HTML' => $HTML 00255 ); 00256 00257 if ($this->pObj->MOD_SETTINGS['depth']) { 00258 $tree->getTree($this->pObj->id, $this->pObj->MOD_SETTINGS['depth'], ''); 00259 } 00260 00261 // Traverse page tree: 00262 $code = ''; 00263 foreach($tree->tree as $data) { 00264 $code.= $this->indexed_info( 00265 $data['row'], 00266 $data['HTML']. 00267 $this->showPageDetails(t3lib_BEfunc::getRecordTitlePrep($data['row']['title']), $data['row']['uid']) 00268 ); 00269 } 00270 00271 if ($code) { 00272 $code = '<br /><br /> 00273 <table border="0" cellspacing="1" cellpadding="2" class="c-list">'. 00274 $this->printPhashRowHeader(). 00275 $code. 00276 '</table>'; 00277 00278 // Create section to output: 00279 $theOutput.=$this->pObj->doc->section('',$code,0,1); 00280 } else { 00281 $theOutput .= $this->pObj->doc->section('', '<br /><br />' . $this->pObj->doc->icons(1) . 'There were no indexed pages found in the tree.<br /><br />', 0, 1); 00282 } 00283 00284 return $theOutput; 00285 } 00286 00287 /** 00288 * Create information table row for a page regarding indexing information. 00289 * 00290 * @param array Data array for this page 00291 * @param string HTML content for first column (page tree icon etc.) 00292 * @return string HTML code. (table row) 00293 */ 00294 function indexed_info($data, $firstColContent) { 00295 00296 // Query: 00297 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 00298 'ISEC.phash_t3, ISEC.rl0, ISEC.rl1, ISEC.rl2, ISEC.page_id, ISEC.uniqid, ' . 00299 'IP.phash, IP.phash_grouping, IP.cHashParams, IP.data_filename, IP.data_page_id, ' . 00300 'IP.data_page_reg1, IP.data_page_type, IP.data_page_mp, IP.gr_list, IP.item_type, ' . 00301 'IP.item_title, IP.item_description, IP.item_mtime, IP.tstamp, IP.item_size, ' . 00302 'IP.contentHash, IP.crdate, IP.parsetime, IP.sys_language_uid, IP.item_crdate, ' . 00303 'IP.externalUrl, IP.recordUid, IP.freeIndexUid, IP.freeIndexSetId, count(*) AS count_val', 00304 'index_phash IP, index_section ISEC', 00305 'IP.phash = ISEC.phash AND ISEC.page_id = '.intval($data['uid']), 00306 'IP.phash,IP.phash_grouping,IP.cHashParams,IP.data_filename,IP.data_page_id,IP.data_page_reg1,IP.data_page_type,IP.data_page_mp,IP.gr_list,IP.item_type,IP.item_title,IP.item_description,IP.item_mtime,IP.tstamp,IP.item_size,IP.contentHash,IP.crdate,IP.parsetime,IP.sys_language_uid,IP.item_crdate,ISEC.phash,ISEC.phash_t3,ISEC.rl0,ISEC.rl1,ISEC.rl2,ISEC.page_id,ISEC.uniqid,IP.externalUrl,IP.recordUid,IP.freeIndexUid,IP.freeIndexSetId', 00307 'IP.item_type, IP.tstamp', 00308 ($this->maxListPerPage+1) 00309 ); 00310 00311 // Initialize variables: 00312 $rowCount = 0; 00313 $lines = array(); // Collecting HTML rows here. 00314 $phashAcc = array(); // Collecting phash values (to remove local indexing for) 00315 $phashAcc[] = 0; 00316 00317 // Traverse the result set of phash rows selected: 00318 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00319 if ($rowCount == $this->maxListPerPage) { 00320 $rowCount++; // Increase to the extra warning row will appear as well. 00321 break; 00322 } 00323 00324 // Adds a display row: 00325 $lines[$row['phash_grouping']][] = $this->printPhashRow( 00326 $row, 00327 isset($lines[$row['phash_grouping']]), 00328 $this->getGrListEntriesForPhash($row['phash'], $row['gr_list']) 00329 ); 00330 $rowCount++; 00331 $phashAcc[] = $row['phash']; 00332 $this->allPhashListed[] = $row['phash']; // For removing all shown phash rows. 00333 } 00334 00335 // Compile rows into the table: 00336 $out = ''; 00337 $cellAttrib = ($data['_CSSCLASS'] ? ' class="'.$data['_CSSCLASS'].'"' : ''); 00338 if (count($lines)) { 00339 $firstColContent = '<td rowspan="'.$rowCount.'"'.$cellAttrib.'>'.$firstColContent.'</td>'; 00340 foreach($lines as $rowSet) { 00341 foreach($rowSet as $rows) { 00342 $out.=' 00343 <tr class="bgColor-20">'.$firstColContent.implode('',$rows).'</tr>'; 00344 00345 $firstColContent = ''; 00346 } 00347 } 00348 00349 if ($rowCount > $this->maxListPerPage) { // Now checking greater than, because we increased $rowCount before... 00350 $out.=' 00351 <tr class="bgColor-20"> 00352 <td> </td> 00353 <td colspan="'.($this->returnNumberOfColumns()-1).'">'.$this->pObj->doc->icons(3).'<span class="">There were more than '.$this->maxListPerPage.' rows. <a href="'.htmlspecialchars('index.php?id='.$this->pObj->id.'&listALL=1').'">Click here to list them ALL!</a></span></td> 00354 </tr>'; 00355 } 00356 } else { 00357 $out.=' 00358 <tr class="bgColor-20"> 00359 <td'.$cellAttrib.'>'.$firstColContent.'</td> 00360 <td colspan="'.($this->returnNumberOfColumns()-1).'"><em>Not indexed</em></td> 00361 </tr>'; 00362 } 00363 00364 // Checking for phash-rows which are NOT joined with the section table: 00365 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('IP.*', 'index_phash IP', 'IP.data_page_id = '.intval($data['uid']).' AND IP.phash NOT IN ('.implode(',',$phashAcc).')'); 00366 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00367 $out.=' 00368 <tr class="typo3-red"> 00369 <td colspan="'.$this->returnNumberOfColumns().'"><strong>Warning:</strong> phash-row "'.$row['phash'].'" didn\'t have a representation in the index_section table!</td> 00370 </tr>'; 00371 $this->allPhashListed[] = $row['phash']; 00372 } 00373 00374 return $out; 00375 } 00376 00377 /** 00378 * Render a single row of information about a indexing entry. 00379 * 00380 * @param array Row from query (combined phash table with sections etc). 00381 * @param boolean Set if grouped to previous result; the icon of the element is not shown again. 00382 * @param array Array of index_grlist records. 00383 * @return array Array of table rows. 00384 * @see indexed_info() 00385 */ 00386 function printPhashRow($row,$grouping=0,$extraGrListRows) { 00387 $lines = array(); 00388 00389 // Title cell attributes will highlight TYPO3 pages with a slightly darker color (bgColor4) than attached medias. Also IF there are more than one section record for a phash row it will be red as a warning that something is wrong! 00390 $titleCellAttribs = $row['count_val']!=1?' bgcolor="red"':($row['item_type']==='0' ? ' class="bgColor4"' : ''); 00391 00392 if ($row['item_type']) { 00393 $arr = unserialize($row['cHashParams']); 00394 $page = $arr['key'] ? ' ['.$arr['key'].']' : ''; 00395 } else $page = ''; 00396 $elTitle = $this->linkDetails($row['item_title'] ? htmlspecialchars(t3lib_div::fixed_lgd_cs($this->utf8_to_currentCharset($row['item_title']), 20).$page) : '<em>[No Title]</em>',$row['phash']); 00397 $cmdLinks = $this->printRemoveIndexed($row['phash'],'Clear phash-row').$this->printReindex($row,'Re-index element'); 00398 00399 switch($this->pObj->MOD_SETTINGS['type']) { 00400 case 1: // Technical details: 00401 // Display icon: 00402 if (!$grouping) { 00403 $lines[] = '<td>'.$this->makeItemTypeIcon($row['item_type'], $row['data_filename'] ? $row['data_filename'] : $row['item_title']).'</td>'; 00404 } else { 00405 $lines[] = '<td> </td>'; 00406 } 00407 00408 // Title displayed: 00409 $lines[] = '<td'.$titleCellAttribs.'>'.$elTitle.'</td>'; 00410 00411 // Remove-indexing-link: 00412 $lines[] = '<td>'.$cmdLinks.'</td>'; 00413 00414 // Various data: 00415 $lines[] = '<td>'.$row['phash'].'</td>'; 00416 $lines[] = '<td>'.$row['contentHash'].'</td>'; 00417 00418 if ($row['item_type']==='0') { 00419 $lines[] = '<td>'.($row['data_page_id'] ? $row['data_page_id'] : ' ').'</td>'; 00420 $lines[] = '<td>'.($row['data_page_type'] ? $row['data_page_type'] : ' ').'</td>'; 00421 $lines[] = '<td>'.($row['sys_language_uid'] ? $row['sys_language_uid'] : ' ').'</td>'; 00422 $lines[] = '<td>'.($row['data_page_mp'] ? $row['data_page_mp'] : ' ').'</td>'; 00423 } else { 00424 $lines[] = '<td colspan="4">'.htmlspecialchars($row['data_filename']).'</td>'; 00425 } 00426 $lines[] = '<td>'.$row['gr_list'].$this->printExtraGrListRows($extraGrListRows).'</td>'; 00427 $lines[] = '<td>'.$this->printRootlineInfo($row).'</td>'; 00428 $lines[] = '<td>'.($row['page_id'] ? $row['page_id'] : ' ').'</td>'; 00429 $lines[] = '<td>'.($row['phash_t3']!=$row['phash'] ? $row['phash_t3'] : ' ').'</td>'; 00430 $lines[] = '<td>'.($row['freeIndexUid'] ? $row['freeIndexUid'].($row['freeIndexSetId']?'/'.$row['freeIndexSetId']:'') : ' ').'</td>'; 00431 $lines[] = '<td>'.($row['recordUid'] ? $row['recordUid'] : ' ').'</td>'; 00432 00433 00434 00435 // cHash parameters: 00436 $arr = unserialize($row['cHashParams']); 00437 if (!is_array($arr)) { 00438 $arr = array( 00439 'cHash' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_general.xml:LGL.error', true) 00440 ); 00441 } 00442 $theCHash = $arr['cHash']; 00443 unset($arr['cHash']); 00444 00445 if ($row['item_type']) { // pdf... 00446 $lines[] = '<td>'.($arr['key'] ? 'Page '.$arr['key'] : '').' </td>'; 00447 } elseif ($row['item_type']==0) { 00448 $lines[] = '<td>'.htmlspecialchars(t3lib_div::implodeArrayForUrl('',$arr)).' </td>'; 00449 } else { 00450 $lines[] = '<td class="bgColor"> </td>'; 00451 } 00452 00453 $lines[] = '<td>'.$theCHash.'</td>'; 00454 break; 00455 case 2: // Words and content: 00456 // Display icon: 00457 if (!$grouping) { 00458 $lines[] = '<td>'.$this->makeItemTypeIcon($row['item_type'], $row['data_filename'] ? $row['data_filename'] : $row['item_title']).'</td>'; 00459 } else { 00460 $lines[] = '<td> </td>'; 00461 } 00462 00463 // Title displayed: 00464 $lines[] = '<td'.$titleCellAttribs.'>'.$elTitle.'</td>'; 00465 00466 // Remove-indexing-link: 00467 $lines[] = '<td>'.$cmdLinks.'</td>'; 00468 00469 // Query: 00470 $ftrow = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow( 00471 '*', 00472 'index_fulltext', 00473 'phash = '.intval($row['phash']) 00474 ); 00475 $lines[] = '<td style="white-space: normal;">'. 00476 htmlspecialchars(t3lib_div::fixed_lgd_cs($this->utf8_to_currentCharset($ftrow['fulltextdata']), 3000)) . 00477 '<hr/><em>Size: ' . strlen($ftrow['fulltextdata']) . '</em>' . 00478 '</td>'; 00479 00480 // Query: 00481 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00482 'index_words.baseword, index_rel.*', 00483 'index_rel, index_words', 00484 'index_rel.phash = '.intval($row['phash']). 00485 ' AND index_words.wid = index_rel.wid', 00486 '', 00487 '', 00488 '', 00489 'baseword' 00490 ); 00491 00492 $wordList = ''; 00493 if (is_array($ftrows)) { 00494 $indexed_words = array_keys($ftrows); 00495 sort($indexed_words); 00496 $wordList = htmlspecialchars($this->utf8_to_currentCharset(implode(' ',$indexed_words))); 00497 $wordList.='<hr/><em>Count: '.count($indexed_words).'</em>'; 00498 } 00499 00500 $lines[] = '<td style="white-space: normal;">'.$wordList.'</td>'; 00501 break; 00502 default: // Overview 00503 // Display icon: 00504 if (!$grouping) { 00505 $lines[] = '<td>'.$this->makeItemTypeIcon($row['item_type'], $row['data_filename'] ? $row['data_filename'] : $row['item_title']).'</td>'; 00506 } else { 00507 $lines[] = '<td> </td>'; 00508 } 00509 00510 // Title displayed: 00511 $lines[] = '<td'.$titleCellAttribs.'>'.$elTitle.'</td>'; 00512 00513 // Remove-indexing-link: 00514 $lines[] = '<td>'.$cmdLinks.'</td>'; 00515 00516 $lines[] = '<td style="white-space: normal;">'.htmlspecialchars($this->utf8_to_currentCharset($row['item_description'])).'...</td>'; 00517 $lines[] = '<td>'.t3lib_div::formatSize($row['item_size']).'</td>'; 00518 $lines[] = '<td>'.t3lib_BEfunc::dateTimeAge($row['tstamp']).'</td>'; 00519 break; 00520 } 00521 00522 return $lines; 00523 } 00524 00525 /** 00526 * Creates the header row for the table 00527 * 00528 * @return string HTML string (table row) 00529 */ 00530 function printPhashRowHeader() { 00531 $lines = array(); 00532 00533 switch($this->pObj->MOD_SETTINGS['type']) { 00534 case 1: 00535 $lines[] = '<td> </td>'; 00536 $lines[] = '<td> </td>'; 00537 $lines[] = '<td>Title</td>'; 00538 $lines[] = '<td bgcolor="red">'.$this->printRemoveIndexed('ALL','Clear ALL phash-rows below!').'</td>'; 00539 00540 $lines[] = '<td>pHash</td>'; 00541 $lines[] = '<td>contentHash</td>'; 00542 $lines[] = '<td>&id</td>'; 00543 $lines[] = '<td>&type</td>'; 00544 $lines[] = '<td>&L</td>'; 00545 $lines[] = '<td>&MP</td>'; 00546 $lines[] = '<td>grlist</td>'; 00547 $lines[] = '<td>Rootline</td>'; 00548 $lines[] = '<td>page_id</td>'; 00549 $lines[] = '<td>phash_t3</td>'; 00550 $lines[] = '<td>CfgUid</td>'; 00551 $lines[] = '<td>RecUid</td>'; 00552 $lines[] = '<td>GET-parameters</td>'; 00553 $lines[] = '<td>&cHash</td>'; 00554 break; 00555 case 2: 00556 $lines[] = '<td> </td>'; 00557 $lines[] = '<td> </td>'; 00558 $lines[] = '<td>Title</td>'; 00559 $lines[] = '<td bgcolor="red">'.$this->printRemoveIndexed('ALL','Clear ALL phash-rows below!').'</td>'; 00560 $lines[] = '<td>Content<br /> 00561 <img src="clear.gif" width="300" height="1" alt="" /></td>'; 00562 $lines[] = '<td>Words<br /> 00563 <img src="clear.gif" width="300" height="1" alt="" /></td>'; 00564 break; 00565 default: 00566 $lines[] = '<td> </td>'; 00567 $lines[] = '<td> </td>'; 00568 $lines[] = '<td>Title</td>'; 00569 $lines[] = '<td bgcolor="red">'.$this->printRemoveIndexed('ALL','Clear ALL phash-rows below!').'</td>'; 00570 $lines[] = '<td>Description</td>'; 00571 $lines[] = '<td>Size</td>'; 00572 $lines[] = '<td>Indexed:</td>'; 00573 break; 00574 } 00575 00576 $out = '<tr class="tableheader bgColor5">'.implode('',$lines).'</tr>'; 00577 return $out; 00578 } 00579 00580 /** 00581 * Returns the number of columns depending on display type of list 00582 * 00583 * @return integer Number of columns in list: 00584 */ 00585 function returnNumberOfColumns() { 00586 switch($this->pObj->MOD_SETTINGS['type']) { 00587 case 1: 00588 return 18; 00589 break; 00590 case 2: 00591 return 6; 00592 break; 00593 default: 00594 return 7; 00595 break; 00596 } 00597 } 00598 00599 00600 00601 00602 00603 00604 00605 00606 00607 00608 00609 /******************************* 00610 * 00611 * Details display, phash row 00612 * 00613 *******************************/ 00614 00615 /** 00616 * Showing details for a particular phash row 00617 * 00618 * @param integer phash value to display details for. 00619 * @return string HTML content 00620 */ 00621 function showDetailsForPhash($phash) { 00622 00623 $content = ''; 00624 00625 // Selects the result row: 00626 $phashRecord = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow( 00627 '*', 00628 'index_phash', 00629 'phash = '.intval($phash) 00630 ); 00631 00632 // If found, display: 00633 if (is_array($phashRecord)) { 00634 $content.= '<h4>phash row content:</h4>'. 00635 $this->utf8_to_currentCharset(t3lib_div::view_array($phashRecord)); 00636 00637 // Getting debug information if any: 00638 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00639 '*', 00640 'index_debug', 00641 'phash = '.intval($phash) 00642 ); 00643 if (is_array($ftrows)) { 00644 $debugInfo = unserialize($ftrows[0]['debuginfo']); 00645 $lexer = $debugInfo['lexer']; 00646 unset($debugInfo['lexer']); 00647 00648 $content.= '<h3>Debug information:</h3>'. 00649 $this->utf8_to_currentCharset(t3lib_div::view_array($debugInfo)); 00650 00651 $content.= '<h4>Debug information / lexer splitting:</h4>'. 00652 '<hr/><strong>'. 00653 $this->utf8_to_currentCharset($lexer). 00654 '</strong><hr/>'; 00655 } 00656 00657 00658 00659 $content.='<h3>Word statistics</h3>'; 00660 00661 // Finding all words for this phash: 00662 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00663 'index_words.*, index_rel.*', 00664 'index_rel, index_words', 00665 'index_rel.phash = '.intval($phash). 00666 ' AND index_words.wid = index_rel.wid', 00667 '', 00668 'index_words.baseword', 00669 '' 00670 ); 00671 $pageRec = t3lib_BEfunc::getRecord('pages', $phashRecord['data_page_id']); 00672 $showStopWordCheckBox = $GLOBALS['BE_USER']->isAdmin(); 00673 $content.= $this->listWords($ftrows, 'All words found on page ('.count($ftrows).'):', $showStopWordCheckBox, $pageRec); 00674 00675 // Group metaphone hash: 00676 $metaphone = array(); 00677 foreach($ftrows as $row) { 00678 $metaphone[$row['metaphone']][] = $row['baseword']; 00679 } 00680 $content.= $this->listMetaphoneStat($metaphone, 'Metaphone stats:'); 00681 00682 // Finding top-20 on frequency for this phash: 00683 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00684 'index_words.baseword, index_words.metaphone, index_rel.*', 00685 'index_rel, index_words', 00686 'index_rel.phash = '.intval($phash). 00687 ' AND index_words.wid = index_rel.wid 00688 AND index_words.is_stopword=0', 00689 '', 00690 'index_rel.freq DESC', 00691 '20' 00692 ); 00693 $content.= $this->listWords($ftrows, 'Top-20 words by frequency:', 2); 00694 00695 // Finding top-20 on count for this phash: 00696 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00697 'index_words.baseword, index_words.metaphone, index_rel.*', 00698 'index_rel, index_words', 00699 'index_rel.phash = '.intval($phash). 00700 ' AND index_words.wid = index_rel.wid 00701 AND index_words.is_stopword=0', 00702 '', 00703 'index_rel.count DESC', 00704 '20' 00705 ); 00706 $content.= $this->listWords($ftrows, 'Top-20 words by count:', 2); 00707 00708 00709 $content.='<h3>Section records for this phash</h3>'; 00710 00711 // Finding sections for this record: 00712 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00713 '*', 00714 'index_section', 00715 'index_section.phash = '.intval($phash), 00716 '', 00717 '', 00718 '' 00719 ); 00720 $content.= t3lib_div::view_array($ftrows); 00721 00722 // Add go-back link: 00723 $content = $this->linkList().$content.$this->linkList(); 00724 00725 } else $content.= 'Error: No phash row found'; 00726 00727 return $content; 00728 } 00729 00730 /** 00731 * Create table with list of words from $ftrows 00732 * 00733 * @param array Array of records selected from index_rel/index_words 00734 * @param string Header string to show before table. 00735 * @param boolean If set, the stopWord checkboxes will be shown in the word list. Only for admins. (because it is a global setting, not per-site). 00736 * @param array The page record from which to load the keywords, if any. 00737 * @return string HTML table 00738 */ 00739 function listWords($ftrows,$header, $stopWordBoxes=FALSE, $page='') { 00740 00741 // Prepare keywords: 00742 $keywords = is_array($page) ? array_flip(t3lib_div::trimExplode(',',$page['keywords'], 1)) : ''; 00743 00744 // Render list: 00745 $trows = ''; 00746 $trows.= ' 00747 <tr class="tableheader bgColor5"> 00748 '.($stopWordBoxes ? '<td>'.htmlspecialchars('Stopword:').'</td>' : '').' 00749 <td>'.htmlspecialchars('Word:').'</td> 00750 <td>'.htmlspecialchars('Count:').'</td> 00751 <td>'.htmlspecialchars('First:').'</td> 00752 <td>'.htmlspecialchars('Frequency:').'</td> 00753 <td>'.htmlspecialchars('Flags:').'</td> 00754 '.(is_array($keywords) ? '<td>'.htmlspecialchars('Page keyword:').'</td>' : '').' 00755 </tr> 00756 '; 00757 foreach($ftrows as $row) { 00758 $hiddenField = $stopWordBoxes!=2 ? '<input type="hidden" name="stopWord['.$row['wid'].']" value="0" />' : ''; 00759 $trows.= ' 00760 <tr class="'.($row['is_stopword'] ? 'bgColor' : 'bgColor4').'"> 00761 '.($stopWordBoxes ? '<td align="center"'.($row['is_stopword'] ? ' style="background-color:red;"' : '').'>'.$hiddenField.'<input type="checkbox" name="stopWord['.$row['wid'].']" value="1"'.($row['is_stopword']?'checked="checked"':'').' /></td>' : '').' 00762 <td>'.$this->linkWordDetails(htmlspecialchars($this->utf8_to_currentCharset($row['baseword'])), $row['wid']).'</td> 00763 <td>'.htmlspecialchars($row['count']).'</td> 00764 <td>'.htmlspecialchars($row['first']).'</td> 00765 <td>'.htmlspecialchars($row['freq']).'</td> 00766 <td>'.htmlspecialchars($this->flagsMsg($row['flags'])).'</td> 00767 '.(is_array($keywords) ? '<td align="center"'.(isset($keywords[$row['baseword']]) ? ' class="bgColor2"' : '').'><input type="hidden" name="pageKeyword['.$row['baseword'].']" value="0" /><input type="checkbox" name="pageKeyword['.$row['baseword'].']" value="1"'.(isset($keywords[$row['baseword']])?'checked="checked"':'').' /></td>' : '').' 00768 </tr> 00769 '; 00770 } 00771 00772 return '<h4>'.htmlspecialchars($header).'</h4>'. 00773 ' 00774 <table border="0" cellspacing="1" cellpadding="2" class="c-list"> 00775 '.$trows.' 00776 </table>'. 00777 ($stopWordBoxes ? '<input type="submit" value="Change stop-word settings" name="_stopwords" onclick="document.webinfoForm.action=\''.htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')).'\';" />' : ''). 00778 (is_array($keywords) ? '<input type="submit" value="Set page keywords" name="_pageKeywords" onclick="document.webinfoForm.action=\''.htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')).'\';" /><input type="hidden" name="pageKeyword_pageUid" value="'.$page['uid'].'" />'. 00779 '<br />Current keywords are: <em>' . htmlspecialchars(implode(', ', array_keys($keywords))) . '</em>' : ''); 00780 } 00781 00782 /** 00783 * Displays table of metaphone groups larger than 1 00784 * 00785 * @param array Result from word selection (index_rel/index_words) 00786 * @param string Header string 00787 * @return string HTML table 00788 */ 00789 function listMetaphoneStat($ftrows,$header) { 00790 00791 $trows = ''; 00792 $trows.= ' 00793 <tr class="tableheader bgColor5"> 00794 <td>'.htmlspecialchars('Metaphone:').'</td> 00795 <td>'.htmlspecialchars('Hash:').'</td> 00796 <td>'.htmlspecialchars('Count:').'</td> 00797 <td>'.htmlspecialchars('Words:').'</td> 00798 </tr> 00799 '; 00800 foreach($ftrows as $metaphone => $words) { 00801 if (count($words)>1) { 00802 $trows.= ' 00803 <tr class="bgColor4"> 00804 <td>'.$this->linkMetaPhoneDetails($this->indexerObj->metaphone($words[0],1),$metaphone).'</td> 00805 <td>'.htmlspecialchars($metaphone).'</td> 00806 <td>'.htmlspecialchars(count($words)).'</td> 00807 <td style="white-space: normal;">'.htmlspecialchars($this->utf8_to_currentCharset(implode(', ',$words))).'</td> 00808 </tr> 00809 '; 00810 } 00811 } 00812 00813 return '<h4>'.htmlspecialchars($header).'</h4>'. 00814 '<table border="0" cellspacing="1" cellpadding="2" class="c-list"> 00815 '.$trows.' 00816 </table>'; 00817 } 00818 00819 /** 00820 * Wraps input string in a link that will display details for the word. Eg. which other pages has the word, metaphone associations etc. 00821 * 00822 * @param string String to wrap, possibly a title or so. 00823 * @param integer wid value to show details for 00824 * @return string Wrapped string 00825 */ 00826 function linkWordDetails($string,$wid) { 00827 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('wid'=>$wid,'phash'=>''))).'">'.$string.'</a>'; 00828 } 00829 00830 00831 /** 00832 * Wraps input string in a link to see more details for metaphone value 00833 * 00834 * @param string String to wrap 00835 * @param integer Metaphone value 00836 * @return string Wrapped string 00837 */ 00838 function linkMetaPhoneDetails($string,$metaphone) { 00839 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('metaphone'=>$metaphone,'wid'=>'','phash'=>''))).'">'.$string.'</a>'; 00840 } 00841 00842 /** 00843 * Creates message for flag value 00844 * 00845 * @param integer Flags integer 00846 * @return string Message string 00847 */ 00848 function flagsMsg($flags) { 00849 if ($flags > 0) { 00850 return 00851 ($flags & 128 ? '<title>' : ''). // pow(2,7) 00852 ($flags & 64 ? '<meta/keywords>' : ''). // pow(2,6) 00853 ($flags & 32 ? '<meta/description>' : ''). // pow(2,5) 00854 ' ('.$flags.')'; 00855 } 00856 } 00857 00858 00859 00860 00861 00862 00863 00864 00865 00866 00867 /******************************* 00868 * 00869 * Details display, words / metaphone 00870 * 00871 *******************************/ 00872 00873 /** 00874 * Show details for words 00875 * 00876 * @param integer Word ID (wid) 00877 * @return string HTML content 00878 */ 00879 function showDetailsForWord($wid) { 00880 00881 // Select references to this word 00882 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00883 'index_phash.*, index_section.*, index_rel.*', 00884 'index_rel, index_section, index_phash', 00885 'index_rel.wid = '.intval($wid). 00886 ' AND index_rel.phash = index_section.phash'. 00887 ' AND index_section.phash = index_phash.phash', 00888 '', 00889 'index_rel.freq DESC', 00890 '' 00891 ); 00892 00893 // Headers: 00894 $content.=' 00895 <tr class="tableheader bgColor5"> 00896 <td>phash</td> 00897 <td>page_id</td> 00898 <td>data_filename</td> 00899 <td>count</td> 00900 <td>first</td> 00901 <td>freq</td> 00902 <td>flags</td> 00903 </tr>'; 00904 00905 if (is_array($ftrows)) { 00906 foreach($ftrows as $wDat) { 00907 $content.=' 00908 <tr class="bgColor4"> 00909 <td>'.$this->linkDetails(htmlspecialchars($wDat['phash']),$wDat['phash']).'</td> 00910 <td>'.htmlspecialchars($wDat['page_id']).'</td> 00911 <td>'.htmlspecialchars($wDat['data_filename']).'</td> 00912 <td>'.htmlspecialchars($wDat['count']).'</td> 00913 <td>'.htmlspecialchars($wDat['first']).'</td> 00914 <td>'.htmlspecialchars($wDat['freq']).'</td> 00915 <td>'.htmlspecialchars($wDat['flags']).'</td> 00916 </tr>'; 00917 } 00918 } 00919 00920 // Compile table: 00921 $content = ' 00922 <table border="0" cellspacing="1" cellpadding="2" class="c-list">'. 00923 $content.' 00924 </table>'; 00925 00926 // Add go-back link: 00927 $content = $content.$this->linkList(); 00928 00929 return $content; 00930 } 00931 00932 /** 00933 * Show details for metaphone value 00934 * 00935 * @param integer Metaphone integer hash 00936 * @return string HTML content 00937 */ 00938 function showDetailsForMetaphone($metaphone) { 00939 00940 // Finding top-20 on frequency for this phash: 00941 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 00942 'index_words.*', 00943 'index_words', 00944 'index_words.metaphone = '.intval($metaphone), 00945 '', 00946 'index_words.baseword', 00947 '' 00948 ); 00949 00950 if (count($ftrows)) { 00951 $content.='<h4>Metaphone: '.$this->indexerObj->metaphone($ftrows[0]['baseword'],1).'</h4>'; 00952 00953 $content.=' 00954 <tr class="tableheader bgColor5"> 00955 <td>Word</td> 00956 <td>Is stopword?</td> 00957 </tr>'; 00958 00959 if (is_array($ftrows)) { 00960 foreach($ftrows as $wDat) { 00961 $content.=' 00962 <tr class="bgColor4"> 00963 <td>'.$this->linkWordDetails(htmlspecialchars($wDat['baseword']),$wDat['wid']).'</td> 00964 <td>'.htmlspecialchars($wDat['is_stopword'] ? 'YES' : 'No').'</td> 00965 </tr>'; 00966 } 00967 } 00968 00969 $content = ' 00970 <table border="0" cellspacing="1" cellpadding="2" class="c-list">'. 00971 $content.' 00972 </table>'; 00973 00974 if ($this->indexerObj->metaphone($ftrows[0]['baseword'])!=$metaphone) { 00975 $content.='ERROR: Metaphone string and hash did not match for some reason!?'; 00976 } 00977 00978 // Add go-back link: 00979 $content = $content.$this->linkList(); 00980 } 00981 00982 return $content; 00983 } 00984 00985 00986 00987 00988 00989 00990 00991 00992 00993 00994 00995 00996 /******************************* 00997 * 00998 * Helper functions 00999 * 01000 *******************************/ 01001 01002 /** 01003 * Creates icon which clears indexes for a certain list of phash values. 01004 * 01005 * @param string List of phash integers 01006 * @param string Alt-text for the garbage bin icon. 01007 * @return string HTML img-tag with link around. 01008 */ 01009 function printRemoveIndexed($phash,$alt) { 01010 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('deletePhash'=>$phash))).'" title="' . htmlspecialchars($alt) . '">' . 01011 t3lib_iconWorks::getSpriteIcon('actions-edit-delete') . 01012 '</a>'; 01013 } 01014 01015 /** 01016 * Button for re-indexing of documents 01017 * 01018 * @param array phash table result row. 01019 * @param string Title attribute text for icon 01020 * @return string HTML content; Icon wrapped in link. 01021 */ 01022 function printReindex($resultRow,$alt) { 01023 if ($resultRow['item_type'] && $resultRow['item_type']!=='0') { 01024 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('reindex'=>$resultRow['phash'],'reindex_id'=>$resultRow['page_id']))).'">'. 01025 '<img '.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], 'gfx/refresh_n.gif', 'width="14" height="14"') . ' hspace="1" vspace="2" border="0" title="'.htmlspecialchars($alt).'" alt="" />'. 01026 '</a>'; 01027 } 01028 } 01029 01030 /** 01031 * Wraps input string in a link that will display details for the phash value set. 01032 * 01033 * @param string String to wrap, possibly a title or so. 01034 * @param integer phash value to show details for 01035 * @return string Wrapped string 01036 */ 01037 function linkDetails($string,$phash) { 01038 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('phash'=>$phash))).'">'.$string.'</a>'; 01039 } 01040 01041 /** 01042 * Creates link back to listing 01043 * 01044 * @return string Link back to list 01045 */ 01046 function linkList() { 01047 return '<br /><a href="index.php?id=' . $this->pObj->id . '">Back to list.</a><br />'; 01048 } 01049 01050 /** 01051 * Wraps input string in a link that will display details for the phash value set. 01052 * 01053 * @param string String to wrap, possibly a title or so. 01054 * @param integer phash value to show details for 01055 * @return string Wrapped string 01056 */ 01057 function showPageDetails($string,$id) { 01058 return '<a href="'.htmlspecialchars('index.php?id='.$id.'&SET[depth]=0&SET[type]=1').'">'.$string.'</a>'; 01059 } 01060 01061 /** 01062 * Prints the gr_lists attached to a indexed entry. 01063 * 01064 * @param array Array of index_grlist records 01065 * @return string HTML code. 01066 */ 01067 function printExtraGrListRows($extraGrListRows) { 01068 if (count($extraGrListRows)) { 01069 $lines=array(); 01070 foreach ($extraGrListRows as $r) { 01071 $lines[] = $r['gr_list']; 01072 } 01073 return '<br />' . $GLOBALS['TBE_TEMPLATE']->dfw(implode('<br />', $lines)); 01074 } 01075 } 01076 01077 /** 01078 * Print path for indexing 01079 * 01080 * @param array Result row with content from index_section 01081 * @return string Rootline information 01082 */ 01083 function printRootlineInfo($row) { 01084 $uidCollection = array(); 01085 01086 if ($row['rl0']) { 01087 $uidCollection[0] = $row['rl0']; 01088 if ($row['rl1']) { 01089 $uidCollection[1] = $row['rl1']; 01090 if ($row['rl2']) { 01091 $uidCollection[2] = $row['rl2']; 01092 01093 // Additional levels: 01094 if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['addRootLineFields'])) { 01095 foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['addRootLineFields'] as $fieldName => $rootLineLevel) { 01096 if ($row[$fieldName]) { 01097 $uidCollection[$rootLineLevel] = $row[$fieldName]; 01098 } 01099 } 01100 } 01101 } 01102 } 01103 } 01104 01105 // Return root line. 01106 ksort($uidCollection); 01107 return implode('/',$uidCollection); 01108 } 01109 01110 /** 01111 * Return icon for file extension 01112 * 01113 * @param string File extension / item type 01114 * @param string Title attribute value in icon. 01115 * @return string <img> tag for icon 01116 */ 01117 function makeItemTypeIcon($it,$alt='') { 01118 if (!isset($this->iconFileNameCache[$it])) { 01119 if ($it==='0') { 01120 $icon = 'EXT:indexed_search/pi/res/pages.gif'; 01121 } elseif ($this->external_parsers[$it]) { 01122 $icon = $this->external_parsers[$it]->getIcon($it); 01123 } 01124 01125 $fullPath = t3lib_div::getFileAbsFileName($icon); 01126 01127 if ($fullPath) { 01128 $info = @getimagesize($fullPath); 01129 $iconPath = $GLOBALS['BACK_PATH'].'../'.substr($fullPath,strlen(PATH_site)); 01130 $this->iconFileNameCache[$it] = is_array($info) ? '<img src="'.$iconPath.'" '.$info[3].' title="###TITLE_ATTRIBUTE###" alt="" />' : ''; 01131 } 01132 } 01133 return str_replace('###TITLE_ATTRIBUTE###',htmlspecialchars($it.': '.$alt),$this->iconFileNameCache[$it]); 01134 } 01135 01136 /** 01137 * Converts the input string from utf-8 to the backend charset. 01138 * 01139 * @param string String to convert (utf-8) 01140 * @return string Converted string (backend charset if different from utf-8) 01141 */ 01142 function utf8_to_currentCharset($string) { 01143 global $LANG; 01144 if ($LANG->charSet != 'utf-8') { 01145 $string = $LANG->csConvObj->utf8_decode($string, $LANG->charSet, TRUE); 01146 } 01147 return $string; 01148 } 01149 01150 01151 01152 01153 01154 01155 01156 01157 01158 01159 01160 01161 /******************************** 01162 * 01163 * Reindexing 01164 * 01165 *******************************/ 01166 01167 /** 01168 * Re-indexing files/records attached to a page. 01169 * 01170 * @param integer Phash value 01171 * @param integer The page uid for the section record (file/url could appear more than one place you know...) 01172 * @return string HTML content 01173 */ 01174 function reindexPhash($phash, $pageId) { 01175 01176 // Query: 01177 $resultRow = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow( 01178 'ISEC.*, IP.*', 01179 'index_phash IP, index_section ISEC', 01180 'IP.phash = ISEC.phash 01181 AND IP.phash = '.intval($phash).' 01182 AND ISEC.page_id = '.intval($pageId) 01183 ); 01184 01185 $content = ''; 01186 if (is_array($resultRow)) { 01187 if ($resultRow['item_type'] && $resultRow['item_type']!=='0') { 01188 01189 // (Re)-Indexing file on page. 01190 $indexerObj = t3lib_div::makeInstance('tx_indexedsearch_indexer'); 01191 $indexerObj->backend_initIndexer($pageId, 0, 0, '', $this->getUidRootLineForClosestTemplate($pageId)); 01192 01193 // URL or local file: 01194 if ($resultRow['externalUrl']) { 01195 $indexerObj->indexExternalUrl($resultRow['data_filename']); 01196 } else { 01197 $indexerObj->indexRegularDocument($resultRow['data_filename'], TRUE); 01198 } 01199 01200 if ($indexerObj->file_phash_arr['phash'] != $resultRow['phash']) { 01201 $content.= 'ERROR: phash ('.$indexerObj->file_phash_arr['phash'].') did NOT match '.$resultRow['phash'].' for strange reasons!'; 01202 } 01203 01204 $content.='<h4>Log for re-indexing of "'.htmlspecialchars($resultRow['data_filename']).'":</h4>'; 01205 $content.=t3lib_div::view_array($indexerObj->internal_log); 01206 01207 $content.='<h4>Hash-array, page:</h4>'; 01208 $content.=t3lib_div::view_array($indexerObj->hash); 01209 01210 $content.='<h4>Hash-array, file:</h4>'; 01211 $content.=t3lib_div::view_array($indexerObj->file_phash_arr); 01212 } 01213 } 01214 01215 // Link back to list. 01216 $content.= $this->linkList(); 01217 01218 return $content; 01219 } 01220 01221 /** 01222 * Get rootline for closest TypoScript template root. 01223 * Algorithm same as used in Web > Template, Object browser 01224 * 01225 * @param integer The page id to traverse rootline back from 01226 * @return array Array where the root lines uid values are found. 01227 */ 01228 function getUidRootLineForClosestTemplate($id) { 01229 $tmpl = t3lib_div::makeInstance('t3lib_tsparser_ext'); // Defined global here! 01230 $tmpl->tt_track = 0; // Do not log time-performance information 01231 $tmpl->init(); 01232 01233 // Gets the rootLine 01234 $sys_page = t3lib_div::makeInstance('t3lib_pageSelect'); 01235 $rootLine = $sys_page->getRootLine($id); 01236 $tmpl->runThroughTemplates($rootLine,0); // This generates the constants/config + hierarchy info for the template. 01237 01238 // Root line uids 01239 $rootline_uids = array(); 01240 foreach($tmpl->rootLine as $rlkey => $rldat) { 01241 $rootline_uids[$rlkey] = $rldat['uid']; 01242 } 01243 01244 return $rootline_uids; 01245 } 01246 01247 01248 01249 01250 01251 01252 01253 01254 01255 01256 01257 01258 /******************************** 01259 * 01260 * SQL functions 01261 * 01262 *******************************/ 01263 01264 /** 01265 * Removes ALL data regarding a certain list of indexed phash-row 01266 * 01267 * @param string List of phash integers 01268 * @param boolean If set, page cache is cleared as well. 01269 * @return void 01270 */ 01271 function removeIndexedPhashRow($phashList,$clearPageCache=1) { 01272 // FIXME: This is only a workaround 01273 if ($phashList=='ALL') { 01274 $this->drawTableOfIndexedPages(); 01275 $phashRows = $this->allPhashListed; 01276 $this->allPhashListed = array(); // Reset it because it will be filled again later... 01277 } else { 01278 $phashRows = t3lib_div::trimExplode(',',$phashList,1); 01279 } 01280 01281 foreach($phashRows as $phash) { 01282 $phash = intval($phash); 01283 if ($phash>0) { 01284 01285 if ($clearPageCache) { 01286 // Clearing page cache: 01287 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('page_id', 'index_section', 'phash='.intval($phash)); 01288 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) { 01289 $idList = array(); 01290 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 01291 $idList[] = (int)$row['page_id']; 01292 } 01293 01294 if (TYPO3_UseCachingFramework) { 01295 $pageCache = $GLOBALS['typo3CacheManager']->getCache('cache_pages'); 01296 foreach ($idList as $pageId) { 01297 $pageCache->flushByTag('pageId_' . $pageId); 01298 } 01299 } else { 01300 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages', 'page_id IN (' . implode(',', $idList) . ')'); 01301 } 01302 } 01303 } 01304 01305 // Removing old registrations for all tables. 01306 $tableArr = explode(',','index_phash,index_rel,index_section,index_grlist,index_fulltext,index_debug'); 01307 foreach($tableArr as $table) { 01308 $GLOBALS['TYPO3_DB']->exec_DELETEquery($table, 'phash='.intval($phash)); 01309 } 01310 01311 // Did not remove any index_section records for external files where phash_t3 points to this hash! 01312 } 01313 } 01314 } 01315 01316 /** 01317 * Returns an array with gr_list records for a phash 01318 * 01319 * @param integer phash integer to look up on 01320 * @param string gr_list string to filter OUT of the result (first occurence) 01321 * @return array Array of records from index_grlist table 01322 */ 01323 function getGrListEntriesForPhash($phash,$gr_list) { 01324 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'index_grlist', 'phash='.intval($phash)); 01325 $lines = array(); 01326 $isRemoved = 0; 01327 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 01328 if (!$isRemoved && !strcmp($row['gr_list'],$gr_list)) { 01329 $isRemoved = 1; 01330 } else { 01331 $lines[] = $row; 01332 } 01333 } 01334 return $lines; 01335 } 01336 01337 /** 01338 * Setting / Unsetting stopwords 01339 * 01340 * @param array Array of stop-words WIDs with 0/1 to set / unset 01341 * @return void 01342 */ 01343 function processStopWords($stopWords) { 01344 01345 if ($GLOBALS['BE_USER']->isAdmin()) { 01346 // Traverse words 01347 foreach($stopWords as $wid => $state) { 01348 $fieldArray = array( 01349 'is_stopword' => $state 01350 ); 01351 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('index_words', 'wid='.$wid, $fieldArray); 01352 } 01353 } 01354 } 01355 01356 /** 01357 * Setting / Unsetting keywords in page header 01358 * 01359 * @param array Page keywords as keys in array with value 0 or 1 for set or unset. 01360 * @param integer The page uid of the header where the keywords are to be set. 01361 * @return void 01362 */ 01363 function processPageKeywords($pageKeywords, $pageUid) { 01364 01365 // Get pages current keywords 01366 $pageRec = t3lib_BEfunc::getRecord('pages', $pageUid); 01367 $keywords = array_flip(t3lib_div::trimExplode(',', $pageRec['keywords'], 1)); 01368 01369 // Merge keywords: 01370 foreach($pageKeywords as $key => $v) { 01371 if ($v) { 01372 $keywords[$key]=1; 01373 } else { 01374 unset($keywords[$key]); 01375 } 01376 } 01377 01378 // Compile new list: 01379 $data = array(); 01380 $data['pages'][$pageUid]['keywords'] = implode(', ',array_keys($keywords)); 01381 01382 $tce = t3lib_div::makeInstance('t3lib_TCEmain'); 01383 $tce->stripslashes_values = 0; 01384 $tce->start($data,array()); 01385 $tce->process_datamap(); 01386 } 01387 } 01388 01389 01390 01391 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/indexed_search/modfunc1/class.tx_indexedsearch_modfunc1.php'])) { 01392 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/indexed_search/modfunc1/class.tx_indexedsearch_modfunc1.php']); 01393 } 01394 01395 ?>
1.8.0