📄 class.tx_indexedsearch.php
字号:
$GLOBALS['TT']->push('Display Final result'); // Set first selected row (for calculation of ranking later) $this->firstRow = $resData['firstRow']; // Result display here: $rowcontent = ''; $rowcontent.= $this->compileResult($resData['resultRows'], $freeIndexUid); // Browsing box: if ($resData['count']) { $this->internal['res_count'] = $resData['count']; $this->internal['results_at_a_time'] = $this->piVars['results']; $this->internal['maxPages'] = t3lib_div::intInRange($this->conf['search.']['page_links'],1,100,10); $addString = ($resData['count']&&$this->piVars['group']=='sections'&&$freeIndexUid<=0 ? ' '.sprintf($this->pi_getLL(count($this->resultSections)>1?'inNsections':'inNsection'),count($this->resultSections)):''); $browseBox1 = $this->pi_list_browseresults(1,$addString,$this->printResultSectionLinks(),$freeIndexUid); $browseBox2 = $this->pi_list_browseresults(0,'','',$freeIndexUid); } // Browsing nav, bottom. if ($resData['count']) { $content = $browseBox1.$rowcontent.$browseBox2; } else { $content = '<p'.$this->pi_classParam('noresults').'>'.$this->pi_getLL('noResults','',1).'</p>'; } $GLOBALS['TT']->pull(); } else { $content.='<p'.$this->pi_classParam('noresults').'>'.$this->pi_getLL('noResults','',1).'</p>'; } // Print a message telling which words we searched for, and in which sections etc. $what = $this->tellUsWhatIsSeachedFor($sWArr). (substr($this->piVars['sections'],0,2)=='rl'?' '.$this->pi_getLL('inSection','',1).' "'.substr($this->getPathFromPageId(substr($this->piVars['sections'],4)),1).'"':''); $what = '<div'.$this->pi_classParam('whatis').'>'.$this->cObj->stdWrap($what, $this->conf['whatis_stdWrap.']).'</div>'; $content = $what.$content; // Return content: return $content; } /** * Takes the array with resultrows as input and returns the result-HTML-code * Takes the "group" var into account: Makes a "section" or "flat" display. * * @param array Result rows * @param integer Pointer to which indexing configuration you want to search in. -1 means no filtering. 0 means only regular indexed content. * @return string HTML */ function compileResult($resultRows, $freeIndexUid=-1) { $content = ''; // Transfer result rows to new variable, performing some mapping of sub-results etc. $newResultRows = array(); foreach ($resultRows as $row) { $id = md5($row['phash_grouping']); if (is_array($newResultRows[$id])) { if (!$newResultRows[$id]['show_resume'] && $row['show_resume']) { // swapping: // Remove old $subrows = $newResultRows[$id]['_sub']; unset($newResultRows[$id]['_sub']); $subrows[] = $newResultRows[$id]; // Insert new: $newResultRows[$id] = $row; $newResultRows[$id]['_sub'] = $subrows; } else $newResultRows[$id]['_sub'][] = $row; } else { $newResultRows[$id] = $row; } } $resultRows = $newResultRows; $this->resultSections = array(); if ($freeIndexUid<=0) { switch($this->piVars['group']) { case 'sections': $rl2flag = substr($this->piVars['sections'],0,2)=='rl'; $sections = array(); foreach ($resultRows as $row) { $id = $row['rl0'].'-'.$row['rl1'].($rl2flag?'-'.$row['rl2']:''); $sections[$id][] = $row; } $this->resultSections = array(); foreach ($sections as $id => $resultRows) { $rlParts = explode('-',$id); $theId = $rlParts[2] ? $rlParts[2] : ($rlParts[1]?$rlParts[1]:$rlParts[0]); $theRLid = $rlParts[2] ? 'rl2_'.$rlParts[2]:($rlParts[1]?'rl1_'.$rlParts[1]:'0'); $sectionName = $this->getPathFromPageId($theId); if ($sectionName{0} == '/') $sectionName = substr($sectionName,1); if (!trim($sectionName)) { $sectionTitleLinked = $this->pi_getLL('unnamedSection','',1).':'; } else { $onclick = 'document.'.$this->prefixId.'[\''.$this->prefixId.'[_sections]\'].value=\''.$theRLid.'\';document.'.$this->prefixId.'.submit();return false;'; $sectionTitleLinked = '<a href="#" onclick="'.htmlspecialchars($onclick).'">'.htmlspecialchars($sectionName).':</a>'; } $this->resultSections[$id] = array($sectionName,count($resultRows)); // Add content header: $content.= $this->makeSectionHeader($id,$sectionTitleLinked,count($resultRows)); // Render result rows: foreach ($resultRows as $row) { $content.= $this->printResultRow($row); } } break; default: // flat: foreach ($resultRows as $row) { $content.= $this->printResultRow($row); } break; } } else { foreach ($resultRows as $row) { $content.= $this->printResultRow($row); } } return '<div'.$this->pi_classParam('res').'>'.$content.'</div>'; } /*********************************** * * Searching functions (SQL) * ***********************************/ /** * Returns a COMPLETE list of phash-integers matching the search-result composed of the search-words in the sWArr array. * The list of phash integers are unsorted and should be used for subsequent selection of index_phash records for display of the result. * * @param array Search word array * @return string List of integers */ function getPhashList($sWArr) { // Initialize variables: $c=0; $totalHashList = array(); // This array accumulates the phash-values $this->wSelClauses = array(); // Traverse searchwords; for each, select all phash integers and merge/diff/intersect them with previous word (based on operator) foreach ($sWArr as $k => $v) { // Making the query for a single search word based on the search-type $sWord = $v['sword']; // $GLOBALS['TSFE']->csConvObj->conv_case('utf-8',$v['sword'],'toLower'); // lower-case all of them... $theType = (string)$this->piVars['type']; if (strstr($sWord,' ')) $theType = 20; // If there are spaces in the search-word, make a full text search instead. $GLOBALS['TT']->push('SearchWord "'.$sWord.'" - $theType='.$theType); $res = ''; $wSel=''; // Perform search for word: switch($theType) { case '1': // Part of word $wSel = "IW.baseword LIKE '%".$GLOBALS['TYPO3_DB']->quoteStr($sWord, 'index_words')."%'"; $res = $this->execPHashListQuery($wSel,' AND is_stopword=0'); break; case '2': // First part of word $wSel = "IW.baseword LIKE '".$GLOBALS['TYPO3_DB']->quoteStr($sWord, 'index_words')."%'"; $res = $this->execPHashListQuery($wSel,' AND is_stopword=0'); break; case '3': // Last part of word $wSel = "IW.baseword LIKE '%".$GLOBALS['TYPO3_DB']->quoteStr($sWord, 'index_words')."'"; $res = $this->execPHashListQuery($wSel,' AND is_stopword=0'); break; case '10': // Sounds like $wSel = 'IW.metaphone = '.$this->indexerObj->metaphone($sWord); $res = $this->execPHashListQuery($wSel,' AND is_stopword=0'); break; case '20': // Sentence $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 'ISEC.phash', 'index_section ISEC, index_fulltext IFT', 'IFT.fulltextdata LIKE \'%'.$GLOBALS['TYPO3_DB']->quoteStr($sWord, 'index_fulltext').'%\' AND ISEC.phash = IFT.phash '.$this->sectionTableWhere(), 'ISEC.phash' ); $wSel = '1=1'; if ($this->piVars['type']==20) $this->piVars['order'] = 'mtime'; // If there is a fulltext search for a sentence there is a likeliness that sorting cannot be done by the rankings from the rel-table (because no relations will exist for the sentence in the word-table). So therefore mtime is used instaed. It is not required, but otherwise some hits may be left out. break; default: // Distinct word $wSel = 'IW.wid = '.$hash = $this->indexerObj->md5inthash($sWord); $res = $this->execPHashListQuery($wSel,' AND is_stopword=0'); break; } // Accumulate the word-select clauses $this->wSelClauses[] = $wSel; // If there was a query to do, then select all phash-integers which resulted from this. if ($res) { // Get phash list by searching for it: $phashList = array(); while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { $phashList[] = $row['phash']; } $GLOBALS['TYPO3_DB']->sql_free_result($res); // Here the phash list are merged with the existing result based on whether we are dealing with OR, NOT or AND operations. if ($c) { switch($v['oper']) { case 'OR': $totalHashList = array_unique(array_merge($phashList,$totalHashList)); break; case 'AND NOT': $totalHashList = array_diff($totalHashList,$phashList); break; default: // AND... $totalHashList = array_intersect($totalHashList,$phashList); break; } } else { $totalHashList = $phashList; // First search } } $GLOBALS['TT']->pull(); $c++; } return implode(',',$totalHashList); } /** * Returns a query which selects the search-word from the word/rel tables. * * @param string WHERE clause selecting the word from phash * @param string Additional AND clause in the end of the query. * @return pointer SQL result pointer */ function execPHashListQuery($wordSel,$plusQ='') { return $GLOBALS['TYPO3_DB']->exec_SELECTquery( 'IR.phash', 'index_words IW, index_rel IR, index_section ISEC', $wordSel.' AND IW.wid=IR.wid AND ISEC.phash = IR.phash '.$this->sectionTableWhere().' '.$plusQ, 'IR.phash' ); } /** * Returns AND statement for selection of section in database. (rootlevel 0-2 + page_id) * * @return string AND clause for selection of section in database. */ function sectionTableWhere() { $out = $this->wholeSiteIdList<0 ? '' : 'AND ISEC.rl0 IN ('.$this->wholeSiteIdList.')'; $match = ''; if (substr($this->piVars['sections'],0,4)=='rl1_') { $list = implode(',',t3lib_div::intExplode(',',substr($this->piVars['sections'],4))); $out.= 'AND ISEC.rl1 IN ('.$list.')'; $match = TRUE; } elseif (substr($this->piVars['sections'],0,4)=='rl2_') { $list = implode(',',t3lib_div::intExplode(',',substr($this->piVars['sections'],4))); $out.= 'AND ISEC.rl2 IN ('.$list.')'; $match = TRUE; } elseif (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['addRootLineFields'])) { // Traversing user configured fields to see if any of those are used to limit search to a section: foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['addRootLineFields'] as $fieldName => $rootLineLevel) { if (substr($this->piVars['sections'],0,strlen($fieldName)+1)==$fieldName.'_') { $list = implode(',',t3lib_div::intExplode(',',substr($this->piVars['sections'],strlen($fieldName)+1))); $out.= 'AND ISEC.'.$fieldName.' IN ('.$list.')'; $match = TRUE; break; } } } // If no match above, test the static types: if (!$match) { switch((string)$this->piVars['sections']) { case '-1': // '-1' => 'Only this page', $out.= ' AND ISEC.page_id='.$GLOBALS['TSFE']->id; break; case '-2': // '-2' => 'Top + level 1', $out.= ' AND ISEC.rl2=0'; break; case '-3': // '-3' => 'Level 2 and out', $out.= ' AND ISEC.rl2>0'; break; } } return $out; } /** * Returns AND statement for selection of media type * * @return string AND statement for selection of media type */ function mediaTypeWhere() { switch((string)$this->piVars['media']) { case '0': // '0' => 'Kun TYPO3 sider', $out = 'AND IP.item_type='.$GLOBALS['TYPO3_DB']->fullQuoteStr('0', 'index_phash');; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -