00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00106 require_once(PATH_tslib.'class.tslib_pibase.php');
00107 require_once(PATH_tslib.'class.tslib_search.php');
00108 require_once(t3lib_extMgm::extPath('indexed_search').'class.indexer.php');
00109
00110
00121 class tx_indexedsearch extends tslib_pibase {
00122 var $prefixId = 'tx_indexedsearch';
00123 var $scriptRelPath = 'pi/class.tx_indexedsearch.php';
00124 var $extKey = 'indexed_search';
00125
00126 var $join_pages = 0;
00127 var $defaultResultNumber = 20;
00128
00129 var $operator_translate_table = Array (
00130 Array ('+' , 'AND'),
00131 Array ('|' , 'OR'),
00132 Array ('-' , 'AND NOT'),
00133
00134 # Array ('AND' , 'AND'),
00135 # Array ('OR' , 'OR'),
00136 # Array ('NOT' , 'AND NOT'),
00137 );
00138
00139
00140 var $wholeSiteIdList = 0;
00141
00142
00143 var $sWArr = array();
00144 var $optValues = array();
00145 var $firstRow = Array();
00146
00147 var $cache_path = array();
00148 var $cache_rl = array();
00149 var $fe_groups_required = array();
00150 var $domain_records = array();
00151 var $wSelClauses = array();
00152 var $resultSections = array();
00153 var $external_parsers = array();
00154 var $iconFileNameCache = array();
00155 var $lexerObj;
00156
00157
00165 function main($content, $conf) {
00166
00167
00168 $this->conf = $conf;
00169 $this->pi_loadLL();
00170 $this->pi_setPiVarDefaults();
00171
00172
00173 $this->indexerObj = t3lib_div::makeInstance('tx_indexedsearch_indexer');
00174
00175
00176 $this->initialize();
00177
00178
00179
00180 if (is_array($this->sWArr)) {
00181 $content = $this->doSearch($this->sWArr);
00182 }
00183
00184
00185 $content=
00186 $this->makeSearchForm($this->optValues).
00187 $this->printRules().
00188 $content;
00189
00190 return $this->pi_wrapInBaseClass($content);
00191 }
00192
00198 function initialize() {
00199 global $TYPO3_CONF_VARS;
00200
00201
00202 if (is_array($TYPO3_CONF_VARS['EXTCONF']['indexed_search']['external_parsers'])) {
00203 foreach($TYPO3_CONF_VARS['EXTCONF']['indexed_search']['external_parsers'] as $extension => $_objRef) {
00204 $this->external_parsers[$extension] = &t3lib_div::getUserObj($_objRef);
00205
00206
00207 if (!$this->external_parsers[$extension]->softInit($extension)) {
00208 unset($this->external_parsers[$extension]);
00209 }
00210 }
00211 }
00212
00213
00214 $lexerObjRef = $TYPO3_CONF_VARS['EXTCONF']['indexed_search']['lexer'] ?
00215 $TYPO3_CONF_VARS['EXTCONF']['indexed_search']['lexer'] :
00216 'EXT:indexed_search/class.lexer.php:&tx_indexedsearch_lexer';
00217 $this->lexerObj = &t3lib_div::getUserObj($lexerObjRef);
00218
00219
00220 if ($this->piVars['_sections']) $this->piVars['sections'] = $this->piVars['_sections'];
00221
00222
00223 if ($this->piVars['sword_prev_include'] && $this->piVars['sword_prev']) {
00224 $this->piVars['sword'] = trim($this->piVars['sword_prev']).' '.$this->piVars['sword'];
00225 }
00226
00227 $this->piVars['results'] = t3lib_div::intInRange($this->piVars['results'],1,100000,$this->defaultResultNumber);
00228
00229
00230 $this->optValues = Array(
00231 'type' => Array(
00232 '0' => $this->pi_getLL('opt_type_0'),
00233 '1' => $this->pi_getLL('opt_type_1'),
00234 '2' => $this->pi_getLL('opt_type_2'),
00235 '3' => $this->pi_getLL('opt_type_3'),
00236 '10' => $this->pi_getLL('opt_type_10'),
00237 '20' => $this->pi_getLL('opt_type_20'),
00238 ),
00239 'defOp' => Array(
00240 '0' => $this->pi_getLL('opt_defOp_0'),
00241 '1' => $this->pi_getLL('opt_defOp_1'),
00242 ),
00243 'sections' => Array(
00244 '0' => $this->pi_getLL('opt_sections_0'),
00245 '-1' => $this->pi_getLL('opt_sections_-1'),
00246 '-2' => $this->pi_getLL('opt_sections_-2'),
00247 '-3' => $this->pi_getLL('opt_sections_-3'),
00248
00249 ),
00250 'media' => Array(
00251 '-1' => $this->pi_getLL('opt_media_-1'),
00252 '0' => $this->pi_getLL('opt_media_0'),
00253 '-2' => $this->pi_getLL('opt_media_-2'),
00254 ),
00255 'order' => Array(
00256 'rank_flag' => $this->pi_getLL('opt_order_rank_flag'),
00257 'rank_freq' => $this->pi_getLL('opt_order_rank_freq'),
00258 'rank_first' => $this->pi_getLL('opt_order_rank_first'),
00259 'rank_count' => $this->pi_getLL('opt_order_rank_count'),
00260 'mtime' => $this->pi_getLL('opt_order_mtime'),
00261 'title' => $this->pi_getLL('opt_order_title'),
00262 'crdate' => $this->pi_getLL('opt_order_crdate'),
00263 ),
00264 'group' => Array (
00265 'sections' => $this->pi_getLL('opt_group_sections'),
00266 'flat' => $this->pi_getLL('opt_group_flat'),
00267 ),
00268 'lang' => Array (
00269 -1 => $this->pi_getLL('opt_lang_-1'),
00270 0 => $this->pi_getLL('opt_lang_0'),
00271 ),
00272 'desc' => Array (
00273 '0' => $this->pi_getLL('opt_desc_0'),
00274 '1' => $this->pi_getLL('opt_desc_1'),
00275 ),
00276 'results' => Array (
00277 '10' => '10',
00278 '20' => '20',
00279 '50' => '50',
00280 '100' => '100',
00281 )
00282 );
00283
00284
00285 foreach($this->external_parsers as $extension => $obj) {
00286 if ($name = $obj->searchTypeMediaTitle($extension)) {
00287 $this->optValues['media'][$extension] = $this->pi_getLL('opt_sections_'.$extension,$name);
00288 }
00289 }
00290
00291
00292
00293 $this->operator_translate_table[] = Array($GLOBALS['TSFE']->csConvObj->conv_case('utf-8',$GLOBALS['TSFE']->csConvObj->utf8_encode($this->pi_getLL('local_operator_AND'), $GLOBALS['TSFE']->renderCharset),'toLower') , 'AND');
00294 $this->operator_translate_table[] = Array($GLOBALS['TSFE']->csConvObj->conv_case('utf-8',$GLOBALS['TSFE']->csConvObj->utf8_encode($this->pi_getLL('local_operator_OR'), $GLOBALS['TSFE']->renderCharset),'toLower') , 'OR');
00295 $this->operator_translate_table[] = Array($GLOBALS['TSFE']->csConvObj->conv_case('utf-8',$GLOBALS['TSFE']->csConvObj->utf8_encode($this->pi_getLL('local_operator_NOT'), $GLOBALS['TSFE']->renderCharset),'toLower') , 'AND NOT');
00296
00297
00298 $this->wholeSiteIdList = intval($GLOBALS['TSFE']->config['rootLine'][0]['uid']);
00299
00300
00301
00302 if ($this->conf['show.']['L1sections']) {
00303 $firstLevelMenu = $this->getMenu($this->wholeSiteIdList);
00304 while(list($kk,$mR) = each($firstLevelMenu)) {
00305 if ($mR['doktype']!=5) {
00306 $this->optValues['sections']['rl1_'.$mR['uid']] = trim($this->pi_getLL('opt_RL1').' '.$mR['title']);
00307 if ($this->conf['show.']['L2sections']) {
00308 $secondLevelMenu = $this->getMenu($mR['uid']);
00309 while(list($kk2,$mR2) = each($secondLevelMenu)) {
00310 if ($mR['doktype']!=5) {
00311 $this->optValues['sections']['rl2_'.$mR2['uid']] = trim($this->pi_getLL('opt_RL2').' '.$mR2['title']);
00312 } else unset($secondLevelMenu[$kk2]);
00313 }
00314 $this->optValues['sections']['rl2_'.implode(',',array_keys($secondLevelMenu))] = $this->pi_getLL('opt_RL2ALL');
00315 }
00316 } else unset($firstLevelMenu[$kk]);
00317 }
00318 $this->optValues['sections']['rl1_'.implode(',',array_keys($firstLevelMenu))] = $this->pi_getLL('opt_RL1ALL');
00319 }
00320
00321
00322
00323 if ($this->conf['search.']['rootPidList']) {
00324 $this->wholeSiteIdList = implode(',',t3lib_div::intExplode(',',$this->conf['search.']['rootPidList']));
00325 }
00326
00327
00328 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'sys_language', '1=1'.$this->cObj->enableFields('sys_language'));
00329 while($lR = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00330 $this->optValues['lang'][$lR['uid']] = $lR['title'];
00331 }
00332
00333
00334 if ($hookObj = &$this->hookRequest('initialize_postProc')) {
00335 $hookObj->initialize_postProc();
00336 }
00337
00338
00339
00340 foreach($this->optValues as $kk => $vv) {
00341 if (!isset($this->piVars[$kk])) {
00342 reset($vv);
00343 $this->piVars[$kk] = key($vv);
00344 }
00345 }
00346
00347
00348 if (is_array($this->conf['blind.'])) {
00349 foreach($this->conf['blind.'] as $kk => $vv) {
00350 if (is_array($vv)) {
00351 foreach($vv as $kkk => $vvv) {
00352 if (!is_array($vvv) && $vvv && is_array($this->optValues[substr($kk,0,-1)])) {
00353 unset($this->optValues[substr($kk,0,-1)][$kkk]);
00354 }
00355 }
00356 } elseif ($vv) {
00357 unset($this->optValues[$kk]);
00358 }
00359 }
00360 }
00361
00362
00363 $this->sWArr = $this->getSearchWords($this->piVars['defOp']);
00364 }
00365
00381 function getSearchWords($defOp) {
00382
00383 $inSW = substr($this->piVars['sword'],0,200);
00384
00385
00386 $inSW = $GLOBALS['TSFE']->csConvObj->utf8_encode($inSW, $GLOBALS['TSFE']->metaCharset);
00387 $inSW = $GLOBALS['TSFE']->csConvObj->entities_to_utf8($inSW,TRUE);
00388
00389 if ($hookObj = &$this->hookRequest('getSearchWords')) {
00390 return $hookObj->getSearchWords_splitSWords($inSW, $defOp);
00391 } else {
00392
00393 if ($this->piVars['type']==20) {
00394 return array(array('sword'=>trim($inSW), 'oper'=>'AND'));
00395 } else {
00396 $search = t3lib_div::makeInstance('tslib_search');
00397 $search->default_operator = $defOp==1 ? 'OR' : 'AND';
00398 $search->operator_translate_table = $this->operator_translate_table;
00399 $search->register_and_explode_search_string($inSW);
00400
00401 if (is_array($search->sword_array)) {
00402 return $this->procSearchWordsByLexer($search->sword_array);
00403 }
00404 }
00405 }
00406 }
00407
00415 function procSearchWordsByLexer($SWArr) {
00416
00417
00418 $newSWArr = array();
00419
00420
00421 foreach($SWArr as $wordDef) {
00422 if (!strstr($wordDef['sword'],' ')) {
00423
00424 $res = $this->lexerObj->split2Words($wordDef['sword']);
00425
00426
00427 foreach($res as $word) {
00428 $newSWArr[] = array('sword'=>$word, 'oper'=>$wordDef['oper']);
00429 }
00430 } else {
00431 $newSWArr[] = $wordDef;
00432 }
00433 }
00434
00435
00436 return $newSWArr;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00459 function doSearch($sWArr) {
00460
00461
00462 $pt1 = t3lib_div::milliseconds();
00463 if ($hookObj = &$this->hookRequest('getResultRows')) {
00464 $resData = $hookObj->getResultRows($sWArr);
00465 } else {
00466 $resData = $this->getResultRows($sWArr);
00467 }
00468
00469
00470 $pt2 = t3lib_div::milliseconds();
00471 if ($hookObj = &$this->hookRequest('getDisplayResults')) {
00472 $content = $hookObj->getDisplayResults($sWArr, $resData);
00473 } else {
00474 $content = $this->getDisplayResults($sWArr, $resData);
00475 }
00476
00477 $pt3 = t3lib_div::milliseconds();
00478
00479
00480 $this->writeSearchStat($sWArr,$resData['count'],array($pt1,$pt2,$pt3));
00481
00482
00483 return $content;
00484 }
00485
00492 function getResultRows($sWArr) {
00493
00494
00495 $GLOBALS['TT']->push('Searching result');
00496 $res = $this->getResultRows_SQLpointer($sWArr);
00497 $GLOBALS['TT']->pull();
00498
00499
00500 if ($res) {
00501
00502
00503 $count = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
00504 $pointer = t3lib_div::intInRange($this->piVars['pointer'],0,floor($count/$this->piVars['results']));
00505
00506
00507 $c = 0;
00508 $lines = Array();
00509 $grouping_phashes = array();
00510 $grouping_chashes = array();
00511 $firstRow = Array();
00512 $resultRows = Array();
00513
00514
00515
00516 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00517
00518
00519 if (!$c) {
00520 $firstRow = $row;
00521 }
00522
00523 $row['show_resume'] = $this->checkResume($row);
00524 $phashGr = !in_array($row['phash_grouping'], $grouping_phashes);
00525 $chashGr = !in_array($row['contentHash'].'.'.$row['data_page_id'], $grouping_chashes);
00526 if ($phashGr && $chashGr) {
00527 if ($row['show_resume']) {
00528 if (!$this->multiplePagesType($row['item_type'])) {
00529 $grouping_phashes[] = $row['phash_grouping'];
00530 }
00531 $grouping_chashes[] = $row['contentHash'].'.'.$row['data_page_id'];
00532 }
00533 $c++;
00534
00535
00536 if ($c > $pointer * $this->piVars['results']) {
00537 $row['result_number'] = $c;
00538 $resultRows[] = $row;
00539 if ($c+1 > ($pointer+1)*$this->piVars['results']) break;
00540 }
00541 } else {
00542 $count--;
00543 }
00544 }
00545
00546 return array(
00547 'resultRows' => $resultRows,
00548 'firstRow' => $firstRow,
00549 'count' => $count
00550 );
00551 } else {
00552 return FALSE;
00553 }
00554 }
00555
00562 function getResultRows_SQLpointer($sWArr) {
00563
00564 $list = $this->getPhashList($sWArr);
00565
00566
00567 if ($list) {
00568
00569 return $this->execFinalQuery($list);
00570 } else {
00571 return FALSE;
00572 }
00573 }
00574
00582 function getDisplayResults($sWArr, $resData) {
00583
00584 if ($resData) {
00585 $GLOBALS['TT']->push('Display Final result');
00586
00587
00588 $this->firstRow = $resData['firstRow'];
00589
00590
00591 $rowcontent = '';
00592 $rowcontent.= $this->compileResult($resData['resultRows']);
00593
00594
00595 if ($resData['count']) {
00596 $this->internal['res_count'] = $resData['count'];
00597 $this->internal['results_at_a_time'] = $this->piVars['results'];
00598 $this->internal['maxPages'] = t3lib_div::intInRange($this->conf['search.']['page_links'],1,100,10);
00599 $addString = ($resData['count']&&$this->piVars['group']=='sections' ? ' '.sprintf($this->pi_getLL(count($this->resultSections)>1?'inNsections':'inNsection'),count($this->resultSections)):'');
00600 $browseBox1 = $this->pi_list_browseresults(1,$addString,$this->printResultSectionLinks());
00601 $browseBox2 = $this->pi_list_browseresults(0);
00602 }
00603
00604
00605 if ($resData['count']) {
00606 $content = $browseBox1.$rowcontent.$browseBox2;
00607 } else {
00608 $content = '<p'.$this->pi_classParam('noresults').'>'.$this->pi_getLL('noResults','',1).'</p>';
00609 }
00610
00611 $GLOBALS['TT']->pull();
00612 } else {
00613 $content.='<p'.$this->pi_classParam('noresults').'>'.$this->pi_getLL('noResults','',1).'</p>';
00614 }
00615
00616
00617 $what = $this->tellUsWhatIsSeachedFor($sWArr).
00618 (substr($this->piVars['sections'],0,2)=='rl'?' '.$this->pi_getLL('inSection','',1).' "'.substr($this->getPathFromPageId(substr($this->piVars['sections'],4)),1).'"':'');
00619 $what = '<div'.$this->pi_classParam('whatis').'><p>'.$what.'</p></div>';
00620 $content = $what.$content;
00621
00622
00623 return $content;
00624 }
00625
00633 function compileResult($resultRows) {
00634 $content = '';
00635
00636
00637 $newResultRows = array();
00638 foreach($resultRows as $row) {
00639 $id = md5($row['phash_grouping']);
00640 if (is_array($newResultRows[$id])) {
00641 if (!$newResultRows[$id]['show_resume'] && $row['show_resume']) {
00642
00643
00644 $subrows = $newResultRows[$id]['_sub'];
00645 unset($newResultRows[$id]['_sub']);
00646 $subrows[] = $newResultRows[$id];
00647
00648
00649 $newResultRows[$id] = $row;
00650 $newResultRows[$id]['_sub'] = $subrows;
00651 } else $newResultRows[$id]['_sub'][] = $row;
00652 } else {
00653 $newResultRows[$id] = $row;
00654 }
00655 }
00656 $resultRows = $newResultRows;
00657
00658
00659 switch($this->piVars['group']) {
00660 case 'sections':
00661
00662 $rl2flag = substr($this->piVars['sections'],0,2)=='rl';
00663 $sections = array();
00664 foreach($resultRows as $row) {
00665 $id = $row['rl0'].'-'.$row['rl1'].($rl2flag?'-'.$row['rl2']:'');
00666 $sections[$id][] = $row;
00667 }
00668
00669 $this->resultSections = array();
00670
00671 foreach($sections as $id => $resultRows) {
00672 $rlParts = explode('-',$id);
00673 $theId = $rlParts[2] ? $rlParts[2] : ($rlParts[1]?$rlParts[1]:$rlParts[0]);
00674 $theRLid = $rlParts[2] ? 'rl2_'.$rlParts[2]:($rlParts[1]?'rl1_'.$rlParts[1]:'0');
00675
00676 $sectionName = substr($this->getPathFromPageId($theId),1);
00677 if (!trim($sectionName)) {
00678 $sectionTitleLinked = $this->pi_getLL('unnamedSection','',1).':';
00679 } else {
00680 $onclick = 'document.'.$this->prefixId.'[\''.$this->prefixId.'[_sections]\'].value=\''.$theRLid.'\';document.'.$this->prefixId.'.submit();return false;';
00681 $sectionTitleLinked = '<a href="#" onclick="'.htmlspecialchars($onclick).'">'.htmlspecialchars($sectionName).':</a>';
00682 }
00683 $this->resultSections[$id] = array($sectionName,count($resultRows));
00684
00685
00686 $content.= $this->makeSectionHeader($id,$sectionTitleLinked,count($resultRows));
00687
00688
00689 foreach($resultRows as $row) {
00690 $content.= $this->printResultRow($row);
00691 }
00692 }
00693 break;
00694 default:
00695 foreach($resultRows as $row) {
00696 $content.= $this->printResultRow($row);
00697 }
00698 break;
00699 }
00700 return '<div'.$this->pi_classParam('res').'>'.$content.'</div>';
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00726 function getPhashList($sWArr) {
00727
00728
00729 $c=0;
00730 $totalHashList = array();
00731 $this->wSelClauses = array();
00732
00733
00734 foreach($sWArr as $k => $v) {
00735 $GLOBALS['TT']->push('SearchWord '.$sWord);
00736
00737
00738 $sWord = $v['sword'];
00739
00740 $theType = (string)$this->piVars['type'];
00741 if (strstr($sWord,' ')) $theType = 20;
00742 $res = '';
00743 $wSel='';
00744
00745
00746 switch($theType) {
00747 case '1':
00748 $wSel = "IW.baseword LIKE '%".$GLOBALS['TYPO3_DB']->quoteStr($sWord, 'index_words')."%'";
00749 $res = $this->execPHashListQuery($wSel,' AND is_stopword=0');
00750 break;
00751 case '2':
00752 $wSel = "IW.baseword LIKE '".$GLOBALS['TYPO3_DB']->quoteStr($sWord, 'index_words')."%'";
00753 $res = $this->execPHashListQuery($wSel,' AND is_stopword=0');
00754 break;
00755 case '3':
00756 $wSel = "IW.baseword LIKE '%".$GLOBALS['TYPO3_DB']->quoteStr($sWord, 'index_words')."'";
00757 $res = $this->execPHashListQuery($wSel,' AND is_stopword=0');
00758 break;
00759 case '10':
00760 $wSel = 'IW.metaphone = '.$this->indexerObj->metaphone($sWord);
00761 $res = $this->execPHashListQuery($wSel,' AND is_stopword=0');
00762 break;
00763 case '20':
00764 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00765 'ISEC.phash',
00766 'index_section ISEC, index_fulltext IFT',
00767 'IFT.fulltextdata LIKE \'%'.$GLOBALS['TYPO3_DB']->quoteStr($sWord, 'index_fulltext').'%\' AND
00768 ISEC.phash = IFT.phash
00769 '.$this->sectionTableWhere(),
00770 'ISEC.phash'
00771 );
00772 $wSel = '1=1';
00773
00774 if ($this->piVars['type']==20) $this->piVars['order'] = 'mtime';
00775 break;
00776 default:
00777 $wSel = 'IW.wid = '.$hash = $this->indexerObj->md5inthash($sWord);
00778 $res = $this->execPHashListQuery($wSel,' AND is_stopword=0');
00779 break;
00780 }
00781
00782
00783 $this->wSelClauses[] = $wSel;
00784
00785
00786 if ($res) {
00787
00788
00789 $phashList = array();
00790 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00791 $phashList[] = $row['phash'];
00792 }
00793 $GLOBALS['TYPO3_DB']->sql_free_result($res);
00794
00795
00796 if ($c) {
00797 switch($v['oper']) {
00798 case 'OR':
00799 $totalHashList = array_unique(array_merge($phashList,$totalHashList));
00800 break;
00801 case 'AND NOT':
00802 $totalHashList = array_diff($totalHashList,$phashList);
00803 break;
00804 default:
00805 $totalHashList = array_intersect($totalHashList,$phashList);
00806 break;
00807 }
00808 } else {
00809 $totalHashList = $phashList;
00810 }
00811 }
00812
00813 $GLOBALS['TT']->pull();
00814 $c++;
00815 }
00816
00817 return implode(',',$totalHashList);
00818 }
00819
00827 function execPHashListQuery($wordSel,$plusQ='') {
00828 return $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00829 'IR.phash',
00830 'index_words IW,
00831 index_rel IR,
00832 index_section ISEC',
00833 $wordSel.'
00834 AND IW.wid=IR.wid
00835 AND ISEC.phash = IR.phash
00836 '.$this->sectionTableWhere().'
00837 '.$plusQ,
00838 'IR.phash'
00839 );
00840 }
00841
00847 function sectionTableWhere() {
00848 $out = $this->wholeSiteIdList<0 ? '' : 'AND ISEC.rl0 IN ('.$this->wholeSiteIdList.')';
00849
00850 $match = '';
00851 if (substr($this->piVars['sections'],0,4)=='rl1_') {
00852 $list = implode(',',t3lib_div::intExplode(',',substr($this->piVars['sections'],4)));
00853 $out.= 'AND ISEC.rl1 IN ('.$list.')';
00854 $match = TRUE;
00855 } elseif (substr($this->piVars['sections'],0,4)=='rl2_') {
00856 $list = implode(',',t3lib_div::intExplode(',',substr($this->piVars['sections'],4)));
00857 $out.= 'AND ISEC.rl2 IN ('.$list.')';
00858 $match = TRUE;
00859 } elseif (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['addRootLineFields'])) {
00860
00861 foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['addRootLineFields'] as $fieldName => $rootLineLevel) {
00862 if (substr($this->piVars['sections'],0,strlen($fieldName)+1)==$fieldName.'_') {
00863 $list = implode(',',t3lib_div::intExplode(',',substr($this->piVars['sections'],strlen($fieldName)+1)));
00864 $out.= 'AND ISEC.'.$fieldName.' IN ('.$list.')';
00865 $match = TRUE;
00866 break;
00867 }
00868 }
00869 }
00870
00871
00872 if (!$match) {
00873 switch((string)$this->piVars['sections']) {
00874 case '-1':
00875 $out.= ' AND ISEC.page_id='.$GLOBALS['TSFE']->id;
00876 break;
00877 case '-2':
00878 $out.= ' AND ISEC.rl2=0';
00879 break;
00880 case '-3':
00881 $out.= ' AND ISEC.rl2>0';
00882 break;
00883 }
00884 }
00885
00886 return $out;
00887 }
00888
00894 function mediaTypeWhere() {
00895
00896 switch((string)$this->piVars['media']) {
00897 case '0':
00898 $out = 'AND IP.item_type='.$GLOBALS['TYPO3_DB']->fullQuoteStr('0', 'index_phash');;
00899 break;
00900 case '-2':
00901 $out = 'AND IP.item_type!='.$GLOBALS['TYPO3_DB']->fullQuoteStr('0', 'index_phash');;
00902 break;
00903 case '-1':
00904 $out='';
00905 break;
00906 default:
00907 $out = 'AND IP.item_type='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->piVars['media'], 'index_phash');
00908 break;
00909 }
00910
00911 return $out;
00912 }
00913
00919 function languageWhere() {
00920 if ($this->piVars['lang']>=0) {
00921 return 'AND IP.sys_language_uid='.intval($this->piVars['lang']);
00922 }
00923 }
00924
00931 function execFinalQuery($list) {
00932
00933
00934 $page_join = '';
00935 $page_where = '';
00936
00937
00938 if ($hookObj = &$this->hookRequest('execFinalQuery_idList')) {
00939 $page_where = $hookObj->execFinalQuery_idList($list);
00940 } elseif ($this->join_pages) {
00941 $page_join = ',
00942 pages';
00943 $page_where = 'pages.uid = ISEC.page_id
00944 '.$this->cObj->enableFields('pages').'
00945 AND pages.no_search=0
00946 AND pages.doktype<200
00947 ';
00948 } elseif ($this->wholeSiteIdList>=0) {
00949 $siteIdNumbers = t3lib_div::intExplode(',',$this->wholeSiteIdList);
00950 $id_list=array();
00951 while(list(,$rootId)=each($siteIdNumbers)) {
00952 $id_list[] = $this->cObj->getTreeList($rootId,9999,0,0,'','').$rootId;
00953 }
00954 $page_where = 'ISEC.page_id IN ('.implode(',',$id_list).')';
00955 } else {
00956 $page_where = ' 1=1 ';
00957 }
00958
00959
00960
00961 if (substr($this->piVars['order'],0,5)=='rank_') {
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991 switch($this->piVars['order']) {
00992 case 'rank_flag':
00993
00994 $grsel = 'MAX(IR.flags) AS order_val1, SUM(IR.freq) AS order_val2';
00995 $orderBy = 'order_val1'.$this->isDescending().',order_val2'.$this->isDescending();
00996 break;
00997 case 'rank_first':
00998 $grsel = 'AVG(IR.first) AS order_val';
00999 $orderBy = 'order_val'.$this->isDescending(1);
01000 break;
01001 case 'rank_count':
01002 $grsel = 'SUM(IR.count) AS order_val';
01003 $orderBy = 'order_val'.$this->isDescending();
01004 break;
01005 default:
01006 $grsel = 'SUM(IR.freq) AS order_val';
01007 $orderBy = 'order_val'.$this->isDescending();
01008 break;
01009 }
01010
01011
01012 $wordSel='('.implode(' OR ',$this->wSelClauses).') AND ';
01013
01014 return $GLOBALS['TYPO3_DB']->exec_SELECTquery(
01015 'ISEC.*, IP.*, '
01016 .$grsel,
01017 'index_words IW,
01018 index_rel IR,
01019 index_section ISEC,
01020 index_phash IP'.
01021 $page_join,
01022 $wordSel.'
01023 IP.phash IN ('.$list.') '.
01024 $this->mediaTypeWhere().' '.
01025 $this->languageWhere().'
01026 AND IW.wid=IR.wid
01027 AND ISEC.phash = IR.phash
01028 AND IP.phash = IR.phash
01029 AND '.$page_where,
01030 'IP.phash,ISEC.phash,ISEC.phash_t3,ISEC.rl0,ISEC.rl1,ISEC.rl2 ,ISEC.page_id,ISEC.uniqid,IP.phash_grouping,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,IP.cHashParams,IP.externalUrl,IP.recordUid,IP.freeIndexUid',
01031 $orderBy
01032 );
01033 } else {
01034
01035 $orderBy = '';
01036 switch((string)$this->piVars['order']) {
01037 case 'title':
01038 $orderBy = 'IP.item_title'.$this->isDescending();
01039 break;
01040 case 'crdate':
01041 $orderBy = 'IP.item_crdate'.$this->isDescending();
01042 break;
01043 case 'mtime':
01044 $orderBy = 'IP.item_mtime'.$this->isDescending();
01045 break;
01046 }
01047
01048 return $GLOBALS['TYPO3_DB']->exec_SELECTquery(
01049 'ISEC.*, IP.*',
01050 'index_phash IP,index_section ISEC'.$page_join,
01051 'IP.phash IN ('.$list.') '.
01052 $this->mediaTypeWhere().' '.
01053 $this->languageWhere().'
01054 AND IP.phash = ISEC.phash
01055 AND '.$page_where,
01056 'IP.phash,ISEC.phash,ISEC.phash_t3,ISEC.rl0,ISEC.rl1,ISEC.rl2 ,ISEC.page_id,ISEC.uniqid,IP.phash_grouping,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,IP.cHashParams,IP.externalUrl,IP.recordUid,IP.freeIndexUid',
01057 $orderBy
01058 );
01059 }
01060 }
01061
01069 function checkResume($row) {
01070
01071
01072
01073
01074 if ($row['freeIndexUid']) {
01075 return TRUE;
01076 }
01077
01078
01079 if ($row['item_type']) {
01080
01081
01082
01083
01084 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('phash', 'index_grlist', 'phash='.intval($row['phash_t3']).' AND gr_list='.$GLOBALS['TYPO3_DB']->fullQuoteStr($GLOBALS['TSFE']->gr_list, 'index_grlist'));
01085 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
01086 #debug("Look up for external media '".$row['data_filename']."': phash:".$row['phash_t3'].' YES - ('.$GLOBALS['TSFE']->gr_list.")!",1);
01087 return TRUE;
01088 } else {
01089 #debug("Look up for external media '".$row['data_filename']."': phash:".$row['phash_t3'].' NO - ('.$GLOBALS['TSFE']->gr_list.")!",1);
01090 return FALSE;
01091 }
01092 } else {
01093 if (strcmp($row['gr_list'],$GLOBALS['TSFE']->gr_list)) {
01094
01095 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('phash', 'index_grlist', 'phash='.intval($row['phash']).' AND gr_list='.$GLOBALS['TYPO3_DB']->fullQuoteStr($GLOBALS['TSFE']->gr_list, 'index_grlist'));
01096 if ($GLOBALS['TYPO3_DB']->sql_num_rows($res)) {
01097 #debug('Checking on it ...'.$row['item_title'].'/'.$row['phash'].' - YES ('.$GLOBALS['TSFE']->gr_list.")",1);
01098 return TRUE;
01099 } else {
01100 #debug('Checking on it ...'.$row['item_title'].'/'.$row['phash']." - NOPE",1);
01101 return FALSE;
01102 }
01103 } else {
01104 #debug('Resume can be shown, because the document was in fact indexed by this combination of groups!'.$GLOBALS['TSFE']->gr_list.' - '.$row['item_title'].'/'.$row['phash'],1);
01105 return TRUE;
01106 }
01107 }
01108 }
01109
01116 function isDescending($inverse=FALSE) {
01117 $desc = $this->piVars['desc'];
01118 if ($inverse) $desc=!$desc;
01119 return !$desc ? ' DESC':'';
01120 }
01121
01130 function writeSearchStat($sWArr,$count,$pt) {
01131 $insertFields = array(
01132 'searchstring' => $this->piVars['sword'],
01133 'searchoptions' => serialize(array($this->piVars,$sWArr,$pt)),
01134 'feuser_id' => intval($this->fe_user->user['uid']),
01135 'cookie' => $this->fe_user->id,
01136 'IP' => t3lib_div::getIndpEnv('REMOTE_ADDR'),
01137 'hits' => intval($count),
01138 'tstamp' => $GLOBALS['EXEC_TIME']
01139 );
01140
01141 $GLOBALS['TYPO3_DB']->exec_INSERTquery('index_stat_search', $insertFields);
01142 $newId = $GLOBALS['TYPO3_DB']->sql_insert_id();
01143
01144 if ($newId) {
01145 foreach($sWArr as $val) {
01146 $insertFields = array(
01147 'word' => $val['sword'],
01148 'index_stat_search_id' => $newId,
01149 'tstamp' => $GLOBALS['EXEC_TIME'],
01150 'pageid' => $GLOBALS['TSFE']->id
01151 );
01152
01153 $GLOBALS['TYPO3_DB']->exec_INSERTquery('index_stat_word', $insertFields);
01154 }
01155 }
01156 }
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01182 function makeSearchForm($optValues) {
01183
01184
01185 $rows = array();
01186
01187
01188 $rows[]='<tr>
01189 <td nowrap="nowrap"><p>'.$this->pi_getLL('form_searchFor','',1).' </p></td>
01190 <td><input type="text" name="'.$this->prefixId.'[sword]" value="'.htmlspecialchars($this->conf['show.']['clearSearchBox']?'':$this->piVars['sword']).'"'.$this->pi_classParam('searchbox-sword').' /> <input type="submit" name="'.$this->prefixId.'[submit_button]" value="'.$this->pi_getLL('submit_button_label','',1).'"'.$this->pi_classParam('searchbox-button').' /></td>
01191 </tr>';
01192
01193 if ($this->conf['show.']['clearSearchBox'] && $this->conf['show.']['clearSearchBox.']['enableSubSearchCheckBox']) {
01194 $rows[]='<tr>
01195 <td></td>
01196 <td><input type="hidden" name="'.$this->prefixId.'[sword_prev]" value="'.htmlspecialchars($this->piVars['sword']).'" /><input type="checkbox" name="'.$this->prefixId.'[sword_prev_include]" value="1"'.($this->piVars['sword_prev_include']?' checked="checked"':'').' /> '.$this->pi_getLL('makerating_addToCurrentSearch').'</td>
01197 </tr>';
01198 }
01199
01200
01201 if ($this->piVars['ext']) {
01202 if (is_array($optValues['type']) || is_array($optValues['defOp'])) $rows[]='<tr>
01203 <td nowrap="nowrap"><p>'.$this->pi_getLL('form_match','',1).' </p></td>
01204 <td>'.$this->renderSelectBox($this->prefixId.'[type]',$this->piVars['type'],$optValues['type']).
01205 $this->renderSelectBox($this->prefixId.'[defOp]',$this->piVars['defOp'],$optValues['defOp']).'</td>
01206 </tr>';
01207 if (is_array($optValues['media']) || is_array($optValues['lang'])) $rows[]='<tr>
01208 <td nowrap="nowrap"><p>'.$this->pi_getLL('form_searchIn','',1).' </p></td>
01209 <td>'.$this->renderSelectBox($this->prefixId.'[media]',$this->piVars['media'],$optValues['media']).
01210 $this->renderSelectBox($this->prefixId.'[lang]',$this->piVars['lang'],$optValues['lang']).'</td>
01211 </tr>';
01212 if (is_array($optValues['sections'])) $rows[]='<tr>
01213 <td nowrap="nowrap"><p>'.$this->pi_getLL('form_fromSection','',1).' </p></td>
01214 <td>'.$this->renderSelectBox($this->prefixId.'[sections]',$this->piVars['sections'],$optValues['sections']).'</td>
01215 </tr>';
01216 if (is_array($optValues['order']) || is_array($optValues['desc']) || is_array($optValues['results'])) $rows[]='<tr>
01217 <td nowrap="nowrap"><p>'.$this->pi_getLL('form_orderBy','',1).' </p></td>
01218 <td><p>'.$this->renderSelectBox($this->prefixId.'[order]',$this->piVars['order'],$optValues['order']).
01219 $this->renderSelectBox($this->prefixId.'[desc]',$this->piVars['desc'],$optValues['desc']).
01220 $this->renderSelectBox($this->prefixId.'[results]',$this->piVars['results'],$optValues['results']).' '.$this->pi_getLL('form_atATime','',1).'</p></td>
01221 </tr>';
01222 if (is_array($optValues['group']) || !$this->conf['blind.']['extResume']) $rows[]='<tr>
01223 <td nowrap="nowrap"><p>'.$this->pi_getLL('form_style','',1).' </p></