Пример #1
0
 /**
  * @param ApiPageSet $resultPageSet
  * @return void
  */
 private function run($resultPageSet = null)
 {
     global $wgContLang;
     $params = $this->extractRequestParams();
     // Extract parameters
     $limit = $params['limit'];
     $query = $params['search'];
     $what = $params['what'];
     $interwiki = $params['interwiki'];
     $searchInfo = array_flip($params['info']);
     $prop = array_flip($params['prop']);
     // Deprecated parameters
     if (isset($prop['hasrelated'])) {
         $this->logFeatureUsage('action=search&srprop=hasrelated');
         $this->setWarning('srprop=hasrelated has been deprecated');
     }
     if (isset($prop['score'])) {
         $this->logFeatureUsage('action=search&srprop=score');
         $this->setWarning('srprop=score has been deprecated');
     }
     // Create search engine instance and set options
     $search = isset($params['backend']) && $params['backend'] != self::BACKEND_NULL_PARAM ? SearchEngine::create($params['backend']) : SearchEngine::create();
     $search->setLimitOffset($limit + 1, $params['offset']);
     $search->setNamespaces($params['namespace']);
     $search->setFeatureData('rewrite', (bool) $params['enablerewrites']);
     $query = $search->transformSearchTerm($query);
     $query = $search->replacePrefixes($query);
     // Perform the actual search
     if ($what == 'text') {
         $matches = $search->searchText($query);
     } elseif ($what == 'title') {
         $matches = $search->searchTitle($query);
     } elseif ($what == 'nearmatch') {
         // near matches must receive the user input as provided, otherwise
         // the near matches within namespaces are lost.
         $matches = SearchEngine::getNearMatchResultSet($params['search']);
     } else {
         // We default to title searches; this is a terrible legacy
         // of the way we initially set up the MySQL fulltext-based
         // search engine with separate title and text fields.
         // In the future, the default should be for a combined index.
         $what = 'title';
         $matches = $search->searchTitle($query);
         // Not all search engines support a separate title search,
         // for instance the Lucene-based engine we use on Wikipedia.
         // In this case, fall back to full-text search (which will
         // include titles in it!)
         if (is_null($matches)) {
             $what = 'text';
             $matches = $search->searchText($query);
         }
     }
     if (is_null($matches)) {
         $this->dieUsage("{$what} search is disabled", "search-{$what}-disabled");
     } elseif ($matches instanceof Status && !$matches->isGood()) {
         $this->dieUsage($matches->getWikiText(), 'search-error');
     }
     if ($resultPageSet === null) {
         $apiResult = $this->getResult();
         // Add search meta data to result
         if (isset($searchInfo['totalhits'])) {
             $totalhits = $matches->getTotalHits();
             if ($totalhits !== null) {
                 $apiResult->addValue(array('query', 'searchinfo'), 'totalhits', $totalhits);
             }
         }
         if (isset($searchInfo['suggestion']) && $matches->hasSuggestion()) {
             $apiResult->addValue(array('query', 'searchinfo'), 'suggestion', $matches->getSuggestionQuery());
             $apiResult->addValue(array('query', 'searchinfo'), 'suggestionsnippet', $matches->getSuggestionSnippet());
         }
         if (isset($searchInfo['rewrittenquery']) && $matches->hasRewrittenQuery()) {
             $apiResult->addValue(array('query', 'searchinfo'), 'rewrittenquery', $matches->getQueryAfterRewrite());
             $apiResult->addValue(array('query', 'searchinfo'), 'rewrittenquerysnippet', $matches->getQueryAfterRewriteSnippet());
         }
     }
     // Add the search results to the result
     $terms = $wgContLang->convertForSearchResult($matches->termMatches());
     $titles = array();
     $count = 0;
     $result = $matches->next();
     while ($result) {
         if (++$count > $limit) {
             // We've reached the one extra which shows that there are
             // additional items to be had. Stop here...
             $this->setContinueEnumParameter('offset', $params['offset'] + $params['limit']);
             break;
         }
         // Silently skip broken and missing titles
         if ($result->isBrokenTitle() || $result->isMissingRevision()) {
             $result = $matches->next();
             continue;
         }
         $title = $result->getTitle();
         if ($resultPageSet === null) {
             $vals = array();
             ApiQueryBase::addTitleInfo($vals, $title);
             if (isset($prop['snippet'])) {
                 $vals['snippet'] = $result->getTextSnippet($terms);
             }
             if (isset($prop['size'])) {
                 $vals['size'] = $result->getByteSize();
             }
             if (isset($prop['wordcount'])) {
                 $vals['wordcount'] = $result->getWordCount();
             }
             if (isset($prop['timestamp'])) {
                 $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $result->getTimestamp());
             }
             if (isset($prop['titlesnippet'])) {
                 $vals['titlesnippet'] = $result->getTitleSnippet();
             }
             if (isset($prop['categorysnippet'])) {
                 $vals['categorysnippet'] = $result->getCategorySnippet();
             }
             if (!is_null($result->getRedirectTitle())) {
                 if (isset($prop['redirecttitle'])) {
                     $vals['redirecttitle'] = $result->getRedirectTitle()->getPrefixedText();
                 }
                 if (isset($prop['redirectsnippet'])) {
                     $vals['redirectsnippet'] = $result->getRedirectSnippet();
                 }
             }
             if (!is_null($result->getSectionTitle())) {
                 if (isset($prop['sectiontitle'])) {
                     $vals['sectiontitle'] = $result->getSectionTitle()->getFragment();
                 }
                 if (isset($prop['sectionsnippet'])) {
                     $vals['sectionsnippet'] = $result->getSectionSnippet();
                 }
             }
             if (isset($prop['isfilematch'])) {
                 $vals['isfilematch'] = $result->isFileMatch();
             }
             // Add item to results and see whether it fits
             $fit = $apiResult->addValue(array('query', $this->getModuleName()), null, $vals);
             if (!$fit) {
                 $this->setContinueEnumParameter('offset', $params['offset'] + $count - 1);
                 break;
             }
         } else {
             $titles[] = $title;
         }
         $result = $matches->next();
     }
     $hasInterwikiResults = false;
     $totalhits = null;
     if ($interwiki && $resultPageSet === null && $matches->hasInterwikiResults()) {
         foreach ($matches->getInterwikiResults() as $matches) {
             $matches = $matches->getInterwikiResults();
             $hasInterwikiResults = true;
             // Include number of results if requested
             if ($resultPageSet === null && isset($searchInfo['totalhits'])) {
                 $totalhits += $matches->getTotalHits();
             }
             $result = $matches->next();
             while ($result) {
                 $title = $result->getTitle();
                 if ($resultPageSet === null) {
                     $vals = array('namespace' => $result->getInterwikiNamespaceText(), 'title' => $title->getText(), 'url' => $title->getFullUrl());
                     // Add item to results and see whether it fits
                     $fit = $apiResult->addValue(array('query', 'interwiki' . $this->getModuleName(), $result->getInterwikiPrefix()), null, $vals);
                     if (!$fit) {
                         // We hit the limit. We can't really provide any meaningful
                         // pagination info so just bail out
                         break;
                     }
                 } else {
                     $titles[] = $title;
                 }
                 $result = $matches->next();
             }
         }
         if ($totalhits !== null) {
             $apiResult->addValue(array('query', 'interwikisearchinfo'), 'totalhits', $totalhits);
         }
     }
     if ($resultPageSet === null) {
         $apiResult->addIndexedTagName(array('query', $this->getModuleName()), 'p');
         if ($hasInterwikiResults) {
             $apiResult->addIndexedTagName(array('query', 'interwiki' . $this->getModuleName()), 'p');
         }
     } else {
         $resultPageSet->populateFromTitles($titles);
         $offset = $params['offset'] + 1;
         foreach ($titles as $index => $title) {
             $resultPageSet->setGeneratorData($title, array('index' => $index + $offset));
         }
     }
 }
Пример #2
0
 /**
  * @param $resultPageSet ApiPageSet
  * @return void
  */
 private function run($resultPageSet = null)
 {
     global $wgContLang;
     $params = $this->extractRequestParams();
     // Extract parameters
     $limit = $params['limit'];
     $query = $params['search'];
     $what = $params['what'];
     $searchInfo = array_flip($params['info']);
     $prop = array_flip($params['prop']);
     // Create search engine instance and set options
     $search = isset($params['backend']) && $params['backend'] != self::BACKEND_NULL_PARAM ? SearchEngine::create($params['backend']) : SearchEngine::create();
     $search->setLimitOffset($limit + 1, $params['offset']);
     $search->setNamespaces($params['namespace']);
     $search->showRedirects = $params['redirects'];
     $query = $search->transformSearchTerm($query);
     $query = $search->replacePrefixes($query);
     // Perform the actual search
     if ($what == 'text') {
         $matches = $search->searchText($query);
     } elseif ($what == 'title') {
         $matches = $search->searchTitle($query);
     } elseif ($what == 'nearmatch') {
         $matches = SearchEngine::getNearMatchResultSet($query);
     } else {
         // We default to title searches; this is a terrible legacy
         // of the way we initially set up the MySQL fulltext-based
         // search engine with separate title and text fields.
         // In the future, the default should be for a combined index.
         $what = 'title';
         $matches = $search->searchTitle($query);
         // Not all search engines support a separate title search,
         // for instance the Lucene-based engine we use on Wikipedia.
         // In this case, fall back to full-text search (which will
         // include titles in it!)
         if (is_null($matches)) {
             $what = 'text';
             $matches = $search->searchText($query);
         }
     }
     if (is_null($matches)) {
         $this->dieUsage("{$what} search is disabled", "search-{$what}-disabled");
     } elseif ($matches instanceof Status && !$matches->isGood()) {
         $this->dieUsage($matches->getWikiText(), 'search-error');
     }
     $apiResult = $this->getResult();
     // Add search meta data to result
     if (isset($searchInfo['totalhits'])) {
         $totalhits = $matches->getTotalHits();
         if ($totalhits !== null) {
             $apiResult->addValue(array('query', 'searchinfo'), 'totalhits', $totalhits);
         }
     }
     if (isset($searchInfo['suggestion']) && $matches->hasSuggestion()) {
         $apiResult->addValue(array('query', 'searchinfo'), 'suggestion', $matches->getSuggestionQuery());
     }
     // Add the search results to the result
     $terms = $wgContLang->convertForSearchResult($matches->termMatches());
     $titles = array();
     $count = 0;
     $result = $matches->next();
     while ($result) {
         if (++$count > $limit) {
             // We've reached the one extra which shows that there are
             // additional items to be had. Stop here...
             $this->setContinueEnumParameter('offset', $params['offset'] + $params['limit']);
             break;
         }
         // Silently skip broken and missing titles
         if ($result->isBrokenTitle() || $result->isMissingRevision()) {
             $result = $matches->next();
             continue;
         }
         $title = $result->getTitle();
         if (is_null($resultPageSet)) {
             $vals = array();
             ApiQueryBase::addTitleInfo($vals, $title);
             if (isset($prop['snippet'])) {
                 $vals['snippet'] = $result->getTextSnippet($terms);
             }
             if (isset($prop['size'])) {
                 $vals['size'] = $result->getByteSize();
             }
             if (isset($prop['wordcount'])) {
                 $vals['wordcount'] = $result->getWordCount();
             }
             if (isset($prop['timestamp'])) {
                 $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $result->getTimestamp());
             }
             if (!is_null($result->getScore()) && isset($prop['score'])) {
                 $vals['score'] = $result->getScore();
             }
             if (isset($prop['titlesnippet'])) {
                 $vals['titlesnippet'] = $result->getTitleSnippet($terms);
             }
             if (!is_null($result->getRedirectTitle())) {
                 if (isset($prop['redirecttitle'])) {
                     $vals['redirecttitle'] = $result->getRedirectTitle();
                 }
                 if (isset($prop['redirectsnippet'])) {
                     $vals['redirectsnippet'] = $result->getRedirectSnippet($terms);
                 }
             }
             if (!is_null($result->getSectionTitle())) {
                 if (isset($prop['sectiontitle'])) {
                     $vals['sectiontitle'] = $result->getSectionTitle()->getFragment();
                 }
                 if (isset($prop['sectionsnippet'])) {
                     $vals['sectionsnippet'] = $result->getSectionSnippet();
                 }
             }
             if (isset($prop['hasrelated']) && $result->hasRelated()) {
                 $vals['hasrelated'] = '';
             }
             // Add item to results and see whether it fits
             $fit = $apiResult->addValue(array('query', $this->getModuleName()), null, $vals);
             if (!$fit) {
                 $this->setContinueEnumParameter('offset', $params['offset'] + $count - 1);
                 break;
             }
         } else {
             $titles[] = $title;
         }
         $result = $matches->next();
     }
     if (is_null($resultPageSet)) {
         $apiResult->setIndexedTagName_internal(array('query', $this->getModuleName()), 'p');
     } else {
         $resultPageSet->populateFromTitles($titles);
     }
 }