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