class.tx_indexedsearch_modfunc1.php 43.7 KB
Newer Older
Kasper Skårhøj's avatar
Kasper Skårhøj committed
1
2
3
<?php
/***************************************************************
*  Copyright notice
4
*
5
*  (c) 2001-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
Kasper Skårhøj's avatar
Kasper Skårhøj committed
6
7
*  All rights reserved
*
8
*  This script is part of the TYPO3 project. The TYPO3 project is
Kasper Skårhøj's avatar
Kasper Skårhøj committed
9
10
11
12
*  free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
13
*
Kasper Skårhøj's avatar
Kasper Skårhøj committed
14
15
*  The GNU General Public License can be found at
*  http://www.gnu.org/copyleft/gpl.html.
16
*
Kasper Skårhøj's avatar
Kasper Skårhøj committed
17
18
19
20
21
22
23
*  This script is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
24
/**
Kasper Skårhøj's avatar
Kasper Skårhøj committed
25
26
27
28
 * Module extension (addition to function menu) 'Indexed search' for the 'indexed_search' extension.
 *
 * @author    Kasper Skrhj <kasperYYYY@typo3.com>
 */
29
30
31
32
33
/**
 * [CLASS/FUNCTION INDEX of SCRIPT]
 *
 *
 *
34
35
36
 *  106: class tx_indexedsearch_modfunc1 extends t3lib_extobjbase
 *  120:     function modMenu()
 *  144:     function main()
37
38
 *
 *              SECTION: Drawing table of indexed pages
39
40
41
42
43
 *  248:     function drawTableOfIndexedPages()
 *  299:     function indexed_info($data, $firstColContent)
 *  386:     function printPhashRow($row,$grouping=0,$extraGrListRows)
 *  527:     function printPhashRowHeader()
 *  582:     function returnNumberOfColumns()
44
45
 *
 *              SECTION: Details display, phash row
46
47
48
49
50
51
 *  618:     function showDetailsForPhash($phash)
 *  737:     function listWords($ftrows,$header, $stopWordBoxes=FALSE, $page='')
 *  787:     function listMetaphoneStat($ftrows,$header)
 *  824:     function linkWordDetails($string,$wid)
 *  836:     function linkMetaPhoneDetails($string,$metaphone)
 *  846:     function flagsMsg($flags)
52
53
 *
 *              SECTION: Details display, words / metaphone
54
55
 *  877:     function showDetailsForWord($wid)
 *  936:     function showDetailsForMetaphone($metaphone)
56
57
 *
 *              SECTION: Helper functions
58
59
60
61
62
63
64
65
66
 * 1007:     function printRemoveIndexed($phash,$alt)
 * 1020:     function printReindex($resultRow,$alt)
 * 1035:     function linkDetails($string,$phash)
 * 1044:     function linkList()
 * 1055:     function showPageDetails($string,$id)
 * 1065:     function printExtraGrListRows($extraGrListRows)
 * 1082:     function printRootlineInfo($row)
 * 1116:     function makeItemTypeIcon($it,$alt='')
 * 1141:     function utf8_to_currentCharset($string)
67
68
 *
 *              SECTION: Reindexing
69
70
 * 1173:     function reindexPhash($phash, $pageId)
 * 1227:     function getUidRootLineForClosestTemplate($id)
71
72
 *
 *              SECTION: SQL functions
73
74
75
76
 * 1270:     function removeIndexedPhashRow($phashList,$clearPageCache=1)
 * 1314:     function getGrListEntriesForPhash($phash,$gr_list)
 * 1334:     function processStopWords($stopWords)
 * 1354:     function processPageKeywords($pageKeywords, $pageUid)
77
 *
78
 * TOTAL FUNCTIONS: 30
79
80
81
82
83
84
85
86
87
 * (This index is automatically created/updated by the extension "extdeveval")
 *
 */


require_once(PATH_t3lib.'class.t3lib_pagetree.php');
require_once(PATH_t3lib.'class.t3lib_extobjbase.php');
require_once(t3lib_extMgm::extPath('indexed_search').'class.indexer.php');

Kasper Skårhøj's avatar
Kasper Skårhøj committed
88

89
90
91
92
	// ... all for the rootline!
require_once (PATH_t3lib."class.t3lib_page.php");
require_once (PATH_t3lib."class.t3lib_tstemplate.php");
require_once (PATH_t3lib."class.t3lib_tsparser_ext.php");
Kasper Skårhøj's avatar
Kasper Skårhøj committed
93

94
95
	// Keywords mgm:
require_once (PATH_t3lib."class.t3lib_tcemain.php");
Kasper Skårhøj's avatar
Kasper Skårhøj committed
96
97


98
99
100
101
102
103
104
105

/**
 * Indexing class for TYPO3 frontend
 *
 * @author	Kasper Skaarhoj <kasperYYYY@typo3.com>
 * @package TYPO3
 * @subpackage tx_indexedsearch
 */
Kasper Skårhøj's avatar
Kasper Skårhøj committed
106
class tx_indexedsearch_modfunc1 extends t3lib_extobjbase {
107
108
109
110
111
112
113
114
115
116
117
118
119

		// Internal, dynamic:
	var $allPhashListed = array();		// phash values accumulations for link to clear all
	var $external_parsers = array();	// External content parsers - objects set here with file extensions as keys.
	var $iconFileNameCache = array();	// File extensions - icon map/cache.
	var $indexerObj;					// Indexer object


	/**
	 * Initialize menu array internally
	 *
	 * @return	void
	 */
120
121
	function modMenu()	{
		global $LANG;
122

Kasper Skårhøj's avatar
Kasper Skårhøj committed
123
		return array (
124
125
126
127
128
			'depth' => array(
				0 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_0'),
				1 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_1'),
				2 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_2'),
				3 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_3'),
129
				999 => $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.depth_infi'),
130
131
132
133
134
			),
			'type' => array(
				0 => 'Overview',
				1 => 'Technical Details',
				2 => 'Words and content',
Kasper Skårhøj's avatar
Kasper Skårhøj committed
135
136
			)
		);
137
	}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
138

139
140
141
142
143
	/**
	 * Produces main content of the module
	 *
	 * @return	string		HTML output
	 */
144
145
	function main()	{
			// Initializes the module. Done in this function because we may need to re-initialize if data is submitted!
146
		global $LANG,$TYPO3_CONF_VARS;
Kasper Skårhøj's avatar
Kasper Skårhøj committed
147

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
			// Return if no page id:
		if ($this->pObj->id<=0)		return;

			// Initialize max-list items
		$this->maxListPerPage = t3lib_div::_GP('listALL') ? 100000 : 100;

			// Processing deletion of phash rows:
		if (t3lib_div::_GP('deletePhash'))	{
			$this->removeIndexedPhashRow(t3lib_div::_GP('deletePhash'));
		}

			// Processing stop-words:
		if (t3lib_div::_POST('_stopwords'))	{
			$this->processStopWords(t3lib_div::_POST('stopWord'));
		}

			// Processing stop-words:
		if (t3lib_div::_POST('_pageKeywords'))	{
			$this->processPageKeywords(t3lib_div::_POST('pageKeyword'), t3lib_div::_POST('pageKeyword_pageUid'));
Kasper Skårhøj's avatar
Kasper Skårhøj committed
167
168
		}

169
170
171
172
173
			// Initialize external document parsers:
			// Example configuration, see ext_localconf.php of this file!
		if (is_array($TYPO3_CONF_VARS['EXTCONF']['indexed_search']['external_parsers']))	{
			foreach($TYPO3_CONF_VARS['EXTCONF']['indexed_search']['external_parsers'] as $extension => $_objRef)	{
				$this->external_parsers[$extension] = &t3lib_div::getUserObj($_objRef);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
174

175
					// Init parser and if it returns false, unset its entry again:
Kasper Skårhøj's avatar
Kasper Skårhøj committed
176
				if (!$this->external_parsers[$extension]->softInit($extension))	{
177
178
179
180
					unset($this->external_parsers[$extension]);
				}
			}
		}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
181

182
183
			// Initialize indexer if we need it (metaphone display does...)
		$this->indexerObj = &t3lib_div::makeInstance('tx_indexedsearch_indexer');
Kasper Skårhøj's avatar
Kasper Skårhøj committed
184

185
186
187
188
			// Set CSS styles specific for this document:
		$this->pObj->content = str_replace('/*###POSTCSSMARKER###*/','
			TABLE.c-list TR TD { white-space: nowrap; vertical-align: top; }
		',$this->pObj->content);
Kasper Skårhøj's avatar
Kasper Skårhøj committed
189
190


191
192
			// Check if details for a phash record should be shown:
		if (t3lib_div::_GET('phash'))	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
193

194
195
196
197
				// Show title / function menu:
			$theOutput.=$this->pObj->doc->spacer(5);
			$theOutput.=$this->pObj->doc->section('Details for a single result row:',$this->showDetailsForPhash(t3lib_div::_GET('phash')),0,1);
		} elseif (t3lib_div::_GET('wid'))	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
198

199
200
201
202
				// Show title / function menu:
			$theOutput.=$this->pObj->doc->spacer(5);
			$theOutput.=$this->pObj->doc->section('Details for a word:',$this->showDetailsForWord(t3lib_div::_GET('wid')),0,1);
		} elseif (t3lib_div::_GET('metaphone'))	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
203

204
205
206
207
				// Show title / function menu:
			$theOutput.=$this->pObj->doc->spacer(5);
			$theOutput.=$this->pObj->doc->section('Details for metaphone value:',$this->showDetailsForMetaphone(t3lib_div::_GET('metaphone')),0,1);
		} elseif (t3lib_div::_GET('reindex'))	{
Kasper Skårhøj's avatar
Kasper Skårhøj committed
208

209
210
211
212
213
214
				// Show title / function menu:
			$theOutput.=$this->pObj->doc->spacer(5);
			$theOutput.=$this->pObj->doc->section('Reindexing...',$this->reindexPhash(t3lib_div::_GET('reindex'),t3lib_div::_GET('reindex_id')),0,1);
		} else {	// Detail listings:
				// Depth function menu:
			$h_func = t3lib_BEfunc::getFuncMenu($this->pObj->id,'SET[type]',$this->pObj->MOD_SETTINGS['type'],$this->pObj->MOD_MENU['type'],'index.php');
215
			$h_func.= t3lib_BEfunc::getFuncMenu($this->pObj->id,'SET[depth]',$this->pObj->MOD_SETTINGS['depth'],$this->pObj->MOD_MENU['depth'],'index.php');
216

217
218
219
				// Show title / function menu:
			$theOutput.=$this->pObj->doc->spacer(5);
			$theOutput.=$this->pObj->doc->section($LANG->getLL('title'),$h_func,0,1);
220

221
			$theOutput.=$this->drawTableOfIndexedPages();
222
		}
Kasper Skårhøj's avatar
Kasper Skårhøj committed
223
224
225

        return $theOutput;
    }
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271











	/*******************************
	 *
	 * Drawing table of indexed pages
	 *
	 ******************************/

	/**
	 * Produces a table with indexing information for each page.
	 *
	 * @return	string		HTML output
	 */
	function drawTableOfIndexedPages()	{
		global $BACK_PATH;

			// Drawing tree:
		$tree = t3lib_div::makeInstance('t3lib_pageTree');
		$perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
		$tree->init('AND '.$perms_clause);

		$HTML = '<img src="'.$BACK_PATH.t3lib_iconWorks::getIcon('pages',$this->pObj->pageinfo).'" width="18" height="16" align="top" alt="" />';
		$tree->tree[] = Array(
			'row' => $this->pObj->pageinfo,
			'HTML' => $HTML
		);

		if ($this->pObj->MOD_SETTINGS['depth'])	{
			$tree->getTree($this->pObj->id, $this->pObj->MOD_SETTINGS['depth'], '');
		}

			// Traverse page tree:
		$code = '';
		foreach($tree->tree as $data)	{
			$code.= $this->indexed_info(
						$data['row'],
						$data['HTML'].
272
							$this->showPageDetails(t3lib_BEfunc::getRecordTitlePrep($data['row']['title']), $data['row']['uid'])
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
					);
		}

		if ($code)	{
			$code = '<br/><br/>
					<table border="0" cellspacing="1" cellpadding="2" class="c-list">'.
						$this->printPhashRowHeader().
						$code.
					'</table>';

				// Create section to output:
			$theOutput.=$this->pObj->doc->section('',$code,0,1);
		} else {
			$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);
		}

		return 	$theOutput;
	}

	/**
	 * Create information table row for a page regarding indexing information.
	 *
	 * @param	array		Data array for this page
	 * @param	string		HTML content for first column (page tree icon etc.)
	 * @return	string		HTML code. (table row)
	 */
	function indexed_info($data, $firstColContent)	{

			// Query:
Kasper Skårhøj's avatar
Kasper Skårhøj committed
302
		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
303
304
					'ISEC.*, IP.*, count(*) AS count_val',
					'index_phash IP, index_section ISEC',
Kasper Skårhøj's avatar
Kasper Skårhøj committed
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
308
					'IP.item_type, IP.tstamp',
					($this->maxListPerPage+1)
Kasper Skårhøj's avatar
Kasper Skårhøj committed
309
				);
310
311
312
313
314

			// Initialize variables:
		$rowCount = 0;
		$lines = array();		// Collecting HTML rows here.
		$phashAcc = array();	// Collecting phash values (to remove local indexing for)
Kasper Skårhøj's avatar
Kasper Skårhøj committed
315
		$phashAcc[] = 0;
316
317

			// Traverse the result set of phash rows selected:
Kasper Skårhøj's avatar
Kasper Skårhøj committed
318
		while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
			if ($rowCount == $this->maxListPerPage)	{
				$rowCount++;	// Increase to the extra warning row will appear as well.
				break;
			}

				// Adds a display row:
			$lines[$row['phash_grouping']][] = $this->printPhashRow(
						$row,
						isset($lines[$row['phash_grouping']]),
						$this->getGrListEntriesForPhash($row['phash'], $row['gr_list'])
					);
			$rowCount++;
			$phashAcc[] = $row['phash'];
			$this->allPhashListed[] = $row['phash'];	// For removing all shown phash rows.
		}

			// Compile rows into the table:
		$out = '';
337
		$cellAttrib = ($data['_CSSCLASS'] ? ' class="'.$data['_CSSCLASS'].'"' : '');
338
		if (count($lines))	{
339
			$firstColContent = '<td rowspan="'.$rowCount.'"'.$cellAttrib.'>'.$firstColContent.'</td>';
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
			foreach($lines as $rowSet)	{
				foreach($rowSet as $rows)	{
					$out.='
						<tr class="bgColor-20">'.$firstColContent.implode('',$rows).'</tr>';

					$firstColContent = '';
				}
			}

			if ($rowCount > $this->maxListPerPage)	{	// Now checking greater than, because we increased $rowCount before...
				$out.='
				<tr class="bgColor-20">
					<td>&nbsp;</td>
					<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>
				</tr>';
Kasper Skårhøj's avatar
Kasper Skårhøj committed
355
			}
356
357
358
		} else {
			$out.='
				<tr class="bgColor-20">
359
					<td'.$cellAttrib.'>'.$firstColContent.'</td>
360
361
					<td colspan="'.($this->returnNumberOfColumns()-1).'"><em>Not indexed</em></td>
				</tr>';
Kasper Skårhøj's avatar
Kasper Skårhøj committed
362
363
		}

364
			// Checking for phash-rows which are NOT joined with the section table:
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
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).')');
Kasper Skårhøj's avatar
Kasper Skårhøj committed
366
		while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
367
368
369
370
371
			$out.='
				<tr class="typo3-red">
					<td colspan="'.$this->returnNumberOfColumns().'"><b>Warning:</b> phash-row "'.$row['phash'].'" didn\'t have a representation in the index_section table!</td>
				</tr>';
			$this->allPhashListed[] = $row['phash'];
Kasper Skårhøj's avatar
Kasper Skårhøj committed
372
		}
373

Kasper Skårhøj's avatar
Kasper Skårhøj committed
374
375
		return $out;
	}
376
377
378
379
380
381
382
383
384
385

	/**
	 * Render a single row of information about a indexing entry.
	 *
	 * @param	array		Row from query (combined phash table with sections etc).
	 * @param	boolean		Set if grouped to previous result; the icon of the element is not shown again.
	 * @param	array		Array of index_grlist records.
	 * @return	array		Array of table rows.
	 * @see indexed_info()
	 */
Kasper Skårhøj's avatar
Kasper Skårhøj committed
386
	function printPhashRow($row,$grouping=0,$extraGrListRows)	{
387
388
389
390
391
392
393
394
395
		$lines = array();

			// 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!
		$titleCellAttribs = $row['count_val']!=1?' bgcolor="red"':($row['item_type']==='0' ? ' class="bgColor4"' : '');

		if ($row['item_type'])	{
			$arr = unserialize($row['cHashParams']);
			$page = $arr['key'] ? ' ['.$arr['key'].']' : '';
		} else $page = '';
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
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
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
		$cmdLinks = $this->printRemoveIndexed($row['phash'],'Clear phash-row').$this->printReindex($row,'Re-index element');

		switch($this->pObj->MOD_SETTINGS['type'])	{
			case 1:		// Technical details:
					// Display icon:
				if (!$grouping)	{
					$lines[] = '<td>'.$this->makeItemTypeIcon($row['item_type'], $row['data_filename'] ? $row['data_filename'] : $row['item_title']).'</td>';
				} else {
					$lines[] = '<td>&nbsp;</td>';
				}

					// Title displayed:
				$lines[] = '<td'.$titleCellAttribs.'>'.$elTitle.'</td>';

					// Remove-indexing-link:
				$lines[] = '<td>'.$cmdLinks.'</td>';

					// Various data:
				$lines[] = '<td>'.$row['phash'].'</td>';
				$lines[] = '<td>'.$row['contentHash'].'</td>';

				if ($row['item_type']==='0')	{
					$lines[] = '<td>'.($row['data_page_id'] ? $row['data_page_id'] : '&nbsp;').'</td>';
					$lines[] = '<td>'.($row['data_page_type'] ? $row['data_page_type'] : '&nbsp;').'</td>';
					$lines[] = '<td>'.($row['sys_language_uid'] ? $row['sys_language_uid'] : '&nbsp;').'</td>';
					$lines[] = '<td>'.($row['data_page_mp'] ? $row['data_page_mp'] : '&nbsp;').'</td>';
				} else {
					$lines[] = '<td colspan="4">'.htmlspecialchars($row['data_filename']).'</td>';
				}
				$lines[] = '<td>'.$row['gr_list'].$this->printExtraGrListRows($extraGrListRows).'</td>';
				$lines[] = '<td>'.$this->printRootlineInfo($row).'</td>';
				$lines[] = '<td>'.($row['page_id'] ? $row['page_id'] : '&nbsp;').'</td>';
				$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
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
				$lines[] = '<td>'.($row['recordUid'] ? $row['recordUid'] : '&nbsp;').'</td>';



					// cHash parameters:
				$arr = unserialize($row['cHashParams']);
				if (is_array($arr))		{
					$theCHash = $arr['cHash'];
					unset($arr['cHash']);
				}

				if ($row['item_type'])	{	// pdf...
					$lines[] = '<td>'.($arr['key'] ? 'Page '.$arr['key'] : '').'&nbsp;</td>';
				} elseif ($row['item_type']==0) {
					$lines[] = '<td>'.htmlspecialchars(t3lib_div::implodeArrayForUrl('',$arr)).'&nbsp;</td>';
				} else {
					$lines[] = '<td class="bgColor">&nbsp;</td>';
				}

				$lines[] = '<td>'.$theCHash.'</td>';
			break;
			case 2:		// Words and content:
					// Display icon:
				if (!$grouping)	{
					$lines[] = '<td>'.$this->makeItemTypeIcon($row['item_type'], $row['data_filename'] ? $row['data_filename'] : $row['item_title']).'</td>';
				} else {
					$lines[] = '<td>&nbsp;</td>';
				}

					// Title displayed:
				$lines[] = '<td'.$titleCellAttribs.'>'.$elTitle.'</td>';

					// Remove-indexing-link:
				$lines[] = '<td>'.$cmdLinks.'</td>';

					// Query:
				$ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
							'*',
							'index_fulltext',
							'phash = '.intval($row['phash'])
						);
				$lines[] = '<td style="white-space: normal;">'.
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
473
							htmlspecialchars(t3lib_div::fixed_lgd_cs($this->utf8_to_currentCharset($ftrows[0]['fulltextdata']),3000)).
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
							'<hr/><em>Size: '.strlen($ftrows[0]['fulltextdata']).'</em>'.
							'</td>';

					// Query:
				$ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
							'index_words.baseword, index_rel.*',
							'index_rel, index_words',
							'index_rel.phash = '.intval($row['phash']).
								' AND index_words.wid = index_rel.wid',
							'',
							'',
							'',
							'baseword'
						);

				$wordList = '';
				if (is_array($ftrows))	{
					$indexed_words = array_keys($ftrows);
					sort($indexed_words);
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
493
					$wordList = htmlspecialchars($this->utf8_to_currentCharset(implode(' ',$indexed_words)));
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
					$wordList.='<hr/><em>Count: '.count($indexed_words).'</em>';
				}

				$lines[] = '<td style="white-space: normal;">'.$wordList.'</td>';
			break;
			default:	// Overview
					// Display icon:
				if (!$grouping)	{
					$lines[] = '<td>'.$this->makeItemTypeIcon($row['item_type'], $row['data_filename'] ? $row['data_filename'] : $row['item_title']).'</td>';
				} else {
					$lines[] = '<td>&nbsp;</td>';
				}

					// Title displayed:
				$lines[] = '<td'.$titleCellAttribs.'>'.$elTitle.'</td>';

					// Remove-indexing-link:
				$lines[] = '<td>'.$cmdLinks.'</td>';

Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
513
				$lines[] = '<td style="white-space: normal;">'.htmlspecialchars($this->utf8_to_currentCharset($row['item_description'])).'...</td>';
514
515
516
				$lines[] = '<td>'.t3lib_div::formatSize($row['item_size']).'</td>';
				$lines[] = '<td>'.t3lib_BEfunc::dateTimeAge($row['tstamp']).'</td>';
			break;
Kasper Skårhøj's avatar
Kasper Skårhøj committed
517
		}
518
519

		return $lines;
Kasper Skårhøj's avatar
Kasper Skårhøj committed
520
	}
521
522
523
524
525
526

	/**
	 * Creates the header row for the table
	 *
	 * @return	string		HTML string (table row)
	 */
Kasper Skårhøj's avatar
Kasper Skårhøj committed
527
	function printPhashRowHeader()	{
528
529
530
531
532
533
534
		$lines = array();

		switch($this->pObj->MOD_SETTINGS['type'])	{
			case 1:
				$lines[] = '<td>&nbsp;</td>';
				$lines[] = '<td>&nbsp;</td>';
				$lines[] = '<td>Title</td>';
535
				$lines[] = '<td bgcolor="red">'.$this->printRemoveIndexed('ALL','Clear ALL phash-rows below!').'</td>';
536
537

				$lines[] = '<td>pHash</td>';
538
				$lines[] = '<td>contentHash</td>';
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
				$lines[] = '<td>&amp;id</td>';
				$lines[] = '<td>&amp;type</td>';
				$lines[] = '<td>&amp;L</td>';
				$lines[] = '<td>&amp;MP</td>';
				$lines[] = '<td>grlist</td>';
				$lines[] = '<td>Rootline</td>';
				$lines[] = '<td>page_id</td>';
				$lines[] = '<td>phash_t3</td>';
				$lines[] = '<td>CfgUid</td>';
				$lines[] = '<td>RecUid</td>';
				$lines[] = '<td>GET-parameters</td>';
				$lines[] = '<td>&amp;cHash</td>';
			break;
			case 2:
				$lines[] = '<td>&nbsp;</td>';
				$lines[] = '<td>&nbsp;</td>';
				$lines[] = '<td>Title</td>';
556
				$lines[] = '<td bgcolor="red">'.$this->printRemoveIndexed('ALL','Clear ALL phash-rows below!').'</td>';
557
558
559
560
				$lines[] = '<td>Content<br/>
							<img src="clear.gif" width="300" height="1" alt="" /></td>';
				$lines[] = '<td>Words<br/>
							<img src="clear.gif" width="300" height="1" alt="" /></td>';
561
562
563
564
565
			break;
			default:
				$lines[] = '<td>&nbsp;</td>';
				$lines[] = '<td>&nbsp;</td>';
				$lines[] = '<td>Title</td>';
566
				$lines[] = '<td bgcolor="red">'.$this->printRemoveIndexed('ALL','Clear ALL phash-rows below!').'</td>';
567
568
569
570
571
572
573
				$lines[] = '<td>Description</td>';
				$lines[] = '<td>Size</td>';
				$lines[] = '<td>Indexed:</td>';
			break;
		}

		$out = '<tr class="tableheader bgColor5">'.implode('',$lines).'</tr>';
Kasper Skårhøj's avatar
Kasper Skårhøj committed
574
575
		return $out;
	}
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684

	/**
	 * Returns the number of columns depending on display type of list
	 *
	 * @return	integer		Number of columns in list:
	 */
	function returnNumberOfColumns()	{
		switch($this->pObj->MOD_SETTINGS['type'])	{
			case 1:
				return 18;
			break;
			case 2:
				return 6;
			break;
			default:
				return 7;
			break;
		}
	}











	/*******************************
	 *
	 * Details display, phash row
	 *
	 *******************************/

	/**
	 * Showing details for a particular phash row
	 *
	 * @param	integer		phash value to display details for.
	 * @return	string		HTML content
	 */
	function showDetailsForPhash($phash)	{

		$content = '';

			// Selects the result row:
		$ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
					'*',
					'index_phash',
					'phash = '.intval($phash)
				);
		$phashRecord = $ftrows[0];

			// If found, display:
		if (is_array($phashRecord))	{
			$content.= '<h4>phash row content:</h4>'.
						$this->utf8_to_currentCharset(t3lib_div::view_array($phashRecord));

				// Getting debug information if any:
			$ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
						'*',
						'index_debug',
						'phash = '.intval($phash)
					);
			if (is_array($ftrows))	{
				$debugInfo = unserialize($ftrows[0]['debuginfo']);
				$lexer = $debugInfo['lexer'];
				unset($debugInfo['lexer']);

				$content.= '<h3>Debug information:</h3>'.
						$this->utf8_to_currentCharset(t3lib_div::view_array($debugInfo));

				$content.= '<h4>Debug information / lexer splitting:</h4>'.
						'<hr/><b>'.
						$this->utf8_to_currentCharset($lexer).
						'</b><hr/>';
			}



			$content.='<h3>Word statistics</h3>';

				// Finding all words for this phash:
			$ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
						'index_words.*, index_rel.*',
						'index_rel, index_words',
						'index_rel.phash = '.intval($phash).
							' AND index_words.wid = index_rel.wid',
						'',
						'index_words.baseword',
						''
					);
			$pageRec = t3lib_BEfunc::getRecord('pages', $phashRecord['data_page_id']);
			$showStopWordCheckBox = $GLOBALS['BE_USER']->isAdmin();
			$content.= $this->listWords($ftrows, 'All words found on page ('.count($ftrows).'):', $showStopWordCheckBox, $pageRec);

				// Group metaphone hash:
			$metaphone = array();
			foreach($ftrows as $row)	{
				$metaphone[$row['metaphone']][] = $row['baseword'];
			}
			$content.= $this->listMetaphoneStat($metaphone, 'Metaphone stats:');

				// Finding top-20 on frequency for this phash:
			$ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
						'index_words.baseword, index_words.metaphone, index_rel.*',
						'index_rel, index_words',
						'index_rel.phash = '.intval($phash).
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
685
686
							' AND index_words.wid = index_rel.wid
							 AND index_words.is_stopword=0',
687
688
689
690
						'',
						'index_rel.freq DESC',
						'20'
					);
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
691
			$content.= $this->listWords($ftrows, 'Top-20 words by frequency:', 2);
692
693
694
695
696
697

				// Finding top-20 on count for this phash:
			$ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
						'index_words.baseword, index_words.metaphone, index_rel.*',
						'index_rel, index_words',
						'index_rel.phash = '.intval($phash).
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
698
699
							' AND index_words.wid = index_rel.wid
							 AND index_words.is_stopword=0',
700
701
702
703
						'',
						'index_rel.count DESC',
						'20'
					);
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
704
			$content.= $this->listWords($ftrows, 'Top-20 words by count:', 2);
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755


			$content.='<h3>Section records for this phash</h3>';

				// Finding sections for this record:
			$ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
						'*',
						'index_section',
						'index_section.phash = '.intval($phash),
						'',
						'',
						''
					);
			$content.= t3lib_div::view_array($ftrows);

				// Add go-back link:
			$content = $this->linkList().$content.$this->linkList();

		} else $content.= 'Error: No phash row found';

		return $content;
	}

	/**
	 * Create table with list of words from $ftrows
	 *
	 * @param	array		Array of records selected from index_rel/index_words
	 * @param	string		Header string to show before table.
	 * @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).
	 * @param	array		The page record from which to load the keywords, if any.
	 * @return	string		HTML table
	 */
	function listWords($ftrows,$header, $stopWordBoxes=FALSE, $page='')	{

			// Prepare keywords:
		$keywords = is_array($page) ? array_flip(t3lib_div::trimExplode(',',$page['keywords'], 1)) : '';

			// Render list:
		$trows = '';
		$trows.= '
			<tr class="tableheader bgColor5">
				'.($stopWordBoxes ? '<td>'.htmlspecialchars('Stopword:').'</td>' : '').'
				<td>'.htmlspecialchars('Word:').'</td>
				<td>'.htmlspecialchars('Count:').'</td>
				<td>'.htmlspecialchars('First:').'</td>
				<td>'.htmlspecialchars('Frequency:').'</td>
				<td>'.htmlspecialchars('Flags:').'</td>
				'.(is_array($keywords) ? '<td>'.htmlspecialchars('Page keyword:').'</td>' : '').'
			</tr>
		';
		foreach($ftrows as $row)	{
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
756
			$hiddenField = $stopWordBoxes!=2 ? '<input type="hidden" name="stopWord['.$row['wid'].']" value="0" />' : '';
757
758
			$trows.= '
				<tr class="'.($row['is_stopword'] ? 'bgColor' : 'bgColor4').'">
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
759
760
					'.($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>' : '').'
					<td>'.$this->linkWordDetails(htmlspecialchars($this->utf8_to_currentCharset($row['baseword'])), $row['wid']).'</td>
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
					<td>'.htmlspecialchars($row['count']).'</td>
					<td>'.htmlspecialchars($row['first']).'</td>
					<td>'.htmlspecialchars($row['freq']).'</td>
					<td>'.htmlspecialchars($this->flagsMsg($row['flags'])).'</td>
					'.(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>' : '').'
				</tr>
			';
		}

		return '<h4>'.htmlspecialchars($header).'</h4>'.
					'
					<table border="0" cellspacing="1" cellpadding="2" class="c-list">
					'.$trows.'
					</table>'.
					($stopWordBoxes ? '<input type="submit" value="Change stop-word settings" name="_stopwords" onclick="document.webinfoForm.action=\''.htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')).'\';" />' : '').
					(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'].'" />'.
										'<br/>Current keywords are: <em>'.htmlspecialchars(implode(', ',array_keys($keywords))).'</em>' : '');
	}

	/**
	 * Displays table of metaphone groups larger than 1
	 *
	 * @param	array		Result from word selection (index_rel/index_words)
	 * @param	string		Header string
	 * @return	string		HTML table
	 */
	function listMetaphoneStat($ftrows,$header)	{

		$trows = '';
		$trows.= '
			<tr class="tableheader bgColor5">
				<td>'.htmlspecialchars('Metaphone:').'</td>
				<td>'.htmlspecialchars('Hash:').'</td>
				<td>'.htmlspecialchars('Count:').'</td>
				<td>'.htmlspecialchars('Words:').'</td>
			</tr>
		';
		foreach($ftrows as $metaphone => $words)	{
			if (count($words)>1)	{
				$trows.= '
					<tr class="bgColor4">
						<td>'.$this->linkMetaPhoneDetails($this->indexerObj->metaphone($words[0],1),$metaphone).'</td>
						<td>'.htmlspecialchars($metaphone).'</td>
						<td>'.htmlspecialchars(count($words)).'</td>
Kasper Skårhøj's avatar
   
Kasper Skårhøj committed
805
						<td style="white-space: normal;">'.htmlspecialchars($this->utf8_to_currentCharset(implode(', ',$words))).'</td>
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
					</tr>
				';
			}
		}

		return '<h4>'.htmlspecialchars($header).'</h4>'.
					'<table border="0" cellspacing="1" cellpadding="2" class="c-list">
					'.$trows.'
					</table>';
	}

	/**
	 * Wraps input string in a link that will display details for the word. Eg. which other pages has the word, metaphone associations etc.
	 *
	 * @param	string		String to wrap, possibly a title or so.
	 * @param	integer		wid value to show details for
	 * @return	string		Wrapped string
	 */
	function linkWordDetails($string,$wid)	{
		return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('wid'=>$wid,'phash'=>''))).'">'.$string.'</a>';
	}


	/**
	 * Wraps input string in a link to see more details for metaphone value
	 *
	 * @param	string		String to wrap
	 * @param	integer		Metaphone value
	 * @return	string		Wrapped string
	 */
	function linkMetaPhoneDetails($string,$metaphone)	{
		return '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('metaphone'=>$metaphone,'wid'=>'','phash'=>''))).'">'.$string.'</a>';
	}

	/**
	 * Creates message for flag value
	 *
	 * @param	integer		Flags integer
	 * @return	string		Message string
	 */
	function flagsMsg($flags)	{
		if ($flags > 0)	{
			return
				($flags & 128 ? '<title>' : '').	// pow(2,7)
				($flags & 64 ? '<meta/keywords>' : '').	// pow(2,6)
				($flags & 32 ? '<meta/description>' : '').	// pow(2,5)
				' ('.$flags.')';
		}
	}










	/*******************************
	 *
	 * Details display, words / metaphone
	 *
	 *******************************/

	/**
	 * Show details for words
	 *
	 * @param	integer		Word ID (wid)
	 * @return	string		HTML content
	 */
	function showDetailsForWord($wid)	{

			// Select references to this word
		$ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
					'index_phash.*, index_section.*, index_rel.*',
					'index_rel, index_section, index_phash',
					'index_rel.wid = '.intval($wid).
						' AND index_rel.phash = index_section.phash'.
						' AND index_section.phash = index_phash.phash',
					'',
					'index_rel.freq DESC',
					''
				);

			// Headers:
		$content.='
			<tr class="tableheader bgColor5">
				<td>phash</td>
				<td>page_id</td>
				<td>data_filename</td>
				<td>count</td>
				<td>first</td>
				<td>freq</td>
				<td>flags</td>
			</tr>';

		if (is_array($ftrows))	{
			foreach($ftrows as $wDat)	{
				$content.='
					<tr class="bgColor4">
						<td>'.$this->linkDetails(htmlspecialchars($wDat['phash']),$wDat['phash']).'</td>
						<td>'.htmlspecialchars($wDat['page_id']).'</td>
						<td>'.htmlspecialchars($wDat['data_filename']).'</td>
						<td>'.htmlspecialchars($wDat['count']).'</td>
						<td>'.htmlspecialchars($wDat['first']).'</td>
						<td>'.htmlspecialchars($wDat['freq']).'</td>
						<td>'.htmlspecialchars($wDat['flags']).'</td>
					</tr>';
			}
		}

			// Compile table:
		$content = '
			<table border="0" cellspacing="1" cellpadding="2" class="c-list">'.
				$content.'
			</table>';

			// Add go-back link:
		$content = $content.$this->linkList();

		return $content;
	}

	/**
	 * Show details for metaphone value
	 *
	 * @param	integer		Metaphone integer hash
	 * @return	string		HTML content
	 */
	function showDetailsForMetaphone($metaphone)	{

			// Finding top-20 on frequency for this phash:
		$ftrows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
					'index_words.*',
					'index_words',
					'index_words.metaphone = '.intval($metaphone),
					'',
					'index_words.baseword',
					''
				);

		if (count($ftrows))	{
			$content.='<h4>Metaphone: '.$this->indexerObj->metaphone($ftrows[0]['baseword'],1).'</h4>';

			$content.='
				<tr class="tableheader bgColor5">
					<td>Word</td>
					<td>Is stopword?</td>
				</tr>';

			if (is_array($ftrows))	{
				foreach($ftrows as $wDat)	{
					$content.='
						<tr class="bgColor4">
							<td>'.$this->linkWordDetails(htmlspecialchars($wDat['baseword']),$wDat['wid']).'</td>
							<td>'.htmlspecialchars($wDat['is_stopword'] ? 'YES' : 'No').'</td>
						</tr>';
				}
			}

			$content = '
				<table border="0" cellspacing="1" cellpadding="2" class="c-list">'.
					$content.'
				</table>';

			if ($this->indexerObj->metaphone($ftrows[0]['baseword'])!=$metaphone)	{
				$content.='ERROR: Metaphone string and hash did not match for some reason!?';
			}

				// Add go-back link:
			$content = $content.$this->linkList();
		}

		return $content;
	}












	/*******************************
	 *
	 * Helper functions
	 *
	 *******************************/

	/**
For faster browsing, not all history is shown. View entire blame