45 if ( $this->format ===
null ) {
54 if ( substr(
$format, -2 ) ===
'fm' ) {
55 $this->format = substr(
$format, 0, -2 );
73 $printer = $this->
getMain()->createPrinterByName(
'xml' . $this->fm );
74 '@phan-var ApiFormatXML $printer';
75 $printer->setRootElement(
'SearchSuggestion' );
85 $search = $params[
'search'];
86 $suggest = $params[
'suggest'];
88 if ( !$suggest || $this->
getConfig()->
get(
'EnableOpenSearchSuggest' ) ) {
90 $this->
getMain()->setCacheMaxAge( $this->
getConfig()->
get(
'SearchSuggestCacheExpiry' ) );
91 $this->
getMain()->setCacheMode(
'public' );
92 $results = $this->
search( $search, $params );
95 Hooks::run(
'ApiOpenSearchSuggest', [ &$results ] );
98 $length = $this->
getConfig()->get(
'OpenSearchDescriptionLength' );
99 foreach ( $results as &$r ) {
101 if ( is_string( $r[
'extract'] ) && !$r[
'extract trimmed'] ) {
119 private function search( $search, array $params ) {
121 $titles = $searchEngine->extractTitles( $searchEngine->completionSearchWithVariants( $search ) );
131 $nextSpecialPageId = -1;
133 if ( $params[
'redirects'] ===
null ) {
135 $resolveRedir = $this->
getFormat() !==
'json';
137 $resolveRedir = $params[
'redirects'] ===
'resolve';
140 if ( $resolveRedir ) {
144 if ( !$lb->isEmpty() ) {
145 $db = $this->
getDB();
147 [
'page',
'redirect' ],
148 [
'page_namespace',
'page_title',
'rd_namespace',
'rd_title' ],
151 'rd_interwiki IS NULL OR rd_interwiki = ' . $db->addQuotes(
'' ),
152 $lb->constructSet(
'page', $db ),
156 foreach (
$res as $row ) {
157 $redirects[$row->page_namespace][$row->page_title] =
158 [ $row->rd_namespace, $row->rd_title ];
164 foreach ( $titles as
$title ) {
165 $ns =
$title->getNamespace();
166 $dbkey =
$title->getDBkey();
168 if ( isset( $redirects[$ns][$dbkey] ) ) {
169 list( $ns, $dbkey ) = $redirects[$ns][$dbkey];
171 $title = Title::makeTitle( $ns, $dbkey );
173 if ( !isset( $seen[$ns][$dbkey] ) ) {
174 $seen[$ns][$dbkey] =
true;
175 $resultId =
$title->getArticleID();
176 if ( $resultId === 0 ) {
177 $resultId = $nextSpecialPageId;
178 $nextSpecialPageId -= 1;
180 $results[$resultId] = [
182 'redirect from' => $from,
184 'extract trimmed' =>
false,
191 foreach ( $titles as
$title ) {
192 $resultId =
$title->getArticleID();
193 if ( $resultId === 0 ) {
194 $resultId = $nextSpecialPageId;
195 $nextSpecialPageId -= 1;
197 $results[$resultId] = [
199 'redirect from' =>
null,
201 'extract trimmed' =>
false,
221 $result->addArrayType(
null,
'array' );
222 $result->addValue(
null, 0, strval( $search ) );
226 foreach ( $results as $r ) {
227 $terms[] = $r[
'title']->getPrefixedText();
228 $descriptions[] = strval( $r[
'extract'] );
231 $result->addValue(
null, 1, $terms );
232 $result->addValue(
null, 2, $descriptions );
233 $result->addValue(
null, 3,
$urls );
246 foreach ( $results as $r ) {
248 'Text' => $r[
'title']->getPrefixedText(),
251 if ( is_string( $r[
'extract'] ) && $r[
'extract'] !==
'' ) {
252 $item[
'Description'] = $r[
'extract'];
254 if ( is_array( $r[
'image'] ) && isset( $r[
'image'][
'source'] ) ) {
255 $item[
'Image'] = array_intersect_key( $r[
'image'], $imageKeys );
257 ApiResult::setSubelementsList( $item, array_keys( $item ) );
260 ApiResult::setIndexedTagName( $items,
'Item' );
261 $result->addValue(
null,
'version',
'2.0' );
262 $result->addValue(
null,
'xmlns',
'http://opensearch.org/searchsuggest2' );
263 $result->addValue(
null,
'Query', strval( $search ) );
264 $result->addSubelementsList(
null,
'Query' );
265 $result->addValue(
null,
'Section', $items );
274 if ( $this->allowedParams !==
null ) {
286 'warningsaserror' =>
false,
291 'OpenSearchDefaultLimit'
300 'profile-type' => SearchEngine::COMPLETION_PROFILE_TYPE,
301 'help-message' =>
'apihelp-query+prefixsearch-param-profile'
308 'action=opensearch&search=Te'
309 =>
'apihelp-opensearch-example-te',
314 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Opensearch';
328 static $regex =
null;
330 if ( $regex ===
null ) {
332 '([^\d])\.\s',
'\!\s',
'\?\s',
337 $endgroup = implode(
'|', $endchars );
338 $end =
"(?:$endgroup)";
339 $sentence =
".{{$length},}?$end+";
340 $regex =
"/^($sentence)/u";
344 if ( preg_match( $regex, $text,
$matches ) ) {
348 return trim( explode(
"\n", $text )[0] );
360 $config = MediaWikiServices::getInstance()->getSearchEngineConfig();
361 $template = $config->getConfig()->get(
'OpenSearchTemplate' );
363 if ( $template &&
$type ===
'application/x-suggestions+json' ) {
367 $ns = implode(
'|', $config->defaultNamespaces() );
373 case 'application/x-suggestions+json':
374 return $config->getConfig()->get(
'CanonicalServer' ) .
wfScript(
'api' )
375 .
'?action=opensearch&search={searchTerms}&namespace=' . $ns;
377 case 'application/x-suggestions+xml':
378 return $config->getConfig()->get(
'CanonicalServer' ) .
wfScript(
'api' )
379 .
'?action=opensearch&format=xml&search={searchTerms}&namespace=' . $ns;
382 throw new MWException( __METHOD__ .
": Unknown type '$type'" );
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
buildSearchEngine(array $params=null)
Build the search engine to use.
buildCommonApiParams( $isScrollable=true)
The set of api parameters that are shared between api calls that call the SearchEngine.
This abstract class implements many basic API functions, and is the base of all API classes.
getParameter( $paramName, $parseLimit=true)
Get a value for the given parameter.
getDB()
Gets a default replica DB connection object.
static dieDebug( $method, $message)
Internal code errors should be reported with this method.
getMain()
Get the main module.
const PARAM_TYPE
(string|string[]) Either an array of allowed value strings, or a string type as described below.
const PARAM_DFLT
(null|boolean|integer|string) Default value of the parameter.
getResult()
Get the result object.
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
static trimExtract( $text, $length)
Trim an extract to a sensible length.
array $allowedParams
list of api allowed params
getHelpUrls()
Return links to more detailed help pages about the module.
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
getCustomPrinter()
If the module may only be used with a certain format module, it should override this method to return...
getExamplesMessages()
Returns usage examples for this module.
populateResult( $search, &$results)
getFormat()
Get the output format.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
static getOpenSearchTemplate( $type)
Fetch the template for a type.
search( $search, array $params)
Perform the search.
Class representing a list of titles The execute() method checks them all for existence and adds them ...
trait SearchApi
Traits for API components that use a SearchEngine.