MediaWiki  master
ApiQueryLanguageinfo.php
Go to the documentation of this file.
1 <?php
26 use Wikimedia\Timestamp\ConvertibleTimestamp;
27 
34 
44  private const MAX_EXECUTE_SECONDS = 2;
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:1371
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
static setArrayType(array &$arr, $type, $kvpKeyName=null)
Set the array data type.
Definition: ApiResult.php:716
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
Definition: ApiResult.php:604
static bcp47( $code)
Get the normalised IETF language tag See unit test for examples.
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:1298
Service for formatting and validating API parameters.