MediaWiki master
SearchApi.php
Go to the documentation of this file.
1<?php
2
9namespace MediaWiki\Api;
10
11use LogicException;
13use SearchEngine;
18
23trait SearchApi {
24
25 private ?SearchEngineConfig $searchEngineConfig = null;
26 private ?SearchEngineFactory $searchEngineFactory = null;
27
28 private function checkDependenciesSet() {
29 // Since this is a trait, we can't have a constructor where the services
30 // that we need are injected. Instead, the api modules that use this trait
31 // are responsible for setting them (since api modules *can* have services
32 // injected). Double check that the api module did indeed set them
33 if ( $this->searchEngineConfig === null || $this->searchEngineFactory === null ) {
34 throw new LogicException(
35 'SearchApi requires both a SearchEngineConfig and SearchEngineFactory to be set'
36 );
37 }
38 }
39
47 private static $BACKEND_NULL_PARAM = 'database-backed';
48
57 public function buildCommonApiParams( $isScrollable = true ) {
58 $this->checkDependenciesSet();
59
60 $params = [
61 'search' => [
62 ParamValidator::PARAM_TYPE => 'string',
63 ParamValidator::PARAM_REQUIRED => true,
64 ],
65 'namespace' => [
66 ParamValidator::PARAM_DEFAULT => NS_MAIN,
67 ParamValidator::PARAM_TYPE => 'namespace',
68 ParamValidator::PARAM_ISMULTI => true,
69 ],
70 'limit' => [
71 ParamValidator::PARAM_DEFAULT => 10,
72 ParamValidator::PARAM_TYPE => 'limit',
73 IntegerDef::PARAM_MIN => 1,
74 IntegerDef::PARAM_MAX => ApiBase::LIMIT_BIG1,
75 IntegerDef::PARAM_MAX2 => ApiBase::LIMIT_BIG2,
76 ],
77 ];
78 if ( $isScrollable ) {
79 $params['offset'] = [
80 ParamValidator::PARAM_DEFAULT => 0,
81 IntegerDef::PARAM_MIN => 0,
82 ParamValidator::PARAM_TYPE => 'integer',
83 ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
84 ];
85 }
86
87 $alternatives = $this->searchEngineConfig->getSearchTypes();
88 if ( count( $alternatives ) > 1 ) {
89 $alternatives[0] ??= self::$BACKEND_NULL_PARAM;
90 $params['backend'] = [
91 ParamValidator::PARAM_DEFAULT => $this->searchEngineConfig->getSearchType(),
92 ParamValidator::PARAM_TYPE => $alternatives,
93 ];
94 // @todo: support profile selection when multiple
95 // backends are available. The solution could be to
96 // merge all possible profiles and let ApiBase
97 // subclasses do the check. Making ApiHelp and ApiSandbox
98 // comprehensive might be more difficult.
99 } else {
100 $params += $this->buildProfileApiParam();
101 }
102
103 return $params;
104 }
105
114 private function buildProfileApiParam() {
115 $this->checkDependenciesSet();
116
117 $configs = $this->getSearchProfileParams();
118 $searchEngine = $this->searchEngineFactory->create();
119 $params = [];
120 foreach ( $configs as $paramName => $paramConfig ) {
121 $profiles = $searchEngine->getProfiles(
122 $paramConfig['profile-type'],
123 $this->getContext()->getUser()
124 );
125 if ( !$profiles ) {
126 continue;
127 }
128
129 $types = [];
130 $helpMessages = [];
131 $defaultProfile = null;
132 foreach ( $profiles as $profile ) {
133 $types[] = $profile['name'];
134 if ( isset( $profile['desc-message'] ) ) {
135 $helpMessages[$profile['name']] = $profile['desc-message'];
136 }
137
138 if ( !empty( $profile['default'] ) ) {
139 $defaultProfile = $profile['name'];
140 }
141 }
142
143 $params[$paramName] = [
144 ParamValidator::PARAM_TYPE => $types,
145 ApiBase::PARAM_HELP_MSG => $paramConfig['help-message'],
146 ApiBase::PARAM_HELP_MSG_PER_VALUE => $helpMessages,
147 ParamValidator::PARAM_DEFAULT => $defaultProfile,
148 ];
149 }
150
151 return $params;
152 }
153
167 public function buildSearchEngine( ?array $params = null ) {
168 $this->checkDependenciesSet();
169
170 if ( $params == null ) {
171 return $this->searchEngineFactory->create();
172 }
173
174 $type = $params['backend'] ?? null;
175 if ( $type === self::$BACKEND_NULL_PARAM ) {
176 $type = null;
177 }
178 $searchEngine = $this->searchEngineFactory->create( $type );
179 $searchEngine->setNamespaces( $params['namespace'] );
180 $searchEngine->setLimitOffset( $params['limit'], $params['offset'] ?? 0 );
181
182 // Initialize requested search profiles.
183 $configs = $this->getSearchProfileParams();
184 foreach ( $configs as $paramName => $paramConfig ) {
185 if ( isset( $params[$paramName] ) ) {
186 $searchEngine->setFeatureData(
187 $paramConfig['profile-type'],
188 $params[$paramName]
189 );
190 }
191 }
192 return $searchEngine;
193 }
194
199 abstract public function getSearchProfileParams();
200
204 abstract public function getContext();
205}
206
208class_alias( SearchApi::class, 'SearchApi' );
const NS_MAIN
Definition Defines.php:51
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, or 'string' with PARAM_ISMULTI,...
Definition ApiBase.php:207
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition ApiBase.php:167
const LIMIT_BIG2
Fast query, apihighlimits limit.
Definition ApiBase.php:234
const LIMIT_BIG1
Fast query, standard limit.
Definition ApiBase.php:232
Configuration handling class for SearchEngine.
Factory class for SearchEngine.
Contain a class for special pages.
Service for formatting and validating API parameters.
Type definition for integer types.
trait SearchApi
Traits for API components that use a SearchEngine.
Definition SearchApi.php:23
Interface for objects which can provide a MediaWiki context on request.
buildCommonApiParams( $isScrollable=true)
The set of api parameters that are shared between api calls that call the SearchEngine.
Definition SearchApi.php:57
getSearchProfileParams()
buildSearchEngine(?array $params=null)
Build the search engine to use.
array $params
The job parameters.