MediaWiki REL1_39
ApiQueryLanguageinfo.php
Go to the documentation of this file.
1<?php
26use Wikimedia\Timestamp\ConvertibleTimestamp;
27
34
44 private const MAX_EXECUTE_SECONDS = 3;
45
47 private $languageFactory;
48
50 private $languageNameUtils;
51
53 private $languageFallback;
54
56 private $languageConverterFactory;
57
66 public function __construct(
67 ApiQuery $queryModule,
68 $moduleName,
69 LanguageFactory $languageFactory,
70 LanguageNameUtils $languageNameUtils,
71 LanguageFallback $languageFallback,
72 LanguageConverterFactory $languageConverterFactory
73 ) {
74 parent::__construct( $queryModule, $moduleName, 'li' );
75 $this->languageFactory = $languageFactory;
76 $this->languageNameUtils = $languageNameUtils;
77 $this->languageFallback = $languageFallback;
78 $this->languageConverterFactory = $languageConverterFactory;
79 }
80
81 public function execute() {
82 // ConvertibleTimestamp::time() used so we can fake the current time in tests
83 $endTime = ConvertibleTimestamp::time() + self::MAX_EXECUTE_SECONDS;
84
85 $props = array_fill_keys( $this->getParameter( 'prop' ), true );
86 $includeCode = isset( $props['code'] );
87 $includeBcp47 = isset( $props['bcp47'] );
88 $includeDir = isset( $props['dir'] );
89 $includeAutonym = isset( $props['autonym'] );
90 $includeName = isset( $props['name'] );
91 $includeFallbacks = isset( $props['fallbacks'] );
92 $includeVariants = isset( $props['variants'] );
93
94 $targetLanguageCode = $this->getLanguage()->getCode();
95 $include = 'all';
96
97 $availableLanguageCodes = array_keys( $this->languageNameUtils->getLanguageNames(
98 // MediaWiki and extensions may return different sets of language codes
99 // when asked for language names in different languages;
100 // asking for English language names is most likely to give us the full set,
101 // even though we may not need those at all
102 'en',
103 $include
104 ) );
105 $selectedLanguageCodes = $this->getParameter( 'code' );
106 if ( $selectedLanguageCodes === [ '*' ] ) {
107 $languageCodes = $availableLanguageCodes;
108 } else {
109 $languageCodes = array_values( array_intersect(
110 $availableLanguageCodes,
111 $selectedLanguageCodes
112 ) );
113 $unrecognizedCodes = array_values( array_diff(
114 $selectedLanguageCodes,
115 $availableLanguageCodes
116 ) );
117 if ( $unrecognizedCodes !== [] ) {
118 $this->addWarning( [
119 'apiwarn-unrecognizedvalues',
120 $this->encodeParamName( 'code' ),
121 Message::listParam( $unrecognizedCodes, 'comma' ),
122 count( $unrecognizedCodes ),
123 ] );
124 }
125 }
126 // order of $languageCodes is guaranteed by LanguageNameUtils::getLanguageNames()
127 // and preserved by array_values() + array_intersect()
128
129 $continue = $this->getParameter( 'continue' );
130 if ( $continue === null ) {
131 $continue = reset( $languageCodes );
132 }
133
134 $result = $this->getResult();
135 $rootPath = [
136 $this->getQuery()->getModuleName(),
137 $this->getModuleName(),
138 ];
139 $result->addArrayType( $rootPath, 'assoc' );
140
141 foreach ( $languageCodes as $languageCode ) {
142 if ( $languageCode < $continue ) {
143 continue;
144 }
145
146 $now = ConvertibleTimestamp::time();
147 if ( $now >= $endTime ) {
148 $this->setContinueEnumParameter( 'continue', $languageCode );
149 break;
150 }
151
152 $info = [];
153 ApiResult::setArrayType( $info, 'assoc' );
154
155 if ( $includeCode ) {
156 $info['code'] = $languageCode;
157 }
158
159 if ( $includeBcp47 ) {
160 $bcp47 = LanguageCode::bcp47( $languageCode );
161 $info['bcp47'] = $bcp47;
162 }
163
164 if ( $includeDir ) {
165 $dir = $this->languageFactory->getLanguage( $languageCode )->getDir();
166 $info['dir'] = $dir;
167 }
168
169 if ( $includeAutonym ) {
170 $autonym = $this->languageNameUtils->getLanguageName(
171 $languageCode,
172 LanguageNameUtils::AUTONYMS,
173 $include
174 );
175 $info['autonym'] = $autonym;
176 }
177
178 if ( $includeName ) {
179 $name = $this->languageNameUtils->getLanguageName(
180 $languageCode,
181 $targetLanguageCode,
182 $include
183 );
184 $info['name'] = $name;
185 }
186
187 if ( $includeFallbacks ) {
188 $fallbacks = $this->languageFallback->getAll(
189 $languageCode,
190 // allow users to distinguish between implicit and explicit 'en' fallbacks
191 LanguageFallback::STRICT
192 );
193 ApiResult::setIndexedTagName( $fallbacks, 'fb' );
194 $info['fallbacks'] = $fallbacks;
195 }
196
197 if ( $includeVariants ) {
198 $language = $this->languageFactory->getLanguage( $languageCode );
199 $converter = $this->languageConverterFactory->getLanguageConverter( $language );
200 $variants = $converter->getVariants();
201 ApiResult::setIndexedTagName( $variants, 'var' );
202 $info['variants'] = $variants;
203 }
204
205 $fit = $result->addValue( $rootPath, $languageCode, $info );
206 if ( !$fit ) {
207 $this->setContinueEnumParameter( 'continue', $languageCode );
208 break;
209 }
210 }
211 }
212
213 public function getCacheMode( $params ) {
214 return 'public';
215 }
216
217 public function getAllowedParams() {
218 return [
219 'prop' => [
220 ParamValidator::PARAM_DEFAULT => 'code',
221 ParamValidator::PARAM_ISMULTI => true,
222 ParamValidator::PARAM_TYPE => [
223 'code',
224 'bcp47',
225 'dir',
226 'autonym',
227 'name',
228 'fallbacks',
229 'variants',
230 ],
231 self::PARAM_HELP_MSG_PER_VALUE => [],
232 ],
233 'code' => [
234 ParamValidator::PARAM_DEFAULT => '*',
235 ParamValidator::PARAM_ISMULTI => true,
236 ],
237 'continue' => [
238 self::PARAM_HELP_MSG => 'api-help-param-continue',
239 ],
240 ];
241 }
242
243 protected function getExamplesMessages() {
244 $pathUrl = 'action=' . $this->getQuery()->getModuleName() .
245 '&meta=' . $this->getModuleName();
246 $pathMsg = $this->getModulePath();
247 $prefix = $this->getModulePrefix();
248
249 return [
250 "$pathUrl"
251 => "apihelp-$pathMsg-example-simple",
252 "$pathUrl&{$prefix}prop=autonym|name&uselang=de"
253 => "apihelp-$pathMsg-example-autonym-name-de",
254 "$pathUrl&{$prefix}prop=fallbacks|variants&{$prefix}code=oc"
255 => "apihelp-$pathMsg-example-fallbacks-variants-oc",
256 "$pathUrl&{$prefix}prop=bcp47|dir"
257 => "apihelp-$pathMsg-example-bcp47-dir",
258 ];
259 }
260
261}
getModulePrefix()
Get parameter prefix (usually two letters or an empty string).
Definition ApiBase.php:506
getParameter( $paramName, $parseLimit=true)
Get a value for the given parameter.
Definition ApiBase.php:886
encodeParamName( $paramName)
This method mangles parameter name based on the prefix supplied to the constructor.
Definition ApiBase.php:743
getResult()
Get the result object.
Definition ApiBase.php:629
getModulePath()
Get the path to this module.
Definition ApiBase.php:573
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition ApiBase.php:1372
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:498
This is a base class for all Query modules.
setContinueEnumParameter( $paramName, $paramValue)
Set a query-continue value.
getQuery()
Get the main Query module.
API module to enumerate language information.
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
getExamplesMessages()
Returns usage examples for this module.
__construct(ApiQuery $queryModule, $moduleName, LanguageFactory $languageFactory, LanguageNameUtils $languageNameUtils, LanguageFallback $languageFallback, LanguageConverterFactory $languageConverterFactory)
getCacheMode( $params)
Get the cache mode for the data generated by this module.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
This is the main query class.
Definition ApiQuery.php:41
An interface for creating language converters.
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
A service that provides utilities to do with language names and codes.
static listParam(array $list, $type='text')
Definition Message.php:1277
Service for formatting and validating API parameters.