$this->search( $search, $limit, $namespaces, $resolveRedir, $results );
// Allow hooks to populate extracts and images
- wfRunHooks( 'ApiOpenSearchSuggest', array( &$results ) );
+ Hooks::run( 'ApiOpenSearchSuggest', array( &$results ) );
// Trim extracts, if necessary
$length = $this->getConfig()->get( 'OpenSearchDescriptionLength' );
* @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
+ * @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
- $db = $this->getDb();
- $lb = new LinkBatch( $titles );
- $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__
- );
$redirects = array();
- foreach ( $res as $row ) {
- $redirects[$row->page_namespace][$row->page_title] =
- array( $row->rd_namespace, $row->rd_title );
+ $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
}
if ( !isset( $seen[$ns][$dbkey] ) ) {
$seen[$ns][$dbkey] = true;
- $results[$title->getArticleId()] = array(
+ $resultId = $title->getArticleId();
+ if ( $resultId === 0 ) {
+ $resultId = $nextSpecialPageId;
+ $nextSpecialPageId -= 1;
+ }
+ $results[$resultId] = array(
'title' => $title,
'redirect from' => $from,
'extract' => false,
}
} else {
foreach ( $titles as $title ) {
- $results[$title->getArticleId()] = array(
+ $resultId = $title->getArticleId();
+ if ( $resultId === 0 ) {
+ $resultId = $nextSpecialPageId;
+ $nextSpecialPageId -= 1;
+ }
+ $results[$resultId] = array(
'title' => $title,
'redirect from' => null,
'extract' => false,
switch ( $this->getFormat() ) {
case 'json':
// http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.1
+ $result->addArrayType( null, 'BCarray' );
$result->addValue( null, 0, strval( $search ) );
$terms = array();
$descriptions = array();
);
$items = array();
foreach ( $results as $r ) {
- $item = array();
- $result->setContent( $item, $r['title']->getPrefixedText(), 'Text' );
- $result->setContent( $item, $r['url'], 'Url' );
+ $item = array(
+ 'Text' => $r['title']->getPrefixedText(),
+ 'Url' => $r['url'],
+ );
if ( is_string( $r['extract'] ) && $r['extract'] !== '' ) {
- $result->setContent( $item, $r['extract'], 'Description' );
+ $item['Description'] = $r['extract'];
}
if ( is_array( $r['image'] ) && isset( $r['image']['source'] ) ) {
$item['Image'] = array_intersect_key( $r['image'], $imageKeys );
}
+ ApiResult::setSubelementsList( $item, array_keys( $item ) );
$items[] = $item;
}
- $result->setIndexedTagName( $items, 'Item' );
+ ApiResult::setIndexedTagName( $items, 'Item' );
$result->addValue( null, 'version', '2.0' );
$result->addValue( null, 'xmlns', 'http://opensearch.org/searchsuggest2' );
- $query = array();
- $result->setContent( $query, strval( $search ) );
- $result->addValue( null, 'Query', $query );
+ $result->addValue( null, 'Query', strval( $search ) );
+ $result->addSubelementsList( null, 'Query' );
$result->addValue( null, 'Section', $items );
break;
*
* @param string $type MIME type
* @return string
+ * @throws MWException
*/
public static function getOpenSearchTemplate( $type ) {
global $wgOpenSearchTemplate, $wgCanonicalServer;