/** * @param $resultPageSet ApiPageSet */ private function run($resultPageSet = null) { $params = $this->extractRequestParams(); $search = $params['search']; $limit = $params['limit']; $namespaces = $params['namespace']; $searcher = new TitlePrefixSearch(); $titles = $searcher->searchWithVariants($search, $limit, $namespaces); if ($resultPageSet) { $resultPageSet->populateFromTitles($titles); } else { $result = $this->getResult(); foreach ($titles as $title) { if (!$limit--) { break; } $vals = array('ns' => intval($title->getNamespace()), 'title' => $title->getPrefixedText()); if ($title->isSpecialPage()) { $vals['special'] = ''; } else { $vals['pageid'] = intval($title->getArticleId()); } $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals); if (!$fit) { break; } } $result->setIndexedTagName_internal(array('query', $this->getModuleName()), $this->getModulePrefix()); } }
/** * @param ApiPageSet $resultPageSet */ private function run($resultPageSet = null) { $params = $this->extractRequestParams(); $search = $params['search']; $limit = $params['limit']; $namespaces = $params['namespace']; $offset = $params['offset']; $searcher = new TitlePrefixSearch(); $titles = $searcher->searchWithVariants($search, $limit + 1, $namespaces, $offset); if ($resultPageSet) { $resultPageSet->setRedirectMergePolicy(function (array $current, array $new) { if (!isset($current['index']) || $new['index'] < $current['index']) { $current['index'] = $new['index']; } return $current; }); if (count($titles) > $limit) { $this->setContinueEnumParameter('offset', $offset + $params['limit']); array_pop($titles); } $resultPageSet->populateFromTitles($titles); foreach ($titles as $index => $title) { $resultPageSet->setGeneratorData($title, array('index' => $index + $offset + 1)); } } else { $result = $this->getResult(); $count = 0; foreach ($titles as $title) { if (++$count > $limit) { $this->setContinueEnumParameter('offset', $offset + $params['limit']); break; } $vals = array('ns' => intval($title->getNamespace()), 'title' => $title->getPrefixedText()); if ($title->isSpecialPage()) { $vals['special'] = true; } else { $vals['pageid'] = intval($title->getArticleId()); } $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals); if (!$fit) { $this->setContinueEnumParameter('offset', $offset + $count - 1); break; } } $result->addIndexedTagName(array('query', $this->getModuleName()), $this->getModulePrefix()); } }
/** * Return an array of subpages beginning with $search that this special page will accept. * * @param string $search Prefix to search for * @param int $limit Maximum number of results to return (usually 10) * @param int $offset Number of results to skip (usually 0) * @return string[] Matching subpages */ public function prefixSearchSubpages($search, $limit, $offset) { $title = Title::newFromText($search, NS_FILE); if (!$title || $title->getNamespace() !== NS_FILE) { // No prefix suggestion outside of file namespace return array(); } // Autocomplete subpage the same as a normal search, but just for files $prefixSearcher = new TitlePrefixSearch(); $result = $prefixSearcher->search($search, $limit, array(NS_FILE), $offset); return array_map(function (Title $t) { // Remove namespace in search suggestion return $t->getText(); }, $result); }
/** * Call out to simple search backend. * Defaults to TitlePrefixSearch. * @param string $search * @return Title[] */ protected function simplePrefixSearch($search) { // Use default database prefix search $backend = new TitlePrefixSearch(); return $backend->defaultSearchBackend($this->namespaces, $search, $this->limit, $this->offset); }
/** * Return an array of subpages beginning with $search that this special page will accept. * * @param string $search Prefix to search for * @param int $limit Maximum number of results to return (usually 10) * @param int $offset Number of results to skip (usually 0) * @return string[] Matching subpages */ public function prefixSearchSubpages($search, $limit, $offset) { if ($search === '') { return array(); } // Autocomplete subpage the same as a normal search, but just for files $prefixSearcher = new TitlePrefixSearch(); $result = $prefixSearcher->search($search, $limit, array(NS_FILE), $offset); return array_map(function (Title $t) { // Remove namespace in search suggestion return $t->getText(); }, $result); }
/** * Perform the search * * @param string $search Text to search * @param int $limit Maximum items to return * @param array $namespaces Namespaces to search * @param bool $resolveRedir Whether to resolve redirects * @param array &$results Put results here. Keys have to be integers. */ protected function search($search, $limit, $namespaces, $resolveRedir, &$results) { // Find matching titles as Title objects $searcher = new TitlePrefixSearch(); $titles = $searcher->searchWithVariants($search, $limit, $namespaces); if (!$titles) { return; } // Special pages need unique integer ids in the return list, so we just // assign them negative numbers because those won't clash with the // always positive articleIds that non-special pages get. $nextSpecialPageId = -1; if ($resolveRedir) { // Query for redirects $redirects = array(); $lb = new LinkBatch($titles); if (!$lb->isEmpty()) { $db = $this->getDb(); $res = $db->select(array('page', 'redirect'), array('page_namespace', 'page_title', 'rd_namespace', 'rd_title'), array('rd_from = page_id', 'rd_interwiki IS NULL OR rd_interwiki = ' . $db->addQuotes(''), $lb->constructSet('page', $db)), __METHOD__); foreach ($res as $row) { $redirects[$row->page_namespace][$row->page_title] = array($row->rd_namespace, $row->rd_title); } } // Bypass any redirects $seen = array(); foreach ($titles as $title) { $ns = $title->getNamespace(); $dbkey = $title->getDBkey(); $from = null; if (isset($redirects[$ns][$dbkey])) { list($ns, $dbkey) = $redirects[$ns][$dbkey]; $from = $title; $title = Title::makeTitle($ns, $dbkey); } if (!isset($seen[$ns][$dbkey])) { $seen[$ns][$dbkey] = true; $resultId = $title->getArticleId(); if ($resultId === 0) { $resultId = $nextSpecialPageId; $nextSpecialPageId -= 1; } $results[$resultId] = array('title' => $title, 'redirect from' => $from, 'extract' => false, 'extract trimmed' => false, 'image' => false, 'url' => wfExpandUrl($title->getFullUrl(), PROTO_CURRENT)); } } } else { foreach ($titles as $title) { $resultId = $title->getArticleId(); if ($resultId === 0) { $resultId = $nextSpecialPageId; $nextSpecialPageId -= 1; } $results[$resultId] = array('title' => $title, 'redirect from' => null, 'extract' => false, 'extract trimmed' => false, 'image' => false, 'url' => wfExpandUrl($title->getFullUrl(), PROTO_CURRENT)); } } }
/** * PrefixSearch fallback method to searchSuggestion. * This is needed when: * - the completion suggester is not enabled * - the query is for a namespace not covered by the completion suggester * - the Special: namespace * * @param string $search the user query * @return SearchSuggestionSet the suggestions */ private function searchSuggestionsPrefixSearchFallback($search) { $searcher = new TitlePrefixSearch(); $titles = $searcher->searchWithVariants($search, $this->limit, $this->namespaces); if (!$titles) { return SearchSuggestionSet::emptySuggestionSet(); } return SearchSuggestionSet::fromTitles($titles); }