MediaWiki master
SearchApi.php
Go to the documentation of this file.
1<?php
2
26
31trait SearchApi {
32
33 private SearchEngineConfig $searchEngineConfig;
34 private SearchEngineFactory $searchEngineFactory;
35
36 private function checkDependenciesSet() {
37 // Since this is a trait, we can't have a constructor where the services
38 // that we need are injected. Instead, the api modules that use this trait
39 // are responsible for setting them (since api modules *can* have services
40 // injected). Double check that the api module did indeed set them
41 // @phan-suppress-next-line PhanRedundantCondition Phan trusts the type hints too much
42 if ( !isset( $this->searchEngineConfig ) || !isset( $this->searchEngineFactory ) ) {
43 throw new LogicException(
44 'SearchApi requires both a SearchEngineConfig and SearchEngineFactory to be set'
45 );
46 }
47 }
48
55 private static $BACKEND_NULL_PARAM = 'database-backed';
56
65 public function buildCommonApiParams( $isScrollable = true ) {
66 $this->checkDependenciesSet();
67
68 $params = [
69 'search' => [
70 ParamValidator::PARAM_TYPE => 'string',
71 ParamValidator::PARAM_REQUIRED => true,
72 ],
73 'namespace' => [
74 ParamValidator::PARAM_DEFAULT => NS_MAIN,
75 ParamValidator::PARAM_TYPE => 'namespace',
76 ParamValidator::PARAM_ISMULTI => true,
77 ],
78 'limit' => [
79 ParamValidator::PARAM_DEFAULT => 10,
80 ParamValidator::PARAM_TYPE => 'limit',
81 IntegerDef::PARAM_MIN => 1,
82 IntegerDef::PARAM_MAX => ApiBase::LIMIT_BIG1,
83 IntegerDef::PARAM_MAX2 => ApiBase::LIMIT_BIG2,
84 ],
85 ];
86 if ( $isScrollable ) {
87 $params['offset'] = [
88 ParamValidator::PARAM_DEFAULT => 0,
89 IntegerDef::PARAM_MIN => 0,
90 ParamValidator::PARAM_TYPE => 'integer',
91 ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
92 ];
93 }
94
95 $alternatives = $this->searchEngineConfig->getSearchTypes();
96 if ( count( $alternatives ) > 1 ) {
97 $alternatives[0] ??= self::$BACKEND_NULL_PARAM;
98 $params['backend'] = [
99 ParamValidator::PARAM_DEFAULT => $this->searchEngineConfig->getSearchType(),
100 ParamValidator::PARAM_TYPE => $alternatives,
101 ];
102 // @todo: support profile selection when multiple
103 // backends are available. The solution could be to
104 // merge all possible profiles and let ApiBase
105 // subclasses do the check. Making ApiHelp and ApiSandbox
106 // comprehensive might be more difficult.
107 } else {
108 $params += $this->buildProfileApiParam();
109 }
110
111 return $params;
112 }
113
122 private function buildProfileApiParam() {
123 $this->checkDependenciesSet();
124
125 $configs = $this->getSearchProfileParams();
126 $searchEngine = $this->searchEngineFactory->create();
127 $params = [];
128 foreach ( $configs as $paramName => $paramConfig ) {
129 $profiles = $searchEngine->getProfiles(
130 $paramConfig['profile-type'],
131 $this->getContext()->getUser()
132 );
133 if ( !$profiles ) {
134 continue;
135 }
136
137 $types = [];
138 $helpMessages = [];
139 $defaultProfile = null;
140 foreach ( $profiles as $profile ) {
141 $types[] = $profile['name'];
142 if ( isset( $profile['desc-message'] ) ) {
143 $helpMessages[$profile['name']] = $profile['desc-message'];
144 }
145
146 if ( !empty( $profile['default'] ) ) {
147 $defaultProfile = $profile['name'];
148 }
149 }
150
151 $params[$paramName] = [
152 ParamValidator::PARAM_TYPE => $types,
153 ApiBase::PARAM_HELP_MSG => $paramConfig['help-message'],
154 ApiBase::PARAM_HELP_MSG_PER_VALUE => $helpMessages,
155 ParamValidator::PARAM_DEFAULT => $defaultProfile,
156 ];
157 }
158
159 return $params;
160 }
161
175 public function buildSearchEngine( array $params = null ) {
176 $this->checkDependenciesSet();
177
178 if ( $params == null ) {
179 return $this->searchEngineFactory->create();
180 }
181
182 $type = $params['backend'] ?? null;
183 if ( $type === self::$BACKEND_NULL_PARAM ) {
184 $type = null;
185 }
186 $searchEngine = $this->searchEngineFactory->create( $type );
187 $searchEngine->setNamespaces( $params['namespace'] );
188 $searchEngine->setLimitOffset( $params['limit'], $params['offset'] ?? 0 );
189
190 // Initialize requested search profiles.
191 $configs = $this->getSearchProfileParams();
192 foreach ( $configs as $paramName => $paramConfig ) {
193 if ( isset( $params[$paramName] ) ) {
194 $searchEngine->setFeatureData(
195 $paramConfig['profile-type'],
196 $params[$paramName]
197 );
198 }
199 }
200 return $searchEngine;
201 }
202
207 abstract public function getSearchProfileParams();
208
212 abstract public function getContext();
213}
getUser()
const NS_MAIN
Definition Defines.php:64
getSearchProfileParams()
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.
Definition SearchApi.php:65
getContext()
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, or 'string' with PARAM_ISMULTI,...
Definition ApiBase.php:211
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition ApiBase.php:171
Configuration handling class for SearchEngine.
Factory class for SearchEngine.
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:31
Interface for objects which can provide a MediaWiki context on request.