Fixed bug #12872: Use "strong" instead of "b": typo3/sysext/
[Packages/TYPO3.CMS.git] / typo3 / sysext / indexed_search / modfunc1 / class.tx_indexedsearch_modfunc1.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2001-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24 /**
25 * Module extension (addition to function menu) 'Indexed search' for the 'indexed_search' extension.
26 *
27 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
28 */
29 /**
30 * [CLASS/FUNCTION INDEX of SCRIPT]
31 *
32 *
33 *
34 * 106: class tx_indexedsearch_modfunc1 extends t3lib_extobjbase
35 * 120: function modMenu()
36 * 144: function main()
37 *
38 * SECTION: Drawing table of indexed pages
39 * 248: function drawTableOfIndexedPages()
40 * 299: function indexed_info($data, $firstColContent)
41 * 386: function printPhashRow($row,$grouping=0,$extraGrListRows)
42 * 527: function printPhashRowHeader()
43 * 582: function returnNumberOfColumns()
44 *
45 * SECTION: Details display, phash row
46 * 618: function showDetailsForPhash($phash)
47 * 737: function listWords($ftrows,$header, $stopWordBoxes=FALSE, $page='')
48 * 787: function listMetaphoneStat($ftrows,$header)
49 * 824: function linkWordDetails($string,$wid)
50 * 836: function linkMetaPhoneDetails($string,$metaphone)
51 * 846: function flagsMsg($flags)
52 *
53 * SECTION: Details display, words / metaphone
54 * 877: function showDetailsForWord($wid)
55 * 936: function showDetailsForMetaphone($metaphone)
56 *
57 * SECTION: Helper functions
58 * 1007: function printRemoveIndexed($phash,$alt)
59 * 1020: function printReindex($resultRow,$alt)
60 * 1035: function linkDetails($string,$phash)
61 * 1044: function linkList()
62 * 1055: function showPageDetails($string,$id)
63 * 1065: function printExtraGrListRows($extraGrListRows)
64 * 1082: function printRootlineInfo($row)
65 * 1116: function makeItemTypeIcon($it,$alt='')
66 * 1141: function utf8_to_currentCharset($string)
67 *
68 * SECTION: Reindexing
69 * 1173: function reindexPhash($phash, $pageId)
70 * 1227: function getUidRootLineForClosestTemplate($id)
71 *
72 * SECTION: SQL functions
73 * 1270: function removeIndexedPhashRow($phashList,$clearPageCache=1)
74 * 1314: function getGrListEntriesForPhash($phash,$gr_list)
75 * 1334: function processStopWords($stopWords)
76 * 1354: function processPageKeywords($pageKeywords, $pageUid)
77 *
78 * TOTAL FUNCTIONS: 30
79 * (This index is automatically created/updated by the extension "extdeveval")
80 *
81 */
82
83
84 require_once(t3lib_extMgm::extPath('indexed_search').'class.indexer.php');
85
86
87 /**
88 * Indexing class for TYPO3 frontend
89 *
90 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
91 * @package TYPO3
92 * @subpackage tx_indexedsearch
93 */
94 class tx_indexedsearch_modfunc1 extends t3lib_extobjbase {
95
96 // Internal, dynamic:
97 var $allPhashListed = array(); // phash values accumulations for link to clear all
98 var $external_parsers = array(); // External content parsers - objects set here with file extensions as keys.
99 var $iconFileNameCache = array(); // File extensions - icon map/cache.
100
101 /**
102 * Indexer object
103 *
104 * @var tx_indexedsearch_indexer
105 */
106 var $indexerObj;
107
108
109 /**
110 * Initialize menu array internally
111 *
112 * @return void
113 */
114 function modMenu() {
115 global $LANG;
116
117 return array (
118 'depth' => array(
119 0 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_0'),
120 1 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_1'),
121 2 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_2'),
122 3 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_3'),
123 999 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_infi'),
124 ),
125 'type' => array(
126 0 => 'Overview',
127 1 => 'Technical Details',
128 2 => 'Words and content',
129 )
130 );
131 }
132
133 /**
134 * Produces main content of the module
135 *
136 * @return string HTML output
137 */
138 function main() {
139 // Initializes the module. Done in this function because we may need to re-initialize if data is submitted!
140 global $LANG,$TYPO3_CONF_VARS;
141
142 // Return if no page id:
143 if ($this->pObj->id<=0) return;
144
145 // Initialize max-list items
146 $this->maxListPerPage = t3lib_div::_GP('listALL') ? 100000 : 100;
147
148 // Processing deletion of phash rows:
149 if (t3lib_div::_GP('deletePhash')) {
150 $this->removeIndexedPhashRow(t3lib_div::_GP('deletePhash'));
151 }
152
153 // Processing stop-words:
154 if (t3lib_div::_POST('_stopwords')) {
155 $this->processStopWords(t3lib_div::_POST('stopWord'));
156 }
157
158 // Processing stop-words:
159 if (t3lib_div::_POST('_pageKeywords')) {
160 $this->processPageKeywords(t3lib_div::_POST('pageKeyword'), t3lib_div::_POST('pageKeyword_pageUid'));
161 }
162
163 // Initialize external document parsers:
164 // Example configuration, see ext_localconf.php of this file!
165 if (is_array($TYPO3_CONF_VARS['EXTCONF']['indexed_search']['external_parsers'])) {
166 foreach($TYPO3_CONF_VARS['EXTCONF']['indexed_search']['external_parsers'] as $extension => $_objRef) {
167 $this->external_parsers[$extension] = t3lib_div::getUserObj($_objRef);
168
169 // Init parser and if it returns false, unset its entry again:
170 if (!$this->external_parsers[$extension]->softInit($extension)) {
171 unset($this->external_parsers[$extension]);
172 }
173 }
174 }
175
176 // Initialize indexer if we need it (metaphone display does...)
177 $this->indexerObj = t3lib_div::makeInstance('tx_indexedsearch_indexer');
178
179 // Set CSS styles specific for this document:
180 $this->pObj->content = str_replace('/*###POSTCSSMARKER###*/','
181 TABLE.c-list TR TD { white-space: nowrap; vertical-align: top; }
182 ',$this->pObj->content);
183
184
185 // Check if details for a phash record should be shown:
186 if (t3lib_div::_GET('phash')) {
187
188 // Show title / function menu:
189 $theOutput.=$this->pObj->doc->spacer(5);
190 $theOutput.=$this->pObj->doc->section('Details for a single result row:',$this->showDetailsForPhash(t3lib_div::_GET('phash')),0,1);
191
192 } elseif (t3lib_div::_GET('wid')) {
193 // Show title / function menu:
194 $theOutput.=$this->pObj->doc->spacer(5);
195 $theOutput.=$this->pObj->doc->section('Details for a word:',$this->showDetailsForWord(t3lib_div::_GET('wid')),0,1);
196
197 } elseif (t3lib_div::_GET('metaphone')) {
198 // Show title / function menu:
199 $theOutput.=$this->pObj->doc->spacer(5);
200 $theOutput.=$this->pObj->doc->section('Details for metaphone value:',$this->showDetailsForMetaphone(t3lib_div::_GET('metaphone')),0,1);
201
202 } elseif (t3lib_div::_GET('reindex')) {
203 // Show title / function menu:
204 $theOutput.=$this->pObj->doc->spacer(5);
205 $theOutput.=$this->pObj->doc->section('Reindexing...',$this->reindexPhash(t3lib_div::_GET('reindex'),t3lib_div::_GET('reindex_id')),0,1);
206
207 } else { // Detail listings:
208 // Depth function menu:
209 $h_func = t3lib_BEfunc::getFuncMenu($this->pObj->id,'SET[type]',$this->pObj->MOD_SETTINGS['type'],$this->pObj->MOD_MENU['type'],'index.php');
210 $h_func.= t3lib_BEfunc::getFuncMenu($this->pObj->id,'SET[depth]',$this->pObj->MOD_SETTINGS['depth'],$this->pObj->MOD_MENU['depth'],'index.php');
211
212 // Show title / function menu:
213 $theOutput.=$this->pObj->doc->spacer(5);
214 $theOutput.=$this->pObj->doc->section($LANG->getLL('title'),$h_func,0,1);
215
216 $theOutput.=$this->drawTableOfIndexedPages();
217 }
218
219 return $theOutput;
220 }
221
222
223
224
225
226
227
228
229
230
231
232 /*******************************
233 *
234 * Drawing table of indexed pages
235 *
236 ******************************/
237
238 /**
239 * Produces a table with indexing information for each page.
240 *
241 * @return string HTML output
242 */
243 function drawTableOfIndexedPages() {
244 global $BACK_PATH;
245
246 // Drawing tree:
247 $tree = t3lib_div::makeInstance('t3lib_pageTree');
248 $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
249 $tree->init('AND '.$perms_clause);
250
251 $HTML = '<img src="'.$BACK_PATH.t3lib_iconWorks::getIcon('pages',$this->pObj->pageinfo).'" width="18" height="16" align="top" alt="" />';
252 $tree->tree[] = Array(
253 'row' => $this->pObj->pageinfo,
254 'HTML' => $HTML
255 );
256
257 if ($this->pObj->MOD_SETTINGS['depth']) {
258 $tree->getTree($this->pObj->id, $this->pObj->MOD_SETTINGS['depth'], '');
259 }
260
261 // Traverse page tree:
262 $code = '';
263 foreach($tree->tree as $data) {
264 $code.= $this->indexed_info(
265 $data['row'],
266 $data['HTML'].
267 $this->showPageDetails(t3lib_div::fixed_lgd_cs($data['row']['title'], 20),$data['row']['uid'])
268 );
269 }
270
271 if ($code) {
272 $code = '<br /><br />
273 <table border="0" cellspacing="1" cellpadding="2" class="c-list">'.
274 $this->printPhashRowHeader().
275 $code.
276 '</table>';
277
278 // Create section to output:
279 $theOutput.=$this->pObj->doc->section('',$code,0,1);
280 } else {
281 $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);
282 }
283
284 return $theOutput;
285 }
286
287 /**
288 * Create information table row for a page regarding indexing information.
289 *
290 * @param array Data array for this page
291 * @param string HTML content for first column (page tree icon etc.)
292 * @return string HTML code. (table row)
293 */
294 function indexed_info($data, $firstColContent) {
295
296 // Query:
297 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
298 'ISEC.phash_t3, ISEC.rl0, ISEC.rl1, ISEC.rl2, ISEC.page_id, ISEC.uniqid, ' .
299 'IP.phash, IP.phash_grouping, IP.cHashParams, IP.data_filename, IP.data_page_id, ' .
300 'IP.data_page_reg1, IP.data_page_type, IP.data_page_mp, IP.gr_list, IP.item_type, ' .
301 'IP.item_title, IP.item_description, IP.item_mtime, IP.tstamp, IP.item_size, ' .
302 'IP.contentHash, IP.crdate, IP.parsetime, IP.sys_language_uid, IP.item_crdate, ' .
303 'IP.externalUrl, IP.recordUid, IP.freeIndexUid, IP.freeIndexSetId, count(*) AS count_val',
304 'index_phash IP, index_section ISEC',
305 'IP.phash = ISEC.phash AND ISEC.page_id = '.intval($data['uid']),
306 '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',
307 'IP.item_type, IP.tstamp',
308 ($this->maxListPerPage+1)
309 );
310
311 // Initialize variables:
312 $rowCount = 0;
313 $lines = array(); // Collecting HTML rows here.
314 $phashAcc = array(); // Collecting phash values (to remove local indexing for)
315 $phashAcc[] = 0;
316
317 // Traverse the result set of phash rows selected:
318 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
319 if ($rowCount == $this->maxListPerPage) {
320 $rowCount++; // Increase to the extra warning row will appear as well.
321 break;
322 }
323
324 // Adds a display row:
325 $lines[$row['phash_grouping']][] = $this->printPhashRow(
326 $row,
327 isset($lines[$row['phash_grouping']]),
328 $this->getGrListEntriesForPhash($row['phash'], $row['gr_list'])
329 );
330 $rowCount++;
331 $phashAcc[] = $row['phash'];
332 $this->allPhashListed[] = $row['phash']; // For removing all shown phash rows.
333 }
334
335 // Compile rows into the table:
336 $out = '';
337 $cellAttrib = ($data['_CSSCLASS'] ? ' class="'.$data['_CSSCLASS'].'"' : '');
338 if (count($lines)) {
339 $firstColContent = '<td rowspan="'.$rowCount.'"'.$cellAttrib.'>'.$firstColContent.'</td>';
340 foreach($lines as $rowSet) {
341 foreach($rowSet as $rows) {
342 $out.='
343 <tr class="bgColor-20">'.$firstColContent.implode('',$rows).'</tr>';
344
345 $firstColContent = '';
346 }
347 }
348
349 if ($rowCount > $this->maxListPerPage) { // Now checking greater than, because we increased $rowCount before...
350 $out.='
351 <tr class="bgColor-20">
352 <td>&nbsp;</td>
353 <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>
354 </tr>';
355 }
356 } else {
357 $out.='
358 <tr class="bgColor-20">
359 <td'.$cellAttrib.'>'.$firstColContent.'</td>
360 <td colspan="'.($this->returnNumberOfColumns()-1).'"><em>Not indexed</em></td>
361 </tr>';
362 }
363
364 // Checking for phash-rows which are NOT joined with the section table:
365 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('IP.*', 'index_phash IP', 'IP.data_page_id = '.intval($data['uid']).' AND IP.phash NOT IN ('.implode(',',$phashAcc).')');
366 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
367 $out.='
368 <tr class="typo3-red">
369 <td colspan="'.$this->returnNumberOfColumns().'"><strong>Warning:</strong> phash-row "'.$row['phash'].'" didn\'t have a representation in the index_section table!</td>
370 </tr>';
371 $this->allPhashListed[] = $row['phash'];
372 }
373
374 return $out;
375 }
376
377 /**
378 * Render a single row of information about a indexing entry.
379 *
380 * @param array Row from query (combined phash table with sections etc).
381 * @param boolean Set if grouped to previous result; the icon of the element is not shown again.
382 * @param array Array of index_grlist records.
383 * @return array Array of table rows.
384 * @see indexed_info()
385 */
386 function printPhashRow($row,$grouping=0,$extraGrListRows) {
387 $lines = array();
388
389 // 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!
390 $titleCellAttribs = $row['count_val']!=1?' bgcolor="red"':($row['item_type']==='0' ? ' class="bgColor4"' : '');
391
392 if ($row['item_type']) {
393 $arr = unserialize($row['cHashParams']);
394 $page = $arr['key'] ? ' ['.$arr['key'].']' : '';
395 } else $page = '';
396 $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']);
397 $cmdLinks = $this->printRemoveIndexed($row['phash'],'Clear phash-row').$this->printReindex($row,'Re-index element');
398
399 switch($this->pObj->MOD_SETTINGS['type']) {
400 case 1: // Technical details:
401 // Display icon:
402 if (!$grouping) {
403 $lines[] = '<td>'.$this->makeItemTypeIcon($row['item_type'], $row['data_filename'] ? $row['data_filename'] : $row['item_title']).'</td>';
404 } else {
405 $lines[] = '<td>&nbsp;</td>';
406 }
407
408 // Title displayed:
409 $lines[] = '<td'.$titleCellAttribs.'>'.$elTitle.'</td>';
410
411 // Remove-indexing-link:
412 $lines[] = '<td>'.$cmdLinks.'</td>';
413
414 // Various data:
415 $lines[] = '<td>'.$row['phash'].'</td>';
416 $lines[] = '<td>'.$row['contentHash'].'</td>';
417
418 if ($row['item_type']==='0') {
419 $lines[] = '<td>'.($row['data_page_id'] ? $row['data_page_id'] : '&nbsp;').'</td>';
420 $lines[] = '<td>'.($row['data_page_type'] ? $row['data_page_type'] : '&nbsp;').'</td>';
421 $lines[] = '<td>'.($row['sys_language_uid'] ? $row['sys_language_uid'] : '&nbsp;').'</td>';
422 $lines[] = '<td>'.($row['data_page_mp'] ? $row['data_page_mp'] : '&nbsp;').'</td>';
423 } else {
424 $lines[] = '<td colspan="4">'.htmlspecialchars($row['data_filename']).'</td>';
425 }
426 $lines[] = '<td>'.$row['gr_list'].$this->printExtraGrListRows($extraGrListRows).'</td>';
427 $lines[] = '<td>'.$this->printRootlineInfo($row).'</td>';
428 $lines[] = '<td>'.($row['page_id'] ? $row['page_id'] : '&nbsp;').'</td>';
429 $lines[] = '<td>'.($row['phash_t3']!=$row['phash'] ? $row['phash_t3'] : '&nbsp;').'</td>';
430 $lines[] = '<td>'.($row['freeIndexUid'] ? $row['freeIndexUid'].($row['freeIndexSetId']?'/'.$row['freeIndexSetId']:'') : '&nbsp;').'</td>';
431 $lines[] = '<td>'.($row['recordUid'] ? $row['recordUid'] : '&nbsp;').'</td>';
432
433
434
435 // cHash parameters:
436 $arr = unserialize($row['cHashParams']);
437 if (!is_array($arr)) {
438 $arr = array(
439 'cHash' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_general.xml:LGL.error', true)
440 );
441 }
442 $theCHash = $arr['cHash'];
443 unset($arr['cHash']);
444
445 if ($row['item_type']) { // pdf...
446 $lines[] = '<td>'.($arr['key'] ? 'Page '.$arr['key'] : '').'&nbsp;</td>';
447 } elseif ($row['item_type']==0) {
448 $lines[] = '<td>'.htmlspecialchars(t3lib_div::implodeArrayForUrl('',$arr)).'&nbsp;</td>';
449 } else {
450 $lines[] = '<td class="bgColor">&nbsp;</td>';
451 }
452
453 $lines[] = '<td>'.$theCHash.'</td>';
454 break;
455 case 2: // Words and content:
456 // Display icon:
457 if (!$grouping) {
458 $lines[] = '<td>'.$this->makeItemTypeIcon($row['item_type'], $row['data_filename'] ? $row['data_filename'] : $row['item_title']).'</td>';
459 } else {
460 $lines[] = '<td>&nbsp;</td>';
461 }
462
463 // Title displayed:
464 $lines[] = '<td'.$titleCellAttribs.'>'.$elTitle.'</td>';
465
466 // Remove-indexing-link:
467 $lines[] = '<td>'.$cmdLinks.'</td>';
468
469 // Query:
470 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
471 '*',
472 'index_fulltext',
473 'phash = '.intval($row['phash'])
474 );
475 $lines[] = '<td style="white-space: normal;">'.
476 htmlspecialchars(t3lib_div::fixed_lgd_cs($this->utf8_to_currentCharset($ftrows[0]['fulltextdata']),3000)).
477 '<hr/><em>Size: '.strlen($ftrows[0]['fulltextdata']).'</em>'.
478 '</td>';
479
480 // Query:
481 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
482 'index_words.baseword, index_rel.*',
483 'index_rel, index_words',
484 'index_rel.phash = '.intval($row['phash']).
485 ' AND index_words.wid = index_rel.wid',
486 '',
487 '',
488 '',
489 'baseword'
490 );
491
492 $wordList = '';
493 if (is_array($ftrows)) {
494 $indexed_words = array_keys($ftrows);
495 sort($indexed_words);
496 $wordList = htmlspecialchars($this->utf8_to_currentCharset(implode(' ',$indexed_words)));
497 $wordList.='<hr/><em>Count: '.count($indexed_words).'</em>';
498 }
499
500 $lines[] = '<td style="white-space: normal;">'.$wordList.'</td>';
501 break;
502 default: // Overview
503 // Display icon:
504 if (!$grouping) {
505 $lines[] = '<td>'.$this->makeItemTypeIcon($row['item_type'], $row['data_filename'] ? $row['data_filename'] : $row['item_title']).'</td>';
506 } else {
507 $lines[] = '<td>&nbsp;</td>';
508 }
509
510 // Title displayed:
511 $lines[] = '<td'.$titleCellAttribs.'>'.$elTitle.'</td>';
512
513 // Remove-indexing-link:
514 $lines[] = '<td>'.$cmdLinks.'</td>';
515
516 $lines[] = '<td style="white-space: normal;">'.htmlspecialchars($this->utf8_to_currentCharset($row['item_description'])).'...</td>';
517 $lines[] = '<td>'.t3lib_div::formatSize($row['item_size']).'</td>';
518 $lines[] = '<td>'.t3lib_BEfunc::dateTimeAge($row['tstamp']).'</td>';
519 break;
520 }
521
522 return $lines;
523 }
524
525 /**
526 * Creates the header row for the table
527 *
528 * @return string HTML string (table row)
529 */
530 function printPhashRowHeader() {
531 $lines = array();
532
533 switch($this->pObj->MOD_SETTINGS['type']) {
534 case 1:
535 $lines[] = '<td>&nbsp;</td>';
536 $lines[] = '<td>&nbsp;</td>';
537 $lines[] = '<td>Title</td>';
538 $lines[] = '<td bgcolor="red">'.$this->printRemoveIndexed('ALL','Clear ALL phash-rows below!').'</td>';
539
540 $lines[] = '<td>pHash</td>';
541 $lines[] = '<td>contentHash</td>';
542 $lines[] = '<td>&amp;id</td>';
543 $lines[] = '<td>&amp;type</td>';
544 $lines[] = '<td>&amp;L</td>';
545 $lines[] = '<td>&amp;MP</td>';
546 $lines[] = '<td>grlist</td>';
547 $lines[] = '<td>Rootline</td>';
548 $lines[] = '<td>page_id</td>';
549 $lines[] = '<td>phash_t3</td>';
550 $lines[] = '<td>CfgUid</td>';
551 $lines[] = '<td>RecUid</td>';
552 $lines[] = '<td>GET-parameters</td>';
553 $lines[] = '<td>&amp;cHash</td>';
554 break;
555 case 2:
556 $lines[] = '<td>&nbsp;</td>';
557 $lines[] = '<td>&nbsp;</td>';
558 $lines[] = '<td>Title</td>';
559 $lines[] = '<td bgcolor="red">'.$this->printRemoveIndexed('ALL','Clear ALL phash-rows below!').'</td>';
560 $lines[] = '<td>Content<br />
561 <img src="clear.gif" width="300" height="1" alt="" /></td>';
562 $lines[] = '<td>Words<br />
563 <img src="clear.gif" width="300" height="1" alt="" /></td>';
564 break;
565 default:
566 $lines[] = '<td>&nbsp;</td>';
567 $lines[] = '<td>&nbsp;</td>';
568 $lines[] = '<td>Title</td>';
569 $lines[] = '<td bgcolor="red">'.$this->printRemoveIndexed('ALL','Clear ALL phash-rows below!').'</td>';
570 $lines[] = '<td>Description</td>';
571 $lines[] = '<td>Size</td>';
572 $lines[] = '<td>Indexed:</td>';
573 break;
574 }
575
576 $out = '<tr class="tableheader bgColor5">'.implode('',$lines).'</tr>';
577 return $out;
578 }
579
580 /**
581 * Returns the number of columns depending on display type of list
582 *
583 * @return integer Number of columns in list:
584 */
585 function returnNumberOfColumns() {
586 switch($this->pObj->MOD_SETTINGS['type']) {
587 case 1:
588 return 18;
589 break;
590 case 2:
591 return 6;
592 break;
593 default:
594 return 7;
595 break;
596 }
597 }
598
599
600
601
602
603
604
605
606
607
608
609 /*******************************
610 *
611 * Details display, phash row
612 *
613 *******************************/
614
615 /**
616 * Showing details for a particular phash row
617 *
618 * @param integer phash value to display details for.
619 * @return string HTML content
620 */
621 function showDetailsForPhash($phash) {
622
623 $content = '';
624
625 // Selects the result row:
626 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
627 '*',
628 'index_phash',
629 'phash = '.intval($phash)
630 );
631 $phashRecord = $ftrows[0];
632
633 // If found, display:
634 if (is_array($phashRecord)) {
635 $content.= '<h4>phash row content:</h4>'.
636 $this->utf8_to_currentCharset(t3lib_div::view_array($phashRecord));
637
638 // Getting debug information if any:
639 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
640 '*',
641 'index_debug',
642 'phash = '.intval($phash)
643 );
644 if (is_array($ftrows)) {
645 $debugInfo = unserialize($ftrows[0]['debuginfo']);
646 $lexer = $debugInfo['lexer'];
647 unset($debugInfo['lexer']);
648
649 $content.= '<h3>Debug information:</h3>'.
650 $this->utf8_to_currentCharset(t3lib_div::view_array($debugInfo));
651
652 $content.= '<h4>Debug information / lexer splitting:</h4>'.
653 '<hr/><strong>'.
654 $this->utf8_to_currentCharset($lexer).
655 '</strong><hr/>';
656 }
657
658
659
660 $content.='<h3>Word statistics</h3>';
661
662 // Finding all words for this phash:
663 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
664 'index_words.*, index_rel.*',
665 'index_rel, index_words',
666 'index_rel.phash = '.intval($phash).
667 ' AND index_words.wid = index_rel.wid',
668 '',
669 'index_words.baseword',
670 ''
671 );
672 $pageRec = t3lib_BEfunc::getRecord('pages', $phashRecord['data_page_id']);
673 $showStopWordCheckBox = $GLOBALS['BE_USER']->isAdmin();
674 $content.= $this->listWords($ftrows, 'All words found on page ('.count($ftrows).'):', $showStopWordCheckBox, $pageRec);
675
676 // Group metaphone hash:
677 $metaphone = array();
678 foreach($ftrows as $row) {
679 $metaphone[$row['metaphone']][] = $row['baseword'];
680 }
681 $content.= $this->listMetaphoneStat($metaphone, 'Metaphone stats:');
682
683 // Finding top-20 on frequency for this phash:
684 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
685 'index_words.baseword, index_words.metaphone, index_rel.*',
686 'index_rel, index_words',
687 'index_rel.phash = '.intval($phash).
688 ' AND index_words.wid = index_rel.wid
689 AND index_words.is_stopword=0',
690 '',
691 'index_rel.freq DESC',
692 '20'
693 );
694 $content.= $this->listWords($ftrows, 'Top-20 words by frequency:', 2);
695
696 // Finding top-20 on count for this phash:
697 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
698 'index_words.baseword, index_words.metaphone, index_rel.*',
699 'index_rel, index_words',
700 'index_rel.phash = '.intval($phash).
701 ' AND index_words.wid = index_rel.wid
702 AND index_words.is_stopword=0',
703 '',
704 'index_rel.count DESC',
705 '20'
706 );
707 $content.= $this->listWords($ftrows, 'Top-20 words by count:', 2);
708
709
710 $content.='<h3>Section records for this phash</h3>';
711
712 // Finding sections for this record:
713 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
714 '*',
715 'index_section',
716 'index_section.phash = '.intval($phash),
717 '',
718 '',
719 ''
720 );
721 $content.= t3lib_div::view_array($ftrows);
722
723 // Add go-back link:
724 $content = $this->linkList().$content.$this->linkList();
725
726 } else $content.= 'Error: No phash row found';
727
728 return $content;
729 }
730
731 /**
732 * Create table with list of words from $ftrows
733 *
734 * @param array Array of records selected from index_rel/index_words
735 * @param string Header string to show before table.
736 * @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).
737 * @param array The page record from which to load the keywords, if any.
738 * @return string HTML table
739 */
740 function listWords($ftrows,$header, $stopWordBoxes=FALSE, $page='') {
741
742 // Prepare keywords:
743 $keywords = is_array($page) ? array_flip(t3lib_div::trimExplode(',',$page['keywords'], 1)) : '';
744
745 // Render list:
746 $trows = '';
747 $trows.= '
748 <tr class="tableheader bgColor5">
749 '.($stopWordBoxes ? '<td>'.htmlspecialchars('Stopword:').'</td>' : '').'
750 <td>'.htmlspecialchars('Word:').'</td>
751 <td>'.htmlspecialchars('Count:').'</td>
752 <td>'.htmlspecialchars('First:').'</td>
753 <td>'.htmlspecialchars('Frequency:').'</td>
754 <td>'.htmlspecialchars('Flags:').'</td>
755 '.(is_array($keywords) ? '<td>'.htmlspecialchars('Page keyword:').'</td>' : '').'
756 </tr>
757 ';
758 foreach($ftrows as $row) {
759 $hiddenField = $stopWordBoxes!=2 ? '<input type="hidden" name="stopWord['.$row['wid'].']" value="0" />' : '';
760 $trows.= '
761 <tr class="'.($row['is_stopword'] ? 'bgColor' : 'bgColor4').'">
762 '.($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>' : '').'
763 <td>'.$this->linkWordDetails(htmlspecialchars($this->utf8_to_currentCharset($row['baseword'])), $row['wid']).'</td>
764 <td>'.htmlspecialchars($row['count']).'</td>
765 <td>'.htmlspecialchars($row['first']).'</td>
766 <td>'.htmlspecialchars($row['freq']).'</td>
767 <td>'.htmlspecialchars($this->flagsMsg($row['flags'])).'</td>
768 '.(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>' : '').'
769 </tr>
770 ';
771 }
772
773 return '<h4>'.htmlspecialchars($header).'</h4>'.
774 '
775 <table border="0" cellspacing="1" cellpadding="2" class="c-list">
776 '.$trows.'
777 </table>'.
778 ($stopWordBoxes ? '<input type="submit" value="Change stop-word settings" name="_stopwords" onclick="document.webinfoForm.action=\''.htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')).'\';" />' : '').
779 (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'].'" />'.
780 '<br />Current keywords are: <em>' . htmlspecialchars(implode(', ', array_keys($keywords))) . '</em>' : '');
781 }
782
783 /**
784 * Displays table of metaphone groups larger than 1
785 *
786 * @param array Result from word selection (index_rel/index_words)
787 * @param string Header string
788 * @return string HTML table
789 */
790 function listMetaphoneStat($ftrows,$header) {
791
792 $trows = '';
793 $trows.= '
794 <tr class="tableheader bgColor5">
795 <td>'.htmlspecialchars('Metaphone:').'</td>
796 <td>'.htmlspecialchars('Hash:').'</td>
797 <td>'.htmlspecialchars('Count:').'</td>
798 <td>'.htmlspecialchars('Words:').'</td>
799 </tr>
800 ';
801 foreach($ftrows as $metaphone => $words) {
802 if (count($words)>1) {
803 $trows.= '
804 <tr class="bgColor4">
805 <td>'.$this->linkMetaPhoneDetails($this->indexerObj->metaphone($words[0],1),$metaphone).'</td>
806 <td>'.htmlspecialchars($metaphone).'</td>
807 <td>'.htmlspecialchars(count($words)).'</td>
808 <td style="white-space: normal;">'.htmlspecialchars($this->utf8_to_currentCharset(implode(', ',$words))).'</td>
809 </tr>
810 ';
811 }
812 }
813
814 return '<h4>'.htmlspecialchars($header).'</h4>'.
815 '<table border="0" cellspacing="1" cellpadding="2" class="c-list">
816 '.$trows.'
817 </table>';
818 }
819
820 /**
821 * Wraps input string in a link that will display details for the word. Eg. which other pages has the word, metaphone associations etc.
822 *
823 * @param string String to wrap, possibly a title or so.
824 * @param integer wid value to show details for
825 * @return string Wrapped string
826 */
827 function linkWordDetails($string,$wid) {
828 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('wid'=>$wid,'phash'=>''))).'">'.$string.'</a>';
829 }
830
831
832 /**
833 * Wraps input string in a link to see more details for metaphone value
834 *
835 * @param string String to wrap
836 * @param integer Metaphone value
837 * @return string Wrapped string
838 */
839 function linkMetaPhoneDetails($string,$metaphone) {
840 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('metaphone'=>$metaphone,'wid'=>'','phash'=>''))).'">'.$string.'</a>';
841 }
842
843 /**
844 * Creates message for flag value
845 *
846 * @param integer Flags integer
847 * @return string Message string
848 */
849 function flagsMsg($flags) {
850 if ($flags > 0) {
851 return
852 ($flags & 128 ? '<title>' : ''). // pow(2,7)
853 ($flags & 64 ? '<meta/keywords>' : ''). // pow(2,6)
854 ($flags & 32 ? '<meta/description>' : ''). // pow(2,5)
855 ' ('.$flags.')';
856 }
857 }
858
859
860
861
862
863
864
865
866
867
868 /*******************************
869 *
870 * Details display, words / metaphone
871 *
872 *******************************/
873
874 /**
875 * Show details for words
876 *
877 * @param integer Word ID (wid)
878 * @return string HTML content
879 */
880 function showDetailsForWord($wid) {
881
882 // Select references to this word
883 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
884 'index_phash.*, index_section.*, index_rel.*',
885 'index_rel, index_section, index_phash',
886 'index_rel.wid = '.intval($wid).
887 ' AND index_rel.phash = index_section.phash'.
888 ' AND index_section.phash = index_phash.phash',
889 '',
890 'index_rel.freq DESC',
891 ''
892 );
893
894 // Headers:
895 $content.='
896 <tr class="tableheader bgColor5">
897 <td>phash</td>
898 <td>page_id</td>
899 <td>data_filename</td>
900 <td>count</td>
901 <td>first</td>
902 <td>freq</td>
903 <td>flags</td>
904 </tr>';
905
906 if (is_array($ftrows)) {
907 foreach($ftrows as $wDat) {
908 $content.='
909 <tr class="bgColor4">
910 <td>'.$this->linkDetails(htmlspecialchars($wDat['phash']),$wDat['phash']).'</td>
911 <td>'.htmlspecialchars($wDat['page_id']).'</td>
912 <td>'.htmlspecialchars($wDat['data_filename']).'</td>
913 <td>'.htmlspecialchars($wDat['count']).'</td>
914 <td>'.htmlspecialchars($wDat['first']).'</td>
915 <td>'.htmlspecialchars($wDat['freq']).'</td>
916 <td>'.htmlspecialchars($wDat['flags']).'</td>
917 </tr>';
918 }
919 }
920
921 // Compile table:
922 $content = '
923 <table border="0" cellspacing="1" cellpadding="2" class="c-list">'.
924 $content.'
925 </table>';
926
927 // Add go-back link:
928 $content = $content.$this->linkList();
929
930 return $content;
931 }
932
933 /**
934 * Show details for metaphone value
935 *
936 * @param integer Metaphone integer hash
937 * @return string HTML content
938 */
939 function showDetailsForMetaphone($metaphone) {
940
941 // Finding top-20 on frequency for this phash:
942 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
943 'index_words.*',
944 'index_words',
945 'index_words.metaphone = '.intval($metaphone),
946 '',
947 'index_words.baseword',
948 ''
949 );
950
951 if (count($ftrows)) {
952 $content.='<h4>Metaphone: '.$this->indexerObj->metaphone($ftrows[0]['baseword'],1).'</h4>';
953
954 $content.='
955 <tr class="tableheader bgColor5">
956 <td>Word</td>
957 <td>Is stopword?</td>
958 </tr>';
959
960 if (is_array($ftrows)) {
961 foreach($ftrows as $wDat) {
962 $content.='
963 <tr class="bgColor4">
964 <td>'.$this->linkWordDetails(htmlspecialchars($wDat['baseword']),$wDat['wid']).'</td>
965 <td>'.htmlspecialchars($wDat['is_stopword'] ? 'YES' : 'No').'</td>
966 </tr>';
967 }
968 }
969
970 $content = '
971 <table border="0" cellspacing="1" cellpadding="2" class="c-list">'.
972 $content.'
973 </table>';
974
975 if ($this->indexerObj->metaphone($ftrows[0]['baseword'])!=$metaphone) {
976 $content.='ERROR: Metaphone string and hash did not match for some reason!?';
977 }
978
979 // Add go-back link:
980 $content = $content.$this->linkList();
981 }
982
983 return $content;
984 }
985
986
987
988
989
990
991
992
993
994
995
996
997 /*******************************
998 *
999 * Helper functions
1000 *
1001 *******************************/
1002
1003 /**
1004 * Creates icon which clears indexes for a certain list of phash values.
1005 *
1006 * @param string List of phash integers
1007 * @param string Alt-text for the garbage bin icon.
1008 * @return string HTML img-tag with link around.
1009 */
1010 function printRemoveIndexed($phash,$alt) {
1011 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('deletePhash'=>$phash))).'" title="' . htmlspecialchars($alt) . '">' .
1012 t3lib_iconWorks::getSpriteIcon('actions-edit-delete') .
1013 '</a>';
1014 }
1015
1016 /**
1017 * Button for re-indexing of documents
1018 *
1019 * @param array phash table result row.
1020 * @param string Title attribute text for icon
1021 * @return string HTML content; Icon wrapped in link.
1022 */
1023 function printReindex($resultRow,$alt) {
1024 if ($resultRow['item_type'] && $resultRow['item_type']!=='0') {
1025 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('reindex'=>$resultRow['phash'],'reindex_id'=>$resultRow['page_id']))).'">'.
1026 '<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="" />'.
1027 '</a>';
1028 }
1029 }
1030
1031 /**
1032 * Wraps input string in a link that will display details for the phash value set.
1033 *
1034 * @param string String to wrap, possibly a title or so.
1035 * @param integer phash value to show details for
1036 * @return string Wrapped string
1037 */
1038 function linkDetails($string,$phash) {
1039 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('phash'=>$phash))).'">'.$string.'</a>';
1040 }
1041
1042 /**
1043 * Creates link back to listing
1044 *
1045 * @return string Link back to list
1046 */
1047 function linkList() {
1048 return '<br /><a href="index.php?id=' . $this->pObj->id . '">Back to list.</a><br />';
1049 }
1050
1051 /**
1052 * Wraps input string in a link that will display details for the phash value set.
1053 *
1054 * @param string String to wrap, possibly a title or so.
1055 * @param integer phash value to show details for
1056 * @return string Wrapped string
1057 */
1058 function showPageDetails($string,$id) {
1059 return '<a href="'.htmlspecialchars('index.php?id='.$id.'&SET[depth]=0&SET[type]=1').'">'.$string.'</a>';
1060 }
1061
1062 /**
1063 * Prints the gr_lists attached to a indexed entry.
1064 *
1065 * @param array Array of index_grlist records
1066 * @return string HTML code.
1067 */
1068 function printExtraGrListRows($extraGrListRows) {
1069 if (count($extraGrListRows)) {
1070 $lines=array();
1071 foreach ($extraGrListRows as $r) {
1072 $lines[] = $r['gr_list'];
1073 }
1074 return '<br />' . $GLOBALS['TBE_TEMPLATE']->dfw(implode('<br />', $lines));
1075 }
1076 }
1077
1078 /**
1079 * Print path for indexing
1080 *
1081 * @param array Result row with content from index_section
1082 * @return string Rootline information
1083 */
1084 function printRootlineInfo($row) {
1085 $uidCollection = array();
1086
1087 if ($row['rl0']) {
1088 $uidCollection[0] = $row['rl0'];
1089 if ($row['rl1']) {
1090 $uidCollection[1] = $row['rl1'];
1091 if ($row['rl2']) {
1092 $uidCollection[2] = $row['rl2'];
1093
1094 // Additional levels:
1095 if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['addRootLineFields'])) {
1096 foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['addRootLineFields'] as $fieldName => $rootLineLevel) {
1097 if ($row[$fieldName]) {
1098 $uidCollection[$rootLineLevel] = $row[$fieldName];
1099 }
1100 }
1101 }
1102 }
1103 }
1104 }
1105
1106 // Return root line.
1107 ksort($uidCollection);
1108 return implode('/',$uidCollection);
1109 }
1110
1111 /**
1112 * Return icon for file extension
1113 *
1114 * @param string File extension / item type
1115 * @param string Title attribute value in icon.
1116 * @return string <img> tag for icon
1117 */
1118 function makeItemTypeIcon($it,$alt='') {
1119 if (!isset($this->iconFileNameCache[$it])) {
1120 if ($it==='0') {
1121 $icon = 'EXT:indexed_search/pi/res/pages.gif';
1122 } elseif ($this->external_parsers[$it]) {
1123 $icon = $this->external_parsers[$it]->getIcon($it);
1124 }
1125
1126 $fullPath = t3lib_div::getFileAbsFileName($icon);
1127
1128 if ($fullPath) {
1129 $info = @getimagesize($fullPath);
1130 $iconPath = $GLOBALS['BACK_PATH'].'../'.substr($fullPath,strlen(PATH_site));
1131 $this->iconFileNameCache[$it] = is_array($info) ? '<img src="'.$iconPath.'" '.$info[3].' title="###TITLE_ATTRIBUTE###" alt="" />' : '';
1132 }
1133 }
1134 return str_replace('###TITLE_ATTRIBUTE###',htmlspecialchars($it.': '.$alt),$this->iconFileNameCache[$it]);
1135 }
1136
1137 /**
1138 * Converts the input string from utf-8 to the backend charset.
1139 *
1140 * @param string String to convert (utf-8)
1141 * @return string Converted string (backend charset if different from utf-8)
1142 */
1143 function utf8_to_currentCharset($string) {
1144 global $LANG;
1145 if ($LANG->charSet != 'utf-8') {
1146 $string = $LANG->csConvObj->utf8_decode($string, $LANG->charSet, TRUE);
1147 }
1148 return $string;
1149 }
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162 /********************************
1163 *
1164 * Reindexing
1165 *
1166 *******************************/
1167
1168 /**
1169 * Re-indexing files/records attached to a page.
1170 *
1171 * @param integer Phash value
1172 * @param integer The page uid for the section record (file/url could appear more than one place you know...)
1173 * @return string HTML content
1174 */
1175 function reindexPhash($phash, $pageId) {
1176
1177 // Query:
1178 list($resultRow) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1179 'ISEC.*, IP.*',
1180 'index_phash IP, index_section ISEC',
1181 'IP.phash = ISEC.phash
1182 AND IP.phash = '.intval($phash).'
1183 AND ISEC.page_id = '.intval($pageId)
1184 );
1185
1186 $content = '';
1187 if (is_array($resultRow)) {
1188 if ($resultRow['item_type'] && $resultRow['item_type']!=='0') {
1189
1190 // (Re)-Indexing file on page.
1191 $indexerObj = t3lib_div::makeInstance('tx_indexedsearch_indexer');
1192 $indexerObj->backend_initIndexer($pageId, 0, 0, '', $this->getUidRootLineForClosestTemplate($pageId));
1193
1194 // URL or local file:
1195 if ($resultRow['externalUrl']) {
1196 $indexerObj->indexExternalUrl($resultRow['data_filename']);
1197 } else {
1198 $indexerObj->indexRegularDocument($resultRow['data_filename'], TRUE);
1199 }
1200
1201 if ($indexerObj->file_phash_arr['phash'] != $resultRow['phash']) {
1202 $content.= 'ERROR: phash ('.$indexerObj->file_phash_arr['phash'].') did NOT match '.$resultRow['phash'].' for strange reasons!';
1203 }
1204
1205 $content.='<h4>Log for re-indexing of "'.htmlspecialchars($resultRow['data_filename']).'":</h4>';
1206 $content.=t3lib_div::view_array($indexerObj->internal_log);
1207
1208 $content.='<h4>Hash-array, page:</h4>';
1209 $content.=t3lib_div::view_array($indexerObj->hash);
1210
1211 $content.='<h4>Hash-array, file:</h4>';
1212 $content.=t3lib_div::view_array($indexerObj->file_phash_arr);
1213 }
1214 }
1215
1216 // Link back to list.
1217 $content.= $this->linkList();
1218
1219 return $content;
1220 }
1221
1222 /**
1223 * Get rootline for closest TypoScript template root.
1224 * Algorithm same as used in Web > Template, Object browser
1225 *
1226 * @param integer The page id to traverse rootline back from
1227 * @return array Array where the root lines uid values are found.
1228 */
1229 function getUidRootLineForClosestTemplate($id) {
1230 $tmpl = t3lib_div::makeInstance('t3lib_tsparser_ext'); // Defined global here!
1231 $tmpl->tt_track = 0; // Do not log time-performance information
1232 $tmpl->init();
1233
1234 // Gets the rootLine
1235 $sys_page = t3lib_div::makeInstance('t3lib_pageSelect');
1236 $rootLine = $sys_page->getRootLine($id);
1237 $tmpl->runThroughTemplates($rootLine,0); // This generates the constants/config + hierarchy info for the template.
1238
1239 // Root line uids
1240 $rootline_uids = array();
1241 foreach($tmpl->rootLine as $rlkey => $rldat) {
1242 $rootline_uids[$rlkey] = $rldat['uid'];
1243 }
1244
1245 return $rootline_uids;
1246 }
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259 /********************************
1260 *
1261 * SQL functions
1262 *
1263 *******************************/
1264
1265 /**
1266 * Removes ALL data regarding a certain list of indexed phash-row
1267 *
1268 * @param string List of phash integers
1269 * @param boolean If set, page cache is cleared as well.
1270 * @return void
1271 */
1272 function removeIndexedPhashRow($phashList,$clearPageCache=1) {
1273 // FIXME: This is only a workaround
1274 if ($phashList=='ALL') {
1275 $this->drawTableOfIndexedPages();
1276 $phashRows = $this->allPhashListed;
1277 $this->allPhashListed = array(); // Reset it because it will be filled again later...
1278 } else {
1279 $phashRows = t3lib_div::trimExplode(',',$phashList,1);
1280 }
1281
1282 foreach($phashRows as $phash) {
1283 $phash = intval($phash);
1284 if ($phash>0) {
1285
1286 if ($clearPageCache) {
1287 // Clearing page cache:
1288 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('page_id', 'index_section', 'phash='.intval($phash));
1289 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
1290 $idList = array();
1291 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1292 $idList[] = (int)$row['page_id'];
1293 }
1294
1295 if (TYPO3_UseCachingFramework) {
1296 $pageCache = $GLOBALS['typo3CacheManager']->getCache('cache_pages');
1297 foreach ($idList as $pageId) {
1298 $pageCache->flushByTag('pageId_' . $pageId);
1299 }
1300 } else {
1301 $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages', 'page_id IN (' . implode(',', $idList) . ')');
1302 }
1303 }
1304 }
1305
1306 // Removing old registrations for all tables.
1307 $tableArr = explode(',','index_phash,index_rel,index_section,index_grlist,index_fulltext,index_debug');
1308 foreach($tableArr as $table) {
1309 $GLOBALS['TYPO3_DB']->exec_DELETEquery($table, 'phash='.intval($phash));
1310 }
1311
1312 // Did not remove any index_section records for external files where phash_t3 points to this hash!
1313 }
1314 }
1315 }
1316
1317 /**
1318 * Returns an array with gr_list records for a phash
1319 *
1320 * @param integer phash integer to look up on
1321 * @param string gr_list string to filter OUT of the result (first occurence)
1322 * @return array Array of records from index_grlist table
1323 */
1324 function getGrListEntriesForPhash($phash,$gr_list) {
1325 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'index_grlist', 'phash='.intval($phash));
1326 $lines = array();
1327 $isRemoved = 0;
1328 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1329 if (!$isRemoved && !strcmp($row['gr_list'],$gr_list)) {
1330 $isRemoved = 1;
1331 } else {
1332 $lines[] = $row;
1333 }
1334 }
1335 return $lines;
1336 }
1337
1338 /**
1339 * Setting / Unsetting stopwords
1340 *
1341 * @param array Array of stop-words WIDs with 0/1 to set / unset
1342 * @return void
1343 */
1344 function processStopWords($stopWords) {
1345
1346 if ($GLOBALS['BE_USER']->isAdmin()) {
1347 // Traverse words
1348 foreach($stopWords as $wid => $state) {
1349 $fieldArray = array(
1350 'is_stopword' => $state
1351 );
1352 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('index_words', 'wid='.$wid, $fieldArray);
1353 }
1354 }
1355 }
1356
1357 /**
1358 * Setting / Unsetting keywords in page header
1359 *
1360 * @param array Page keywords as keys in array with value 0 or 1 for set or unset.
1361 * @param integer The page uid of the header where the keywords are to be set.
1362 * @return void
1363 */
1364 function processPageKeywords($pageKeywords, $pageUid) {
1365
1366 // Get pages current keywords
1367 $pageRec = t3lib_BEfunc::getRecord('pages', $pageUid);
1368 $keywords = array_flip(t3lib_div::trimExplode(',', $pageRec['keywords'], 1));
1369
1370 // Merge keywords:
1371 foreach($pageKeywords as $key => $v) {
1372 if ($v) {
1373 $keywords[$key]=1;
1374 } else {
1375 unset($keywords[$key]);
1376 }
1377 }
1378
1379 // Compile new list:
1380 $data = array();
1381 $data['pages'][$pageUid]['keywords'] = implode(', ',array_keys($keywords));
1382
1383 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
1384 $tce->stripslashes_values = 0;
1385 $tce->start($data,array());
1386 $tce->process_datamap();
1387 }
1388 }
1389
1390
1391
1392 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/indexed_search/modfunc1/class.tx_indexedsearch_modfunc1.php']) {
1393 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/indexed_search/modfunc1/class.tx_indexedsearch_modfunc1.php']);
1394 }
1395
1396 ?>