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