MediaWiki  master
ApiQueryAllMessages.php
Go to the documentation of this file.
1 <?php
28 
35 
36  private Language $contentLanguage;
37  private LanguageFactory $languageFactory;
38  private LanguageNameUtils $languageNameUtils;
39  private LocalisationCache $localisationCache;
40  private MessageCache $messageCache;
41 
51  public function __construct(
52  ApiQuery $query,
53  $moduleName,
54  Language $contentLanguage,
55  LanguageFactory $languageFactory,
56  LanguageNameUtils $languageNameUtils,
57  LocalisationCache $localisationCache,
58  MessageCache $messageCache
59  ) {
60  parent::__construct( $query, $moduleName, 'am' );
61  $this->contentLanguage = $contentLanguage;
62  $this->languageFactory = $languageFactory;
63  $this->languageNameUtils = $languageNameUtils;
64  $this->localisationCache = $localisationCache;
65  $this->messageCache = $messageCache;
66  }
67 
68  public function execute() {
69  $params = $this->extractRequestParams();
70  if ( $params['lang'] === null ) {
71  $langObj = $this->getLanguage();
72  } elseif ( !$this->languageNameUtils->isValidCode( $params['lang'] ) ) {
73  $this->dieWithError(
74  [ 'apierror-invalidlang', $this->encodeParamName( 'lang' ) ], 'invalidlang'
75  );
76  } else {
77  $langObj = $this->languageFactory->getLanguage( $params['lang'] );
78  }
79 
80  if ( $params['enableparser'] ) {
81  if ( $params['title'] !== null ) {
82  $title = Title::newFromText( $params['title'] );
83  if ( !$title || $title->isExternal() ) {
84  $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
85  }
86  } else {
87  $title = Title::newFromText( 'API' );
88  }
89  }
90 
91  $prop = array_fill_keys( (array)$params['prop'], true );
92 
93  // Determine which messages should we print
94  if ( in_array( '*', $params['messages'] ) ) {
95  $message_names = $this->localisationCache->getSubitemList( $langObj->getCode(), 'messages' ) ?? [];
96  if ( $params['includelocal'] ) {
97  $message_names = array_unique( array_merge(
98  $message_names,
99  // Pass in the content language code so we get local messages that have a
100  // MediaWiki:msgkey page. We might theoretically miss messages that have no
101  // MediaWiki:msgkey page but do have a MediaWiki:msgkey/lang page, but that's
102  // just a stupid case.
103  $this->messageCache->getAllMessageKeys( $this->contentLanguage->getCode() )
104  ) );
105  }
106  sort( $message_names );
107  $messages_target = $message_names;
108  } else {
109  $messages_target = $params['messages'];
110  }
111 
112  // Filter messages that have the specified prefix
113  // Because we sorted the message array earlier, they will appear in a clump:
114  if ( isset( $params['prefix'] ) ) {
115  $skip = false;
116  $messages_filtered = [];
117  foreach ( $messages_target as $message ) {
118  if ( str_starts_with( $message, $params['prefix'] ) ) {
119  if ( !$skip ) {
120  $skip = true;
121  }
122  $messages_filtered[] = $message;
123  } elseif ( $skip ) {
124  break;
125  }
126  }
127  $messages_target = $messages_filtered;
128  }
129 
130  // Filter messages that contain specified string
131  if ( isset( $params['filter'] ) ) {
132  $messages_filtered = [];
133  foreach ( $messages_target as $message ) {
134  if ( str_contains( $message, $params['filter'] ) ) {
135  $messages_filtered[] = $message;
136  }
137  }
138  $messages_target = $messages_filtered;
139  }
140 
141  // Whether we have any sort of message customisation filtering
142  $customiseFilterEnabled = $params['customised'] !== 'all';
143  if ( $customiseFilterEnabled ) {
144  $customisedMessages = AllMessagesTablePager::getCustomisedStatuses(
145  array_map(
146  [ $langObj, 'ucfirst' ],
147  $messages_target
148  ),
149  $langObj->getCode(),
150  !$langObj->equals( $this->contentLanguage ),
151  $this->getDB()
152  );
153 
154  $customised = $params['customised'] === 'modified';
155  }
156 
157  // Get all requested messages and print the result
158  $skip = $params['from'] !== null;
159  $useto = $params['to'] !== null;
160  $result = $this->getResult();
161  foreach ( $messages_target as $message ) {
162  // Skip all messages up to $params['from']
163  if ( $skip && $message === $params['from'] ) {
164  $skip = false;
165  }
166 
167  if ( $useto && $message > $params['to'] ) {
168  break;
169  }
170 
171  if ( !$skip ) {
172  $a = [
173  'name' => $message,
174  'normalizedname' => MessageCache::normalizeKey( $message ),
175  ];
176 
177  $args = [];
178  if ( isset( $params['args'] ) && count( $params['args'] ) != 0 ) {
179  $args = $params['args'];
180  }
181 
182  if ( $customiseFilterEnabled ) {
183  $messageIsCustomised = isset( $customisedMessages['pages'][$langObj->ucfirst( $message )] );
184  // @phan-suppress-next-line PhanPossiblyUndeclaredVariable customised is set when used
185  if ( $customised === $messageIsCustomised ) {
186  // @phan-suppress-next-line PhanPossiblyUndeclaredVariable customised is set when used
187  if ( $customised ) {
188  $a['customised'] = true;
189  }
190  } else {
191  continue;
192  }
193  }
194 
195  $msg = $this->msg( $message, $args )->inLanguage( $langObj );
196 
197  if ( !$msg->exists() ) {
198  $a['missing'] = true;
199  } else {
200  // Check if the parser is enabled:
201  if ( $params['enableparser'] ) {
202  // @phan-suppress-next-line PhanPossiblyUndeclaredVariable title is set when used
203  $msgString = $msg->page( $title )->text();
204  } else {
205  $msgString = $msg->plain();
206  }
207  if ( !$params['nocontent'] ) {
208  ApiResult::setContentValue( $a, 'content', $msgString );
209  }
210  if ( isset( $prop['default'] ) ) {
211  $default = $this->msg( $message )->inLanguage( $langObj )->useDatabase( false );
212  if ( !$default->exists() ) {
213  $a['defaultmissing'] = true;
214  } elseif ( $default->plain() != $msgString ) {
215  $a['default'] = $default->plain();
216  }
217  }
218  }
219  $fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $a );
220  if ( !$fit ) {
221  $this->setContinueEnumParameter( 'from', $message );
222  break;
223  }
224  }
225  }
226  $result->addIndexedTagName( [ 'query', $this->getModuleName() ], 'message' );
227  }
228 
229  public function getCacheMode( $params ) {
230  if ( $params['lang'] === null ) {
231  // Language not specified, will be fetched from preferences
232  return 'anon-public-user-private';
233  } elseif ( $params['enableparser'] ) {
234  // User-specific parser options will be used
235  return 'anon-public-user-private';
236  } else {
237  // OK to cache
238  return 'public';
239  }
240  }
241 
242  public function getAllowedParams() {
243  return [
244  'messages' => [
245  ParamValidator::PARAM_DEFAULT => '*',
246  ParamValidator::PARAM_ISMULTI => true,
247  ],
248  'prop' => [
249  ParamValidator::PARAM_ISMULTI => true,
250  ParamValidator::PARAM_TYPE => [
251  'default'
252  ]
253  ],
254  'enableparser' => false,
255  'nocontent' => false,
256  'includelocal' => false,
257  'args' => [
258  ParamValidator::PARAM_ISMULTI => true,
259  ParamValidator::PARAM_ALLOW_DUPLICATES => true,
260  ],
261  'filter' => [],
262  'customised' => [
263  ParamValidator::PARAM_DEFAULT => 'all',
264  ParamValidator::PARAM_TYPE => [
265  'all',
266  'modified',
267  'unmodified'
268  ]
269  ],
270  'lang' => null,
271  'from' => null,
272  'to' => null,
273  'title' => null,
274  'prefix' => null,
275  ];
276  }
277 
278  protected function getExamplesMessages() {
279  return [
280  'action=query&meta=allmessages&amprefix=ipb-'
281  => 'apihelp-query+allmessages-example-ipb',
282  'action=query&meta=allmessages&ammessages=august|mainpage&amlang=de'
283  => 'apihelp-query+allmessages-example-de',
284  ];
285  }
286 
287  public function getHelpUrls() {
288  return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Allmessages';
289  }
290 }
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition: ApiBase.php:1515
encodeParamName( $paramName)
This method mangles parameter name based on the prefix supplied to the constructor.
Definition: ApiBase.php:785
getResult()
Get the result object.
Definition: ApiBase.php:667
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition: ApiBase.php:807
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:528
A query action to return messages from site message cache.
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
getCacheMode( $params)
Get the cache mode for the data generated by this module.
getHelpUrls()
Return links to more detailed help pages about the module.
__construct(ApiQuery $query, $moduleName, Language $contentLanguage, LanguageFactory $languageFactory, LanguageNameUtils $languageNameUtils, LocalisationCache $localisationCache, MessageCache $messageCache)
getExamplesMessages()
Returns usage examples for this module.
This is a base class for all Query modules.
setContinueEnumParameter( $paramName, $paramValue)
Set a query-continue value.
This is the main query class.
Definition: ApiQuery.php:43
static setContentValue(array &$arr, $name, $value, $flags=0)
Add an output value to the array by name and mark as META_CONTENT.
Definition: ApiResult.php:467
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Base class for language-specific code.
Definition: Language.php:63
Caching for the contents of localisation files.
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.
Use TablePager for prettified output.
Represents a title within MediaWiki.
Definition: Title.php:76
Cache messages that are defined by MediaWiki-namespace pages or by hooks.
static normalizeKey( $key)
Normalize message key input.
Service for formatting and validating API parameters.