private function searchTextReal($term, SearchConfig $config = null) { global $wgCirrusSearchInterwikiSources; // Convert the unicode character 'idiographic whitespace' into standard // whitespace. Cirrussearch treats them both as normal whitespace, but // the preceding isn't appropriatly trimmed. $term = trim(str_replace(" ", " ", $term)); // No searching for nothing! That takes forever! if (!$term) { return null; } $context = RequestContext::getMain(); $request = $context->getRequest(); $user = $context->getUser(); if ($config) { $this->indexBaseName = $config->getWikiId(); } $searcher = new Searcher($this->connection, $this->offset, $this->limit, $config, $this->namespaces, $user, $this->indexBaseName); // Ignore leading ~ because it is used to force displaying search results but not to effect them if (substr($term, 0, 1) === '~') { $term = substr($term, 1); $searcher->addSuggestPrefix('~'); } // TODO remove this when we no longer have to support core versions without // Ie946150c6796139201221dfa6f7750c210e97166 if (method_exists($this, 'getSort')) { $searcher->setSort($this->getSort()); } $dumpQuery = $request && $request->getVal('cirrusDumpQuery') !== null; $searcher->setReturnQuery($dumpQuery); $dumpResult = $request && $request->getVal('cirrusDumpResult') !== null; $searcher->setDumpResult($dumpResult); $returnExplain = $request && $request->getVal('cirrusExplain') !== null; $searcher->setReturnExplain($returnExplain); // Delegate to either searchText or moreLikeThisArticle and dump the result into $status if (substr($term, 0, strlen(self::MORE_LIKE_THIS_PREFIX)) === self::MORE_LIKE_THIS_PREFIX) { $term = substr($term, strlen(self::MORE_LIKE_THIS_PREFIX)); $status = $this->moreLikeThis($term, $searcher, Searcher::MORE_LIKE_THESE_NONE); } else { if (substr($term, 0, strlen(self::MORE_LIKE_THIS_JUST_WIKIBASE_PREFIX)) === self::MORE_LIKE_THIS_JUST_WIKIBASE_PREFIX) { $term = substr($term, strlen(self::MORE_LIKE_THIS_JUST_WIKIBASE_PREFIX)); $status = $this->moreLikeThis($term, $searcher, Searcher::MORE_LIKE_THESE_ONLY_WIKIBASE); } else { # Namespace lookup should not be done for morelike special syntax (T111244) if ($this->lastNamespacePrefix) { $searcher->addSuggestPrefix($this->lastNamespacePrefix); } else { $searcher->updateNamespacesFromQuery($term); } $highlightingConfig = FullTextResultsType::HIGHLIGHT_ALL; if ($request) { if ($request->getVal('cirrusSuppressSuggest') !== null) { $this->showSuggestion = false; } if ($request->getVal('cirrusSuppressTitleHighlight') !== null) { $highlightingConfig ^= FullTextResultsType::HIGHLIGHT_TITLE; } if ($request->getVal('cirrusSuppressAltTitle') !== null) { $highlightingConfig ^= FullTextResultsType::HIGHLIGHT_ALT_TITLE; } if ($request->getVal('cirrusSuppressSnippet') !== null) { $highlightingConfig ^= FullTextResultsType::HIGHLIGHT_SNIPPET; } if ($request->getVal('cirrusHighlightDefaultSimilarity') === 'no') { $highlightingConfig ^= FullTextResultsType::HIGHLIGHT_WITH_DEFAULT_SIMILARITY; } if ($request->getVal('cirrusHighlightAltTitleWithPostings') === 'no') { $highlightingConfig ^= FullTextResultsType::HIGHLIGHT_ALT_TITLES_WITH_POSTINGS; } } if ($this->namespaces && !in_array(NS_FILE, $this->namespaces)) { $highlightingConfig ^= FullTextResultsType::HIGHLIGHT_FILE_TEXT; } $searcher->setResultsType(new FullTextResultsType($highlightingConfig, $config ? $config->getWikiCode() : '')); $status = $searcher->searchText($term, $this->showSuggestion); } } if ($dumpQuery || $dumpResult) { // When dumping the query we skip _everything_ but echoing the query. $context->getOutput()->disable(); $request->response()->header('Content-type: application/json; charset=UTF-8'); if ($status->getValue() === null) { echo '{}'; } else { echo json_encode($status->getValue()); } exit; } $this->lastSearchMetrics = $searcher->getSearchMetrics(); // Add interwiki results, if we have a sane result // Note that we have no way of sending warning back to the user. In this case all warnings // are logged when they are added to the status object so we just ignore them here.... if ($status->isOK() && $wgCirrusSearchInterwikiSources && $status->getValue() && method_exists($status->getValue(), 'addInterwikiResults')) { // @todo @fixme: This should absolutely be a multisearch. I knew this when I // wrote the code but Searcher needs some refactoring first. foreach ($wgCirrusSearchInterwikiSources as $interwiki => $index) { $iwSearch = new InterwikiSearcher($this->connection, $this->namespaces, $user, $index, $interwiki); $interwikiResult = $iwSearch->getInterwikiResults($term); if ($interwikiResult) { $status->getValue()->addInterwikiResults($interwikiResult); } } } // For historical reasons all callers of searchText interpret any Status return as an error // so we must unwrap all OK statuses. Note that $status can be "good" and still contain null // since that is interpreted as no results. return $status->isOk() ? $status->getValue() : $status; }
/** * Set interwiki and interwikiNamespace properties * @param \Elastica\Result $result containing the given search result * @param string $interwiki Interwiki prefix, if any */ private function setInterwiki($result, $interwiki) { $resultIndex = $result->getIndex(); $indexBase = InterwikiSearcher::getIndexForInterwiki($interwiki); $pos = strpos($resultIndex, $indexBase); if ($pos === 0 && $resultIndex[strlen($indexBase)] == '_') { $this->interwiki = $interwiki; $this->interwikiNamespace = $result->namespace_text ? $result->namespace_text : ''; } }