77eb12d9b832475c5cb67728908993029fb40970
[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.*, IP.*, count(*) AS count_val',
299 'index_phash IP, index_section ISEC',
300 'IP.phash = ISEC.phash AND ISEC.page_id = '.intval($data['uid']),
301 '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',
302 'IP.item_type, IP.tstamp',
303 ($this->maxListPerPage+1)
304 );
305
306 // Initialize variables:
307 $rowCount = 0;
308 $lines = array(); // Collecting HTML rows here.
309 $phashAcc = array(); // Collecting phash values (to remove local indexing for)
310 $phashAcc[] = 0;
311
312 // Traverse the result set of phash rows selected:
313 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
314 if ($rowCount == $this->maxListPerPage) {
315 $rowCount++; // Increase to the extra warning row will appear as well.
316 break;
317 }
318
319 // Adds a display row:
320 $lines[$row['phash_grouping']][] = $this->printPhashRow(
321 $row,
322 isset($lines[$row['phash_grouping']]),
323 $this->getGrListEntriesForPhash($row['phash'], $row['gr_list'])
324 );
325 $rowCount++;
326 $phashAcc[] = $row['phash'];
327 $this->allPhashListed[] = $row['phash']; // For removing all shown phash rows.
328 }
329
330 // Compile rows into the table:
331 $out = '';
332 $cellAttrib = ($data['_CSSCLASS'] ? ' class="'.$data['_CSSCLASS'].'"' : '');
333 if (count($lines)) {
334 $firstColContent = '<td rowspan="'.$rowCount.'"'.$cellAttrib.'>'.$firstColContent.'</td>';
335 foreach($lines as $rowSet) {
336 foreach($rowSet as $rows) {
337 $out.='
338 <tr class="bgColor-20">'.$firstColContent.implode('',$rows).'</tr>';
339
340 $firstColContent = '';
341 }
342 }
343
344 if ($rowCount > $this->maxListPerPage) { // Now checking greater than, because we increased $rowCount before...
345 $out.='
346 <tr class="bgColor-20">
347 <td>&nbsp;</td>
348 <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>
349 </tr>';
350 }
351 } else {
352 $out.='
353 <tr class="bgColor-20">
354 <td'.$cellAttrib.'>'.$firstColContent.'</td>
355 <td colspan="'.($this->returnNumberOfColumns()-1).'"><em>Not indexed</em></td>
356 </tr>';
357 }
358
359 // Checking for phash-rows which are NOT joined with the section table:
360 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('IP.*', 'index_phash IP', 'IP.data_page_id = '.intval($data['uid']).' AND IP.phash NOT IN ('.implode(',',$phashAcc).')');
361 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
362 $out.='
363 <tr class="typo3-red">
364 <td colspan="'.$this->returnNumberOfColumns().'"><b>Warning:</b> phash-row "'.$row['phash'].'" didn\'t have a representation in the index_section table!</td>
365 </tr>';
366 $this->allPhashListed[] = $row['phash'];
367 }
368
369 return $out;
370 }
371
372 /**
373 * Render a single row of information about a indexing entry.
374 *
375 * @param array Row from query (combined phash table with sections etc).
376 * @param boolean Set if grouped to previous result; the icon of the element is not shown again.
377 * @param array Array of index_grlist records.
378 * @return array Array of table rows.
379 * @see indexed_info()
380 */
381 function printPhashRow($row,$grouping=0,$extraGrListRows) {
382 $lines = array();
383
384 // 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!
385 $titleCellAttribs = $row['count_val']!=1?' bgcolor="red"':($row['item_type']==='0' ? ' class="bgColor4"' : '');
386
387 if ($row['item_type']) {
388 $arr = unserialize($row['cHashParams']);
389 $page = $arr['key'] ? ' ['.$arr['key'].']' : '';
390 } else $page = '';
391 $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']);
392 $cmdLinks = $this->printRemoveIndexed($row['phash'],'Clear phash-row').$this->printReindex($row,'Re-index element');
393
394 switch($this->pObj->MOD_SETTINGS['type']) {
395 case 1: // Technical details:
396 // Display icon:
397 if (!$grouping) {
398 $lines[] = '<td>'.$this->makeItemTypeIcon($row['item_type'], $row['data_filename'] ? $row['data_filename'] : $row['item_title']).'</td>';
399 } else {
400 $lines[] = '<td>&nbsp;</td>';
401 }
402
403 // Title displayed:
404 $lines[] = '<td'.$titleCellAttribs.'>'.$elTitle.'</td>';
405
406 // Remove-indexing-link:
407 $lines[] = '<td>'.$cmdLinks.'</td>';
408
409 // Various data:
410 $lines[] = '<td>'.$row['phash'].'</td>';
411 $lines[] = '<td>'.$row['contentHash'].'</td>';
412
413 if ($row['item_type']==='0') {
414 $lines[] = '<td>'.($row['data_page_id'] ? $row['data_page_id'] : '&nbsp;').'</td>';
415 $lines[] = '<td>'.($row['data_page_type'] ? $row['data_page_type'] : '&nbsp;').'</td>';
416 $lines[] = '<td>'.($row['sys_language_uid'] ? $row['sys_language_uid'] : '&nbsp;').'</td>';
417 $lines[] = '<td>'.($row['data_page_mp'] ? $row['data_page_mp'] : '&nbsp;').'</td>';
418 } else {
419 $lines[] = '<td colspan="4">'.htmlspecialchars($row['data_filename']).'</td>';
420 }
421 $lines[] = '<td>'.$row['gr_list'].$this->printExtraGrListRows($extraGrListRows).'</td>';
422 $lines[] = '<td>'.$this->printRootlineInfo($row).'</td>';
423 $lines[] = '<td>'.($row['page_id'] ? $row['page_id'] : '&nbsp;').'</td>';
424 $lines[] = '<td>'.($row['phash_t3']!=$row['phash'] ? $row['phash_t3'] : '&nbsp;').'</td>';
425 $lines[] = '<td>'.($row['freeIndexUid'] ? $row['freeIndexUid'].($row['freeIndexSetId']?'/'.$row['freeIndexSetId']:'') : '&nbsp;').'</td>';
426 $lines[] = '<td>'.($row['recordUid'] ? $row['recordUid'] : '&nbsp;').'</td>';
427
428
429
430 // cHash parameters:
431 $arr = unserialize($row['cHashParams']);
432 if (is_array($arr)) {
433 $theCHash = $arr['cHash'];
434 unset($arr['cHash']);
435 }
436
437 if ($row['item_type']) { // pdf...
438 $lines[] = '<td>'.($arr['key'] ? 'Page '.$arr['key'] : '').'&nbsp;</td>';
439 } elseif ($row['item_type']==0) {
440 $lines[] = '<td>'.htmlspecialchars(t3lib_div::implodeArrayForUrl('',$arr)).'&nbsp;</td>';
441 } else {
442 $lines[] = '<td class="bgColor">&nbsp;</td>';
443 }
444
445 $lines[] = '<td>'.$theCHash.'</td>';
446 break;
447 case 2: // Words and content:
448 // Display icon:
449 if (!$grouping) {
450 $lines[] = '<td>'.$this->makeItemTypeIcon($row['item_type'], $row['data_filename'] ? $row['data_filename'] : $row['item_title']).'</td>';
451 } else {
452 $lines[] = '<td>&nbsp;</td>';
453 }
454
455 // Title displayed:
456 $lines[] = '<td'.$titleCellAttribs.'>'.$elTitle.'</td>';
457
458 // Remove-indexing-link:
459 $lines[] = '<td>'.$cmdLinks.'</td>';
460
461 // Query:
462 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
463 '*',
464 'index_fulltext',
465 'phash = '.intval($row['phash'])
466 );
467 $lines[] = '<td style="white-space: normal;">'.
468 htmlspecialchars(t3lib_div::fixed_lgd_cs($this->utf8_to_currentCharset($ftrows[0]['fulltextdata']),3000)).
469 '<hr/><em>Size: '.strlen($ftrows[0]['fulltextdata']).'</em>'.
470 '</td>';
471
472 // Query:
473 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
474 'index_words.baseword, index_rel.*',
475 'index_rel, index_words',
476 'index_rel.phash = '.intval($row['phash']).
477 ' AND index_words.wid = index_rel.wid',
478 '',
479 '',
480 '',
481 'baseword'
482 );
483
484 $wordList = '';
485 if (is_array($ftrows)) {
486 $indexed_words = array_keys($ftrows);
487 sort($indexed_words);
488 $wordList = htmlspecialchars($this->utf8_to_currentCharset(implode(' ',$indexed_words)));
489 $wordList.='<hr/><em>Count: '.count($indexed_words).'</em>';
490 }
491
492 $lines[] = '<td style="white-space: normal;">'.$wordList.'</td>';
493 break;
494 default: // Overview
495 // Display icon:
496 if (!$grouping) {
497 $lines[] = '<td>'.$this->makeItemTypeIcon($row['item_type'], $row['data_filename'] ? $row['data_filename'] : $row['item_title']).'</td>';
498 } else {
499 $lines[] = '<td>&nbsp;</td>';
500 }
501
502 // Title displayed:
503 $lines[] = '<td'.$titleCellAttribs.'>'.$elTitle.'</td>';
504
505 // Remove-indexing-link:
506 $lines[] = '<td>'.$cmdLinks.'</td>';
507
508 $lines[] = '<td style="white-space: normal;">'.htmlspecialchars($this->utf8_to_currentCharset($row['item_description'])).'...</td>';
509 $lines[] = '<td>'.t3lib_div::formatSize($row['item_size']).'</td>';
510 $lines[] = '<td>'.t3lib_BEfunc::dateTimeAge($row['tstamp']).'</td>';
511 break;
512 }
513
514 return $lines;
515 }
516
517 /**
518 * Creates the header row for the table
519 *
520 * @return string HTML string (table row)
521 */
522 function printPhashRowHeader() {
523 $lines = array();
524
525 switch($this->pObj->MOD_SETTINGS['type']) {
526 case 1:
527 $lines[] = '<td>&nbsp;</td>';
528 $lines[] = '<td>&nbsp;</td>';
529 $lines[] = '<td>Title</td>';
530 $lines[] = '<td bgcolor="red">'.$this->printRemoveIndexed('ALL','Clear ALL phash-rows below!').'</td>';
531
532 $lines[] = '<td>pHash</td>';
533 $lines[] = '<td>contentHash</td>';
534 $lines[] = '<td>&amp;id</td>';
535 $lines[] = '<td>&amp;type</td>';
536 $lines[] = '<td>&amp;L</td>';
537 $lines[] = '<td>&amp;MP</td>';
538 $lines[] = '<td>grlist</td>';
539 $lines[] = '<td>Rootline</td>';
540 $lines[] = '<td>page_id</td>';
541 $lines[] = '<td>phash_t3</td>';
542 $lines[] = '<td>CfgUid</td>';
543 $lines[] = '<td>RecUid</td>';
544 $lines[] = '<td>GET-parameters</td>';
545 $lines[] = '<td>&amp;cHash</td>';
546 break;
547 case 2:
548 $lines[] = '<td>&nbsp;</td>';
549 $lines[] = '<td>&nbsp;</td>';
550 $lines[] = '<td>Title</td>';
551 $lines[] = '<td bgcolor="red">'.$this->printRemoveIndexed('ALL','Clear ALL phash-rows below!').'</td>';
552 $lines[] = '<td>Content<br />
553 <img src="clear.gif" width="300" height="1" alt="" /></td>';
554 $lines[] = '<td>Words<br />
555 <img src="clear.gif" width="300" height="1" alt="" /></td>';
556 break;
557 default:
558 $lines[] = '<td>&nbsp;</td>';
559 $lines[] = '<td>&nbsp;</td>';
560 $lines[] = '<td>Title</td>';
561 $lines[] = '<td bgcolor="red">'.$this->printRemoveIndexed('ALL','Clear ALL phash-rows below!').'</td>';
562 $lines[] = '<td>Description</td>';
563 $lines[] = '<td>Size</td>';
564 $lines[] = '<td>Indexed:</td>';
565 break;
566 }
567
568 $out = '<tr class="tableheader bgColor5">'.implode('',$lines).'</tr>';
569 return $out;
570 }
571
572 /**
573 * Returns the number of columns depending on display type of list
574 *
575 * @return integer Number of columns in list:
576 */
577 function returnNumberOfColumns() {
578 switch($this->pObj->MOD_SETTINGS['type']) {
579 case 1:
580 return 18;
581 break;
582 case 2:
583 return 6;
584 break;
585 default:
586 return 7;
587 break;
588 }
589 }
590
591
592
593
594
595
596
597
598
599
600
601 /*******************************
602 *
603 * Details display, phash row
604 *
605 *******************************/
606
607 /**
608 * Showing details for a particular phash row
609 *
610 * @param integer phash value to display details for.
611 * @return string HTML content
612 */
613 function showDetailsForPhash($phash) {
614
615 $content = '';
616
617 // Selects the result row:
618 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
619 '*',
620 'index_phash',
621 'phash = '.intval($phash)
622 );
623 $phashRecord = $ftrows[0];
624
625 // If found, display:
626 if (is_array($phashRecord)) {
627 $content.= '<h4>phash row content:</h4>'.
628 $this->utf8_to_currentCharset(t3lib_div::view_array($phashRecord));
629
630 // Getting debug information if any:
631 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
632 '*',
633 'index_debug',
634 'phash = '.intval($phash)
635 );
636 if (is_array($ftrows)) {
637 $debugInfo = unserialize($ftrows[0]['debuginfo']);
638 $lexer = $debugInfo['lexer'];
639 unset($debugInfo['lexer']);
640
641 $content.= '<h3>Debug information:</h3>'.
642 $this->utf8_to_currentCharset(t3lib_div::view_array($debugInfo));
643
644 $content.= '<h4>Debug information / lexer splitting:</h4>'.
645 '<hr/><b>'.
646 $this->utf8_to_currentCharset($lexer).
647 '</b><hr/>';
648 }
649
650
651
652 $content.='<h3>Word statistics</h3>';
653
654 // Finding all words for this phash:
655 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
656 'index_words.*, index_rel.*',
657 'index_rel, index_words',
658 'index_rel.phash = '.intval($phash).
659 ' AND index_words.wid = index_rel.wid',
660 '',
661 'index_words.baseword',
662 ''
663 );
664 $pageRec = t3lib_BEfunc::getRecord('pages', $phashRecord['data_page_id']);
665 $showStopWordCheckBox = $GLOBALS['BE_USER']->isAdmin();
666 $content.= $this->listWords($ftrows, 'All words found on page ('.count($ftrows).'):', $showStopWordCheckBox, $pageRec);
667
668 // Group metaphone hash:
669 $metaphone = array();
670 foreach($ftrows as $row) {
671 $metaphone[$row['metaphone']][] = $row['baseword'];
672 }
673 $content.= $this->listMetaphoneStat($metaphone, 'Metaphone stats:');
674
675 // Finding top-20 on frequency for this phash:
676 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
677 'index_words.baseword, index_words.metaphone, index_rel.*',
678 'index_rel, index_words',
679 'index_rel.phash = '.intval($phash).
680 ' AND index_words.wid = index_rel.wid
681 AND index_words.is_stopword=0',
682 '',
683 'index_rel.freq DESC',
684 '20'
685 );
686 $content.= $this->listWords($ftrows, 'Top-20 words by frequency:', 2);
687
688 // Finding top-20 on count for this phash:
689 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
690 'index_words.baseword, index_words.metaphone, index_rel.*',
691 'index_rel, index_words',
692 'index_rel.phash = '.intval($phash).
693 ' AND index_words.wid = index_rel.wid
694 AND index_words.is_stopword=0',
695 '',
696 'index_rel.count DESC',
697 '20'
698 );
699 $content.= $this->listWords($ftrows, 'Top-20 words by count:', 2);
700
701
702 $content.='<h3>Section records for this phash</h3>';
703
704 // Finding sections for this record:
705 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
706 '*',
707 'index_section',
708 'index_section.phash = '.intval($phash),
709 '',
710 '',
711 ''
712 );
713 $content.= t3lib_div::view_array($ftrows);
714
715 // Add go-back link:
716 $content = $this->linkList().$content.$this->linkList();
717
718 } else $content.= 'Error: No phash row found';
719
720 return $content;
721 }
722
723 /**
724 * Create table with list of words from $ftrows
725 *
726 * @param array Array of records selected from index_rel/index_words
727 * @param string Header string to show before table.
728 * @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).
729 * @param array The page record from which to load the keywords, if any.
730 * @return string HTML table
731 */
732 function listWords($ftrows,$header, $stopWordBoxes=FALSE, $page='') {
733
734 // Prepare keywords:
735 $keywords = is_array($page) ? array_flip(t3lib_div::trimExplode(',',$page['keywords'], 1)) : '';
736
737 // Render list:
738 $trows = '';
739 $trows.= '
740 <tr class="tableheader bgColor5">
741 '.($stopWordBoxes ? '<td>'.htmlspecialchars('Stopword:').'</td>' : '').'
742 <td>'.htmlspecialchars('Word:').'</td>
743 <td>'.htmlspecialchars('Count:').'</td>
744 <td>'.htmlspecialchars('First:').'</td>
745 <td>'.htmlspecialchars('Frequency:').'</td>
746 <td>'.htmlspecialchars('Flags:').'</td>
747 '.(is_array($keywords) ? '<td>'.htmlspecialchars('Page keyword:').'</td>' : '').'
748 </tr>
749 ';
750 foreach($ftrows as $row) {
751 $hiddenField = $stopWordBoxes!=2 ? '<input type="hidden" name="stopWord['.$row['wid'].']" value="0" />' : '';
752 $trows.= '
753 <tr class="'.($row['is_stopword'] ? 'bgColor' : 'bgColor4').'">
754 '.($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>' : '').'
755 <td>'.$this->linkWordDetails(htmlspecialchars($this->utf8_to_currentCharset($row['baseword'])), $row['wid']).'</td>
756 <td>'.htmlspecialchars($row['count']).'</td>
757 <td>'.htmlspecialchars($row['first']).'</td>
758 <td>'.htmlspecialchars($row['freq']).'</td>
759 <td>'.htmlspecialchars($this->flagsMsg($row['flags'])).'</td>
760 '.(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>' : '').'
761 </tr>
762 ';
763 }
764
765 return '<h4>'.htmlspecialchars($header).'</h4>'.
766 '
767 <table border="0" cellspacing="1" cellpadding="2" class="c-list">
768 '.$trows.'
769 </table>'.
770 ($stopWordBoxes ? '<input type="submit" value="Change stop-word settings" name="_stopwords" onclick="document.webinfoForm.action=\''.htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')).'\';" />' : '').
771 (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'].'" />'.
772 '<br />Current keywords are: <em>' . htmlspecialchars(implode(', ', array_keys($keywords))) . '</em>' : '');
773 }
774
775 /**
776 * Displays table of metaphone groups larger than 1
777 *
778 * @param array Result from word selection (index_rel/index_words)
779 * @param string Header string
780 * @return string HTML table
781 */
782 function listMetaphoneStat($ftrows,$header) {
783
784 $trows = '';
785 $trows.= '
786 <tr class="tableheader bgColor5">
787 <td>'.htmlspecialchars('Metaphone:').'</td>
788 <td>'.htmlspecialchars('Hash:').'</td>
789 <td>'.htmlspecialchars('Count:').'</td>
790 <td>'.htmlspecialchars('Words:').'</td>
791 </tr>
792 ';
793 foreach($ftrows as $metaphone => $words) {
794 if (count($words)>1) {
795 $trows.= '
796 <tr class="bgColor4">
797 <td>'.$this->linkMetaPhoneDetails($this->indexerObj->metaphone($words[0],1),$metaphone).'</td>
798 <td>'.htmlspecialchars($metaphone).'</td>
799 <td>'.htmlspecialchars(count($words)).'</td>
800 <td style="white-space: normal;">'.htmlspecialchars($this->utf8_to_currentCharset(implode(', ',$words))).'</td>
801 </tr>
802 ';
803 }
804 }
805
806 return '<h4>'.htmlspecialchars($header).'</h4>'.
807 '<table border="0" cellspacing="1" cellpadding="2" class="c-list">
808 '.$trows.'
809 </table>';
810 }
811
812 /**
813 * Wraps input string in a link that will display details for the word. Eg. which other pages has the word, metaphone associations etc.
814 *
815 * @param string String to wrap, possibly a title or so.
816 * @param integer wid value to show details for
817 * @return string Wrapped string
818 */
819 function linkWordDetails($string,$wid) {
820 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('wid'=>$wid,'phash'=>''))).'">'.$string.'</a>';
821 }
822
823
824 /**
825 * Wraps input string in a link to see more details for metaphone value
826 *
827 * @param string String to wrap
828 * @param integer Metaphone value
829 * @return string Wrapped string
830 */
831 function linkMetaPhoneDetails($string,$metaphone) {
832 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('metaphone'=>$metaphone,'wid'=>'','phash'=>''))).'">'.$string.'</a>';
833 }
834
835 /**
836 * Creates message for flag value
837 *
838 * @param integer Flags integer
839 * @return string Message string
840 */
841 function flagsMsg($flags) {
842 if ($flags > 0) {
843 return
844 ($flags & 128 ? '<title>' : ''). // pow(2,7)
845 ($flags & 64 ? '<meta/keywords>' : ''). // pow(2,6)
846 ($flags & 32 ? '<meta/description>' : ''). // pow(2,5)
847 ' ('.$flags.')';
848 }
849 }
850
851
852
853
854
855
856
857
858
859
860 /*******************************
861 *
862 * Details display, words / metaphone
863 *
864 *******************************/
865
866 /**
867 * Show details for words
868 *
869 * @param integer Word ID (wid)
870 * @return string HTML content
871 */
872 function showDetailsForWord($wid) {
873
874 // Select references to this word
875 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
876 'index_phash.*, index_section.*, index_rel.*',
877 'index_rel, index_section, index_phash',
878 'index_rel.wid = '.intval($wid).
879 ' AND index_rel.phash = index_section.phash'.
880 ' AND index_section.phash = index_phash.phash',
881 '',
882 'index_rel.freq DESC',
883 ''
884 );
885
886 // Headers:
887 $content.='
888 <tr class="tableheader bgColor5">
889 <td>phash</td>
890 <td>page_id</td>
891 <td>data_filename</td>
892 <td>count</td>
893 <td>first</td>
894 <td>freq</td>
895 <td>flags</td>
896 </tr>';
897
898 if (is_array($ftrows)) {
899 foreach($ftrows as $wDat) {
900 $content.='
901 <tr class="bgColor4">
902 <td>'.$this->linkDetails(htmlspecialchars($wDat['phash']),$wDat['phash']).'</td>
903 <td>'.htmlspecialchars($wDat['page_id']).'</td>
904 <td>'.htmlspecialchars($wDat['data_filename']).'</td>
905 <td>'.htmlspecialchars($wDat['count']).'</td>
906 <td>'.htmlspecialchars($wDat['first']).'</td>
907 <td>'.htmlspecialchars($wDat['freq']).'</td>
908 <td>'.htmlspecialchars($wDat['flags']).'</td>
909 </tr>';
910 }
911 }
912
913 // Compile table:
914 $content = '
915 <table border="0" cellspacing="1" cellpadding="2" class="c-list">'.
916 $content.'
917 </table>';
918
919 // Add go-back link:
920 $content = $content.$this->linkList();
921
922 return $content;
923 }
924
925 /**
926 * Show details for metaphone value
927 *
928 * @param integer Metaphone integer hash
929 * @return string HTML content
930 */
931 function showDetailsForMetaphone($metaphone) {
932
933 // Finding top-20 on frequency for this phash:
934 $ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
935 'index_words.*',
936 'index_words',
937 'index_words.metaphone = '.intval($metaphone),
938 '',
939 'index_words.baseword',
940 ''
941 );
942
943 if (count($ftrows)) {
944 $content.='<h4>Metaphone: '.$this->indexerObj->metaphone($ftrows[0]['baseword'],1).'</h4>';
945
946 $content.='
947 <tr class="tableheader bgColor5">
948 <td>Word</td>
949 <td>Is stopword?</td>
950 </tr>';
951
952 if (is_array($ftrows)) {
953 foreach($ftrows as $wDat) {
954 $content.='
955 <tr class="bgColor4">
956 <td>'.$this->linkWordDetails(htmlspecialchars($wDat['baseword']),$wDat['wid']).'</td>
957 <td>'.htmlspecialchars($wDat['is_stopword'] ? 'YES' : 'No').'</td>
958 </tr>';
959 }
960 }
961
962 $content = '
963 <table border="0" cellspacing="1" cellpadding="2" class="c-list">'.
964 $content.'
965 </table>';
966
967 if ($this->indexerObj->metaphone($ftrows[0]['baseword'])!=$metaphone) {
968 $content.='ERROR: Metaphone string and hash did not match for some reason!?';
969 }
970
971 // Add go-back link:
972 $content = $content.$this->linkList();
973 }
974
975 return $content;
976 }
977
978
979
980
981
982
983
984
985
986
987
988
989 /*******************************
990 *
991 * Helper functions
992 *
993 *******************************/
994
995 /**
996 * Creates icon which clears indexes for a certain list of phash values.
997 *
998 * @param string List of phash integers
999 * @param string Alt-text for the garbage bin icon.
1000 * @return string HTML img-tag with link around.
1001 */
1002 function printRemoveIndexed($phash,$alt) {
1003 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('deletePhash'=>$phash))).'">'.
1004 '<img src="'.$GLOBALS['BACK_PATH'].'gfx/garbage.gif" width="11" hspace="1" vspace="2" height="12" border="0" title="'.htmlspecialchars($alt).'" alt="" />'.
1005 '</a>';
1006 }
1007
1008 /**
1009 * Button for re-indexing of documents
1010 *
1011 * @param array phash table result row.
1012 * @param string Title attribute text for icon
1013 * @return string HTML content; Icon wrapped in link.
1014 */
1015 function printReindex($resultRow,$alt) {
1016 if ($resultRow['item_type'] && $resultRow['item_type']!=='0') {
1017 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('reindex'=>$resultRow['phash'],'reindex_id'=>$resultRow['page_id']))).'">'.
1018 '<img src="'.$GLOBALS['BACK_PATH'].'gfx/refresh_n.gif" width="14" hspace="1" vspace="2" height="14" border="0" title="'.htmlspecialchars($alt).'" alt="" />'.
1019 '</a>';
1020 }
1021 }
1022
1023 /**
1024 * Wraps input string in a link that will display details for the phash value set.
1025 *
1026 * @param string String to wrap, possibly a title or so.
1027 * @param integer phash value to show details for
1028 * @return string Wrapped string
1029 */
1030 function linkDetails($string,$phash) {
1031 return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('phash'=>$phash))).'">'.$string.'</a>';
1032 }
1033
1034 /**
1035 * Creates link back to listing
1036 *
1037 * @return string Link back to list
1038 */
1039 function linkList() {
1040 return '<br /><a href="index.php?id=' . $this->pObj->id . '">Back to list.</a><br />';
1041 }
1042
1043 /**
1044 * Wraps input string in a link that will display details for the phash value set.
1045 *
1046 * @param string String to wrap, possibly a title or so.
1047 * @param integer phash value to show details for
1048 * @return string Wrapped string
1049 */
1050 function showPageDetails($string,$id) {
1051 return '<a href="'.htmlspecialchars('index.php?id='.$id.'&SET[depth]=0&SET[type]=1').'">'.$string.'</a>';
1052 }
1053
1054 /**
1055 * Prints the gr_lists attached to a indexed entry.
1056 *
1057 * @param array Array of index_grlist records
1058 * @return string HTML code.
1059 */
1060 function printExtraGrListRows($extraGrListRows) {
1061 if (count($extraGrListRows)) {
1062 reset($extraGrListRows);
1063 $lines=array();
1064 while(list(,$r)=each($extraGrListRows)) {
1065 $lines[] = $r['gr_list'];
1066 }
1067 return '<br />' . $GLOBALS['TBE_TEMPLATE']->dfw(implode('<br />', $lines));
1068 }
1069 }
1070
1071 /**
1072 * Print path for indexing
1073 *
1074 * @param array Result row with content from index_section
1075 * @return string Rootline information
1076 */
1077 function printRootlineInfo($row) {
1078 $uidCollection = array();
1079
1080 if ($row['rl0']) {
1081 $uidCollection[0] = $row['rl0'];
1082 if ($row['rl1']) {
1083 $uidCollection[1] = $row['rl1'];
1084 if ($row['rl2']) {
1085 $uidCollection[2] = $row['rl2'];
1086
1087 // Additional levels:
1088 if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['addRootLineFields'])) {
1089 foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['addRootLineFields'] as $fieldName => $rootLineLevel) {
1090 if ($row[$fieldName]) {
1091 $uidCollection[$rootLineLevel] = $row[$fieldName];
1092 }
1093 }
1094 }
1095 }
1096 }
1097 }
1098
1099 // Return root line.
1100 ksort($uidCollection);
1101 return implode('/',$uidCollection);
1102 }
1103
1104 /**
1105 * Return icon for file extension
1106 *
1107 * @param string File extension / item type
1108 * @param string Title attribute value in icon.
1109 * @return string <img> tag for icon
1110 */
1111 function makeItemTypeIcon($it,$alt='') {
1112 if (!isset($this->iconFileNameCache[$it])) {
1113 if ($it==='0') {
1114 $icon = 'EXT:indexed_search/pi/res/pages.gif';
1115 } elseif ($this->external_parsers[$it]) {
1116 $icon = $this->external_parsers[$it]->getIcon($it);
1117 }
1118
1119 $fullPath = t3lib_div::getFileAbsFileName($icon);
1120
1121 if ($fullPath) {
1122 $info = @getimagesize($fullPath);
1123 $iconPath = $GLOBALS['BACK_PATH'].'../'.substr($fullPath,strlen(PATH_site));
1124 $this->iconFileNameCache[$it] = is_array($info) ? '<img src="'.$iconPath.'" '.$info[3].' title="###TITLE_ATTRIBUTE###" alt="" />' : '';
1125 }
1126 }
1127 return str_replace('###TITLE_ATTRIBUTE###',htmlspecialchars($it.': '.$alt),$this->iconFileNameCache[$it]);
1128 }
1129
1130 /**
1131 * Converts the input string from utf-8 to the backend charset.
1132 *
1133 * @param string String to convert (utf-8)
1134 * @return string Converted string (backend charset if different from utf-8)
1135 */
1136 function utf8_to_currentCharset($string) {
1137 global $LANG;
1138 if ($LANG->charSet != 'utf-8') {
1139 $string = $LANG->csConvObj->utf8_decode($string, $LANG->charSet, TRUE);
1140 }
1141 return $string;
1142 }
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155 /********************************
1156 *
1157 * Reindexing
1158 *
1159 *******************************/
1160
1161 /**
1162 * Re-indexing files/records attached to a page.
1163 *
1164 * @param integer Phash value
1165 * @param integer The page uid for the section record (file/url could appear more than one place you know...)
1166 * @return string HTML content
1167 */
1168 function reindexPhash($phash, $pageId) {
1169
1170 // Query:
1171 list($resultRow) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
1172 'ISEC.*, IP.*',
1173 'index_phash IP, index_section ISEC',
1174 'IP.phash = ISEC.phash
1175 AND IP.phash = '.intval($phash).'
1176 AND ISEC.page_id = '.intval($pageId)
1177 );
1178
1179 $content = '';
1180 if (is_array($resultRow)) {
1181 if ($resultRow['item_type'] && $resultRow['item_type']!=='0') {
1182
1183 // (Re)-Indexing file on page.
1184 $indexerObj = t3lib_div::makeInstance('tx_indexedsearch_indexer');
1185 $indexerObj->backend_initIndexer($pageId, 0, 0, '', $this->getUidRootLineForClosestTemplate($pageId));
1186
1187 // URL or local file:
1188 if ($resultRow['externalUrl']) {
1189 $indexerObj->indexExternalUrl($resultRow['data_filename']);
1190 } else {
1191 $indexerObj->indexRegularDocument($resultRow['data_filename'], TRUE);
1192 }
1193
1194 if ($indexerObj->file_phash_arr['phash'] != $resultRow['phash']) {
1195 $content.= 'ERROR: phash ('.$indexerObj->file_phash_arr['phash'].') did NOT match '.$resultRow['phash'].' for strange reasons!';
1196 }
1197
1198 $content.='<h4>Log for re-indexing of "'.htmlspecialchars($resultRow['data_filename']).'":</h4>';
1199 $content.=t3lib_div::view_array($indexerObj->internal_log);
1200
1201 $content.='<h4>Hash-array, page:</h4>';
1202 $content.=t3lib_div::view_array($indexerObj->hash);
1203
1204 $content.='<h4>Hash-array, file:</h4>';
1205 $content.=t3lib_div::view_array($indexerObj->file_phash_arr);
1206 }
1207 }
1208
1209 // Link back to list.
1210 $content.= $this->linkList();
1211
1212 return $content;
1213 }
1214
1215 /**
1216 * Get rootline for closest TypoScript template root.
1217 * Algorithm same as used in Web > Template, Object browser
1218 *
1219 * @param integer The page id to traverse rootline back from
1220 * @return array Array where the root lines uid values are found.
1221 */
1222 function getUidRootLineForClosestTemplate($id) {
1223 $tmpl = t3lib_div::makeInstance('t3lib_tsparser_ext'); // Defined global here!
1224 $tmpl->tt_track = 0; // Do not log time-performance information
1225 $tmpl->init();
1226
1227 // Gets the rootLine
1228 $sys_page = t3lib_div::makeInstance('t3lib_pageSelect');
1229 $rootLine = $sys_page->getRootLine($id);
1230 $tmpl->runThroughTemplates($rootLine,0); // This generates the constants/config + hierarchy info for the template.
1231
1232 // Root line uids
1233 $rootline_uids = array();
1234 foreach($tmpl->rootLine as $rlkey => $rldat) {
1235 $rootline_uids[$rlkey] = $rldat['uid'];
1236 }
1237
1238 return $rootline_uids;
1239 }
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252 /********************************
1253 *
1254 * SQL functions
1255 *
1256 *******************************/
1257
1258 /**
1259 * Removes ALL data regarding a certain list of indexed phash-row
1260 *
1261 * @param string List of phash integers
1262 * @param boolean If set, page cache is cleared as well.
1263 * @return void
1264 */
1265 function removeIndexedPhashRow($phashList,$clearPageCache=1) {
1266 // FIXME: This is only a workaround
1267 if ($phashList=='ALL') {
1268 $this->drawTableOfIndexedPages();
1269 $phashRows = $this->allPhashListed;
1270 $this->allPhashListed = array(); // Reset it because it will be filled again later...
1271 } else {
1272 $phashRows = t3lib_div::trimExplode(',',$phashList,1);
1273 }
1274
1275 foreach($phashRows as $phash) {
1276 $phash = intval($phash);
1277 if ($phash>0) {
1278
1279 if ($clearPageCache) {
1280 // Clearing page cache:
1281 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('page_id', 'index_section', 'phash='.intval($phash));
1282 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
1283 $idList = array();
1284 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1285 $idList[] = $row['page_id'];
1286 }
1287
1288 $pageCache = $GLOBALS['typo3CacheManager']->getCache('cache_pages');
1289
1290 foreach ($idList as $pageId) {
1291 $pageCache->flushByTag('pageId_' . (int) $pageId);
1292 }
1293 }
1294 }
1295
1296 // Removing old registrations for all tables.
1297 $tableArr = explode(',','index_phash,index_rel,index_section,index_grlist,index_fulltext,index_debug');
1298 foreach($tableArr as $table) {
1299 $GLOBALS['TYPO3_DB']->exec_DELETEquery($table, 'phash='.intval($phash));
1300 }
1301
1302 // Did not remove any index_section records for external files where phash_t3 points to this hash!
1303 }
1304 }
1305 }
1306
1307 /**
1308 * Returns an array with gr_list records for a phash
1309 *
1310 * @param integer phash integer to look up on
1311 * @param string gr_list string to filter OUT of the result (first occurence)
1312 * @return array Array of records from index_grlist table
1313 */
1314 function getGrListEntriesForPhash($phash,$gr_list) {
1315 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'index_grlist', 'phash='.intval($phash));
1316 $lines = array();
1317 $isRemoved = 0;
1318 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1319 if (!$isRemoved && !strcmp($row['gr_list'],$gr_list)) {
1320 $isRemoved = 1;
1321 } else {
1322 $lines[] = $row;
1323 }
1324 }
1325 return $lines;
1326 }
1327
1328 /**
1329 * Setting / Unsetting stopwords
1330 *
1331 * @param array Array of stop-words WIDs with 0/1 to set / unset
1332 * @return void
1333 */
1334 function processStopWords($stopWords) {
1335
1336 if ($GLOBALS['BE_USER']->isAdmin()) {
1337 // Traverse words
1338 foreach($stopWords as $wid => $state) {
1339 $fieldArray = array(
1340 'is_stopword' => $state
1341 );
1342 $GLOBALS['TYPO3_DB']->exec_UPDATEquery('index_words', 'wid='.$wid, $fieldArray);
1343 }
1344 }
1345 }
1346
1347 /**
1348 * Setting / Unsetting keywords in page header
1349 *
1350 * @param array Page keywords as keys in array with value 0 or 1 for set or unset.
1351 * @param integer The page uid of the header where the keywords are to be set.
1352 * @return void
1353 */
1354 function processPageKeywords($pageKeywords, $pageUid) {
1355
1356 // Get pages current keywords
1357 $pageRec = t3lib_BEfunc::getRecord('pages', $pageUid);
1358 $keywords = array_flip(t3lib_div::trimExplode(',', $pageRec['keywords'], 1));
1359
1360 // Merge keywords:
1361 foreach($pageKeywords as $key => $v) {
1362 if ($v) {
1363 $keywords[$key]=1;
1364 } else {
1365 unset($keywords[$key]);
1366 }
1367 }
1368
1369 // Compile new list:
1370 $data = array();
1371 $data['pages'][$pageUid]['keywords'] = implode(', ',array_keys($keywords));
1372
1373 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
1374 $tce->stripslashes_values = 0;
1375 $tce->start($data,array());
1376 $tce->process_datamap();
1377 }
1378 }
1379
1380
1381
1382 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/indexed_search/modfunc1/class.tx_indexedsearch_modfunc1.php']) {
1383 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/indexed_search/modfunc1/class.tx_indexedsearch_modfunc1.php']);
1384 }
1385
1386 ?>