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';
76 $printer->setRootElement(
'SearchSuggestion' );
86 $search = $params[
'search'];
89 $this->
getMain()->setCacheMaxAge( $this->
getConfig()->
get(
'SearchSuggestCacheExpiry' ) );
90 $this->
getMain()->setCacheMode(
'public' );
91 $results = $this->
search( $search, $params );
97 $length = $this->
getConfig()->get(
'OpenSearchDescriptionLength' );
98 foreach ( $results as &$r ) {
99 if ( is_string( $r[
'extract'] ) && !$r[
'extract trimmed'] ) {
116 private function search( $search, array $params ) {
118 $titles = $searchEngine->extractTitles( $searchEngine->completionSearchWithVariants( $search ) );
128 $nextSpecialPageId = -1;
130 if ( $params[
'redirects'] ===
null ) {
132 $resolveRedir = $this->
getFormat() !==
'json';
134 $resolveRedir = $params[
'redirects'] ===
'resolve';
137 if ( $resolveRedir ) {
141 if ( !$lb->isEmpty() ) {
142 $db = $this->
getDB();
144 [
'page',
'redirect' ],
145 [
'page_namespace',
'page_title',
'rd_namespace',
'rd_title' ],
148 'rd_interwiki IS NULL OR rd_interwiki = ' . $db->addQuotes(
'' ),
149 $lb->constructSet(
'page', $db ),
153 foreach (
$res as $row ) {
154 $redirects[$row->page_namespace][$row->page_title] =
155 [ $row->rd_namespace, $row->rd_title ];
161 foreach ( $titles as
$title ) {
162 $ns =
$title->getNamespace();
163 $dbkey =
$title->getDBkey();
165 if ( isset( $redirects[$ns][$dbkey] ) ) {
166 list( $ns, $dbkey ) = $redirects[$ns][$dbkey];
168 $title = Title::makeTitle( $ns, $dbkey );
170 if ( !isset( $seen[$ns][$dbkey] ) ) {
171 $seen[$ns][$dbkey] =
true;
172 $resultId =
$title->getArticleID();
173 if ( $resultId === 0 ) {
174 $resultId = $nextSpecialPageId;
175 $nextSpecialPageId -= 1;
177 $results[$resultId] = [
179 'redirect from' => $from,
181 'extract trimmed' =>
false,
188 foreach ( $titles as
$title ) {
189 $resultId =
$title->getArticleID();
190 if ( $resultId === 0 ) {
191 $resultId = $nextSpecialPageId;
192 $nextSpecialPageId -= 1;
194 $results[$resultId] = [
196 'redirect from' =>
null,
198 'extract trimmed' =>
false,
218 $result->addArrayType(
null,
'array' );
219 $result->addValue(
null, 0, strval( $search ) );
223 foreach ( $results as $r ) {
224 $terms[] = $r[
'title']->getPrefixedText();
225 $descriptions[] = strval( $r[
'extract'] );
228 $result->addValue(
null, 1, $terms );
229 $result->addValue(
null, 2, $descriptions );
230 $result->addValue(
null, 3, $urls );
243 foreach ( $results as $r ) {
245 'Text' => $r[
'title']->getPrefixedText(),
248 if ( is_string( $r[
'extract'] ) && $r[
'extract'] !==
'' ) {
249 $item[
'Description'] = $r[
'extract'];
251 if ( is_array( $r[
'image'] ) && isset( $r[
'image'][
'source'] ) ) {
252 $item[
'Image'] = array_intersect_key( $r[
'image'], $imageKeys );
254 ApiResult::setSubelementsList( $item, array_keys( $item ) );
257 ApiResult::setIndexedTagName( $items,
'Item' );
258 $result->addValue(
null,
'version',
'2.0' );
259 $result->addValue(
null,
'xmlns',
'http://opensearch.org/searchsuggest2' );
260 $result->addValue(
null,
'Query', strval( $search ) );
261 $result->addSubelementsList(
null,
'Query' );
262 $result->addValue(
null,
'Section', $items );
271 if ( $this->allowedParams !==
null ) {
287 'warningsaserror' =>
false,
292 'OpenSearchDefaultLimit'
301 'profile-type' => SearchEngine::COMPLETION_PROFILE_TYPE,
302 'help-message' =>
'apihelp-query+prefixsearch-param-profile'
309 'action=opensearch&search=Te'
310 =>
'apihelp-opensearch-example-te',
315 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Opensearch';
329 static $regex =
null;
331 if ( $regex ===
null ) {
333 '([^\d])\.\s',
'\!\s',
'\?\s',
338 $endgroup = implode(
'|', $endchars );
339 $end =
"(?:$endgroup)";
340 $sentence =
".{{$length},}?$end+";
341 $regex =
"/^($sentence)/u";
345 if ( preg_match( $regex, $text,
$matches ) ) {
349 return trim( explode(
"\n", $text )[0] );
361 $config = MediaWikiServices::getInstance()->getSearchEngineConfig();
362 $template = $config->getConfig()->get(
'OpenSearchTemplate' );
364 if ( $template &&
$type ===
'application/x-suggestions+json' ) {
368 $ns = implode(
'|', $config->defaultNamespaces() );
374 case 'application/x-suggestions+json':
375 return $config->getConfig()->get(
'CanonicalServer' ) .
wfScript(
'api' )
376 .
'?action=opensearch&search={searchTerms}&namespace=' . $ns;
378 case 'application/x-suggestions+xml':
379 return $config->getConfig()->get(
'CanonicalServer' ) .
wfScript(
'api' )
380 .
'?action=opensearch&format=xml&search={searchTerms}&namespace=' . $ns;
383 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 Stable to override.
static dieDebug( $method, $message)
Internal code errors should be reported with this method.
getMain()
Get the main module.
getResult()
Get the result object.
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
getHookRunner()
Get an ApiHookRunner for running core API hooks.
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.