MediaWiki master
SearchApi.php
Go to the documentation of this file.
1<?php
2
23namespace MediaWiki\Api;
24
25use LogicException;
27use SearchEngine;
32
37trait SearchApi {
38
39 private SearchEngineConfig $searchEngineConfig;
40 private SearchEngineFactory $searchEngineFactory;
41
42 private function checkDependenciesSet() {
43 // Since this is a trait, we can't have a constructor where the services
44 // that we need are injected. Instead, the api modules that use this trait
45 // are responsible for setting them (since api modules *can* have services
46 // injected). Double check that the api module did indeed set them
47 // @phan-suppress-next-line PhanRedundantCondition Phan trusts the type hints too much
48 if ( !isset( $this->searchEngineConfig ) || !isset( $this->searchEngineFactory ) ) {
49 throw new LogicException(
50 'SearchApi requires both a SearchEngineConfig and SearchEngineFactory to be set'
51 );
52 }
53 }
54
62 private static $BACKEND_NULL_PARAM = 'database-backed';
63
72 public function buildCommonApiParams( $isScrollable = true ) {
73 $this->checkDependenciesSet();
74
75 $params = [
76 'search' => [
77 ParamValidator::PARAM_TYPE => 'string',
78 ParamValidator::PARAM_REQUIRED => true,
79 ],
80 'namespace' => [
81 ParamValidator::PARAM_DEFAULT => NS_MAIN,
82 ParamValidator::PARAM_TYPE => 'namespace',
83 ParamValidator::PARAM_ISMULTI => true,
84 ],
85 'limit' => [
86 ParamValidator::PARAM_DEFAULT => 10,
87 ParamValidator::PARAM_TYPE => 'limit',
88 IntegerDef::PARAM_MIN => 1,
89 IntegerDef::PARAM_MAX => ApiBase::LIMIT_BIG1,
90 IntegerDef::PARAM_MAX2 => ApiBase::LIMIT_BIG2,
91 ],
92 ];
93 if ( $isScrollable ) {
94 $params['offset'] = [
95 ParamValidator::PARAM_DEFAULT => 0,
96 IntegerDef::PARAM_MIN => 0,
97 ParamValidator::PARAM_TYPE => 'integer',
98 ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
99 ];
100 }
101
102 $alternatives = $this->searchEngineConfig->getSearchTypes();
103 if ( count( $alternatives ) > 1 ) {
104 $alternatives[0] ??= self::$BACKEND_NULL_PARAM;
105 $params['backend'] = [
106 ParamValidator::PARAM_DEFAULT => $this->searchEngineConfig->getSearchType(),
107 ParamValidator::PARAM_TYPE => $alternatives,
108 ];
109 // @todo: support profile selection when multiple
110 // backends are available. The solution could be to
111 // merge all possible profiles and let ApiBase
112 // subclasses do the check. Making ApiHelp and ApiSandbox
113 // comprehensive might be more difficult.
114 } else {
115 $params += $this->buildProfileApiParam();
116 }
117
118 return $params;
119 }
120
129 private function buildProfileApiParam() {
130 $this->checkDependenciesSet();
131
132 $configs = $this->getSearchProfileParams();
133 $searchEngine = $this->searchEngineFactory->create();
134 $params = [];
135 foreach ( $configs as $paramName => $paramConfig ) {
136 $profiles = $searchEngine->getProfiles(
137 $paramConfig['profile-type'],
138 $this->getContext()->getUser()
139 );
140 if ( !$profiles ) {
141 continue;
142 }
143
144 $types = [];
145 $helpMessages = [];
146 $defaultProfile = null;
147 foreach ( $profiles as $profile ) {
148 $types[] = $profile['name'];
149 if ( isset( $profile['desc-message'] ) ) {
150 $helpMessages[$profile['name']] = $profile['desc-message'];
151 }
152
153 if ( !empty( $profile['default'] ) ) {
154 $defaultProfile = $profile['name'];
155 }
156 }
157
158 $params[$paramName] = [
159 ParamValidator::PARAM_TYPE => $types,
160 ApiBase::PARAM_HELP_MSG => $paramConfig['help-message'],
161 ApiBase::PARAM_HELP_MSG_PER_VALUE => $helpMessages,
162 ParamValidator::PARAM_DEFAULT => $defaultProfile,
163 ];
164 }
165
166 return $params;
167 }
168
182 public function buildSearchEngine( ?array $params = null ) {
183 $this->checkDependenciesSet();
184
185 if ( $params == null ) {
186 return $this->searchEngineFactory->create();
187 }
188
189 $type = $params['backend'] ?? null;
190 if ( $type === self::$BACKEND_NULL_PARAM ) {
191 $type = null;
192 }
193 $searchEngine = $this->searchEngineFactory->create( $type );
194 $searchEngine->setNamespaces( $params['namespace'] );
195 $searchEngine->setLimitOffset( $params['limit'], $params['offset'] ?? 0 );
196
197 // Initialize requested search profiles.
198 $configs = $this->getSearchProfileParams();
199 foreach ( $configs as $paramName => $paramConfig ) {
200 if ( isset( $params[$paramName] ) ) {
201 $searchEngine->setFeatureData(
202 $paramConfig['profile-type'],
203 $params[$paramName]
204 );
205 }
206 }
207 return $searchEngine;
208 }
209
214 abstract public function getSearchProfileParams();
215
219 abstract public function getContext();
220}
221
223class_alias( SearchApi::class, 'SearchApi' );
const NS_MAIN
Definition Defines.php:65
array $params
The job parameters.
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, or 'string' with PARAM_ISMULTI,...
Definition ApiBase.php:224
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition ApiBase.php:184
const LIMIT_BIG2
Fast query, apihighlimits limit.
Definition ApiBase.php:251
const LIMIT_BIG1
Fast query, standard limit.
Definition ApiBase.php:249
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:37
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:72
getSearchProfileParams()
buildSearchEngine(?array $params=null)
Build the search engine to use.