Merge "Improved readability of MediaWikiParserTest::suite code"
[lhc/web/wiklou.git] / includes / api / ApiQuerySiteinfo.php
1 <?php
2 /**
3 *
4 *
5 * Created on Sep 25, 2006
6 *
7 * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 * http://www.gnu.org/copyleft/gpl.html
23 *
24 * @file
25 */
26
27 /**
28 * A query action to return meta information about the wiki site.
29 *
30 * @ingroup API
31 */
32 class ApiQuerySiteinfo extends ApiQueryBase {
33
34 public function __construct( $query, $moduleName ) {
35 parent::__construct( $query, $moduleName, 'si' );
36 }
37
38 public function execute() {
39 $params = $this->extractRequestParams();
40 $done = array();
41 $fit = false;
42 foreach ( $params['prop'] as $p ) {
43 switch ( $p ) {
44 case 'general':
45 $fit = $this->appendGeneralInfo( $p );
46 break;
47 case 'namespaces':
48 $fit = $this->appendNamespaces( $p );
49 break;
50 case 'namespacealiases':
51 $fit = $this->appendNamespaceAliases( $p );
52 break;
53 case 'specialpagealiases':
54 $fit = $this->appendSpecialPageAliases( $p );
55 break;
56 case 'magicwords':
57 $fit = $this->appendMagicWords( $p );
58 break;
59 case 'interwikimap':
60 $filteriw = isset( $params['filteriw'] ) ? $params['filteriw'] : false;
61 $fit = $this->appendInterwikiMap( $p, $filteriw );
62 break;
63 case 'dbrepllag':
64 $fit = $this->appendDbReplLagInfo( $p, $params['showalldb'] );
65 break;
66 case 'statistics':
67 $fit = $this->appendStatistics( $p );
68 break;
69 case 'usergroups':
70 $fit = $this->appendUserGroups( $p, $params['numberingroup'] );
71 break;
72 case 'extensions':
73 $fit = $this->appendExtensions( $p );
74 break;
75 case 'fileextensions':
76 $fit = $this->appendFileExtensions( $p );
77 break;
78 case 'rightsinfo':
79 $fit = $this->appendRightsInfo( $p );
80 break;
81 case 'languages':
82 $fit = $this->appendLanguages( $p );
83 break;
84 case 'skins':
85 $fit = $this->appendSkins( $p );
86 break;
87 case 'extensiontags':
88 $fit = $this->appendExtensionTags( $p );
89 break;
90 case 'functionhooks':
91 $fit = $this->appendFunctionHooks( $p );
92 break;
93 case 'showhooks':
94 $fit = $this->appendSubscribedHooks( $p );
95 break;
96 case 'variables':
97 $fit = $this->appendVariables( $p );
98 break;
99 case 'protocols':
100 $fit = $this->appendProtocols( $p );
101 break;
102 default:
103 ApiBase::dieDebug( __METHOD__, "Unknown prop=$p" );
104 }
105 if ( !$fit ) {
106 // Abuse siprop as a query-continue parameter
107 // and set it to all unprocessed props
108 $this->setContinueEnumParameter( 'prop', implode( '|',
109 array_diff( $params['prop'], $done ) ) );
110 break;
111 }
112 $done[] = $p;
113 }
114 }
115
116 protected function appendGeneralInfo( $property ) {
117 global $wgContLang,
118 $wgDisableLangConversion,
119 $wgDisableTitleConversion;
120
121 $data = array();
122 $mainPage = Title::newMainPage();
123 $data['mainpage'] = $mainPage->getPrefixedText();
124 $data['base'] = wfExpandUrl( $mainPage->getFullURL(), PROTO_CURRENT );
125 $data['sitename'] = $GLOBALS['wgSitename'];
126 $data['generator'] = "MediaWiki {$GLOBALS['wgVersion']}";
127 $data['phpversion'] = phpversion();
128 $data['phpsapi'] = PHP_SAPI;
129 $data['dbtype'] = $GLOBALS['wgDBtype'];
130 $data['dbversion'] = $this->getDB()->getServerVersion();
131
132 if ( !$wgDisableLangConversion ) {
133 $data['langconversion'] = '';
134 }
135
136 if ( !$wgDisableTitleConversion ) {
137 $data['titleconversion'] = '';
138 }
139
140 if ( $wgContLang->linkPrefixExtension() ) {
141 $data['linkprefix'] = wfMessage( 'linkprefix' )->inContentLanguage()->text();
142 } else {
143 $data['linkprefix'] = '';
144 }
145
146 $linktrail = $wgContLang->linkTrail();
147 if ( $linktrail ) {
148 $data['linktrail'] = $linktrail;
149 } else {
150 $data['linktrail'] = '';
151 }
152
153 $git = SpecialVersion::getGitHeadSha1( $GLOBALS['IP'] );
154 if ( $git ) {
155 $data['git-hash'] = $git;
156 } else {
157 $svn = SpecialVersion::getSvnRevision( $GLOBALS['IP'] );
158 if ( $svn ) {
159 $data['rev'] = $svn;
160 }
161 }
162
163 // 'case-insensitive' option is reserved for future
164 $data['case'] = $GLOBALS['wgCapitalLinks'] ? 'first-letter' : 'case-sensitive';
165
166 if ( isset( $GLOBALS['wgRightsCode'] ) ) {
167 $data['rightscode'] = $GLOBALS['wgRightsCode'];
168 }
169 $data['rights'] = $GLOBALS['wgRightsText'];
170 $data['lang'] = $GLOBALS['wgLanguageCode'];
171
172 $fallbacks = array();
173 foreach ( $wgContLang->getFallbackLanguages() as $code ) {
174 $fallbacks[] = array( 'code' => $code );
175 }
176 $data['fallback'] = $fallbacks;
177 $this->getResult()->setIndexedTagName( $data['fallback'], 'lang' );
178
179 if ( $wgContLang->hasVariants() ) {
180 $variants = array();
181 foreach ( $wgContLang->getVariants() as $code ) {
182 $variants[] = array( 'code' => $code );
183 }
184 $data['variants'] = $variants;
185 $this->getResult()->setIndexedTagName( $data['variants'], 'lang' );
186 }
187
188 if ( $wgContLang->isRTL() ) {
189 $data['rtl'] = '';
190 }
191 $data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
192
193 if ( wfReadOnly() ) {
194 $data['readonly'] = '';
195 $data['readonlyreason'] = wfReadOnlyReason();
196 }
197 if ( $GLOBALS['wgEnableWriteAPI'] ) {
198 $data['writeapi'] = '';
199 }
200
201 $tz = $GLOBALS['wgLocaltimezone'];
202 $offset = $GLOBALS['wgLocalTZoffset'];
203 if ( is_null( $tz ) ) {
204 $tz = 'UTC';
205 $offset = 0;
206 } elseif ( is_null( $offset ) ) {
207 $offset = 0;
208 }
209 $data['timezone'] = $tz;
210 $data['timeoffset'] = intval( $offset );
211 $data['articlepath'] = $GLOBALS['wgArticlePath'];
212 $data['scriptpath'] = $GLOBALS['wgScriptPath'];
213 $data['script'] = $GLOBALS['wgScript'];
214 $data['variantarticlepath'] = $GLOBALS['wgVariantArticlePath'];
215 $data['server'] = $GLOBALS['wgServer'];
216 $data['wikiid'] = wfWikiID();
217 $data['time'] = wfTimestamp( TS_ISO_8601, time() );
218
219 if ( $GLOBALS['wgMiserMode'] ) {
220 $data['misermode'] = '';
221 }
222
223 $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
224
225 wfRunHooks( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
226
227 return $this->getResult()->addValue( 'query', $property, $data );
228 }
229
230 protected function appendNamespaces( $property ) {
231 global $wgContLang;
232 $data = array();
233 foreach ( $wgContLang->getFormattedNamespaces() as $ns => $title ) {
234 $data[$ns] = array(
235 'id' => intval( $ns ),
236 'case' => MWNamespace::isCapitalized( $ns ) ? 'first-letter' : 'case-sensitive',
237 );
238 ApiResult::setContent( $data[$ns], $title );
239 $canonical = MWNamespace::getCanonicalName( $ns );
240
241 if ( MWNamespace::hasSubpages( $ns ) ) {
242 $data[$ns]['subpages'] = '';
243 }
244
245 if ( $canonical ) {
246 $data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
247 }
248
249 if ( MWNamespace::isContent( $ns ) ) {
250 $data[$ns]['content'] = '';
251 }
252
253 if ( MWNamespace::isNonincludable( $ns ) ) {
254 $data[$ns]['nonincludable'] = '';
255 }
256
257 $contentmodel = MWNamespace::getNamespaceContentModel( $ns );
258 if ( $contentmodel ) {
259 $data[$ns]['defaultcontentmodel'] = $contentmodel;
260 }
261 }
262
263 $this->getResult()->setIndexedTagName( $data, 'ns' );
264 return $this->getResult()->addValue( 'query', $property, $data );
265 }
266
267 protected function appendNamespaceAliases( $property ) {
268 global $wgNamespaceAliases, $wgContLang;
269 $aliases = array_merge( $wgNamespaceAliases, $wgContLang->getNamespaceAliases() );
270 $namespaces = $wgContLang->getNamespaces();
271 $data = array();
272 foreach ( $aliases as $title => $ns ) {
273 if ( $namespaces[$ns] == $title ) {
274 // Don't list duplicates
275 continue;
276 }
277 $item = array(
278 'id' => intval( $ns )
279 );
280 ApiResult::setContent( $item, strtr( $title, '_', ' ' ) );
281 $data[] = $item;
282 }
283
284 $this->getResult()->setIndexedTagName( $data, 'ns' );
285 return $this->getResult()->addValue( 'query', $property, $data );
286 }
287
288 protected function appendSpecialPageAliases( $property ) {
289 global $wgContLang;
290 $data = array();
291 $aliases = $wgContLang->getSpecialPageAliases();
292 foreach ( SpecialPageFactory::getList() as $specialpage => $stuff ) {
293 if ( isset( $aliases[$specialpage] ) ) {
294 $arr = array( 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] );
295 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
296 $data[] = $arr;
297 }
298 }
299 $this->getResult()->setIndexedTagName( $data, 'specialpage' );
300 return $this->getResult()->addValue( 'query', $property, $data );
301 }
302
303 protected function appendMagicWords( $property ) {
304 global $wgContLang;
305 $data = array();
306 foreach ( $wgContLang->getMagicWords() as $magicword => $aliases ) {
307 $caseSensitive = array_shift( $aliases );
308 $arr = array( 'name' => $magicword, 'aliases' => $aliases );
309 if ( $caseSensitive ) {
310 $arr['case-sensitive'] = '';
311 }
312 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
313 $data[] = $arr;
314 }
315 $this->getResult()->setIndexedTagName( $data, 'magicword' );
316 return $this->getResult()->addValue( 'query', $property, $data );
317 }
318
319 protected function appendInterwikiMap( $property, $filter ) {
320 $local = null;
321 if ( $filter === 'local' ) {
322 $local = 1;
323 } elseif ( $filter === '!local' ) {
324 $local = 0;
325 } elseif ( $filter ) {
326 ApiBase::dieDebug( __METHOD__, "Unknown filter=$filter" );
327 }
328
329 $params = $this->extractRequestParams();
330 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
331 $langNames = Language::fetchLanguageNames( $langCode );
332
333 $getPrefixes = Interwiki::getAllPrefixes( $local );
334 $data = array();
335
336 foreach ( $getPrefixes as $row ) {
337 $prefix = $row['iw_prefix'];
338 $val = array();
339 $val['prefix'] = $prefix;
340 if ( $row['iw_local'] == '1' ) {
341 $val['local'] = '';
342 }
343 // $val['trans'] = intval( $row['iw_trans'] ); // should this be exposed?
344 if ( isset( $langNames[$prefix] ) ) {
345 $val['language'] = $langNames[$prefix];
346 }
347 $val['url'] = wfExpandUrl( $row['iw_url'], PROTO_CURRENT );
348 if ( isset( $row['iw_wikiid'] ) ) {
349 $val['wikiid'] = $row['iw_wikiid'];
350 }
351 if ( isset( $row['iw_api'] ) ) {
352 $val['api'] = $row['iw_api'];
353 }
354
355 $data[] = $val;
356 }
357
358 $this->getResult()->setIndexedTagName( $data, 'iw' );
359 return $this->getResult()->addValue( 'query', $property, $data );
360 }
361
362 protected function appendDbReplLagInfo( $property, $includeAll ) {
363 global $wgShowHostnames;
364 $data = array();
365 $lb = wfGetLB();
366 if ( $includeAll ) {
367 if ( !$wgShowHostnames ) {
368 $this->dieUsage( 'Cannot view all servers info unless $wgShowHostnames is true', 'includeAllDenied' );
369 }
370
371 $lags = $lb->getLagTimes();
372 foreach ( $lags as $i => $lag ) {
373 $data[] = array(
374 'host' => $lb->getServerName( $i ),
375 'lag' => $lag
376 );
377 }
378 } else {
379 list( , $lag, $index ) = $lb->getMaxLag();
380 $data[] = array(
381 'host' => $wgShowHostnames
382 ? $lb->getServerName( $index )
383 : '',
384 'lag' => intval( $lag )
385 );
386 }
387
388 $result = $this->getResult();
389 $result->setIndexedTagName( $data, 'db' );
390 return $this->getResult()->addValue( 'query', $property, $data );
391 }
392
393 protected function appendStatistics( $property ) {
394 global $wgDisableCounters;
395 $data = array();
396 $data['pages'] = intval( SiteStats::pages() );
397 $data['articles'] = intval( SiteStats::articles() );
398 if ( !$wgDisableCounters ) {
399 $data['views'] = intval( SiteStats::views() );
400 }
401 $data['edits'] = intval( SiteStats::edits() );
402 $data['images'] = intval( SiteStats::images() );
403 $data['users'] = intval( SiteStats::users() );
404 $data['activeusers'] = intval( SiteStats::activeUsers() );
405 $data['admins'] = intval( SiteStats::numberingroup( 'sysop' ) );
406 $data['jobs'] = intval( SiteStats::jobs() );
407 return $this->getResult()->addValue( 'query', $property, $data );
408 }
409
410 protected function appendUserGroups( $property, $numberInGroup ) {
411 global $wgGroupPermissions, $wgAddGroups, $wgRemoveGroups, $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf;
412
413 $data = array();
414 $result = $this->getResult();
415 foreach ( $wgGroupPermissions as $group => $permissions ) {
416 $arr = array(
417 'name' => $group,
418 'rights' => array_keys( $permissions, true ),
419 );
420
421 if ( $numberInGroup ) {
422 global $wgAutopromote;
423
424 if ( $group == 'user' ) {
425 $arr['number'] = SiteStats::users();
426
427 // '*' and autopromote groups have no size
428 } elseif ( $group !== '*' && !isset( $wgAutopromote[$group] ) ) {
429 $arr['number'] = SiteStats::numberInGroup( $group );
430 }
431 }
432
433 $groupArr = array(
434 'add' => $wgAddGroups,
435 'remove' => $wgRemoveGroups,
436 'add-self' => $wgGroupsAddToSelf,
437 'remove-self' => $wgGroupsRemoveFromSelf
438 );
439
440 foreach ( $groupArr as $type => $rights ) {
441 if ( isset( $rights[$group] ) ) {
442 $arr[$type] = $rights[$group];
443 $result->setIndexedTagName( $arr[$type], 'group' );
444 }
445 }
446
447 $result->setIndexedTagName( $arr['rights'], 'permission' );
448 $data[] = $arr;
449 }
450
451 $result->setIndexedTagName( $data, 'group' );
452 return $result->addValue( 'query', $property, $data );
453 }
454
455 protected function appendFileExtensions( $property ) {
456 global $wgFileExtensions;
457
458 $data = array();
459 foreach ( $wgFileExtensions as $ext ) {
460 $data[] = array( 'ext' => $ext );
461 }
462 $this->getResult()->setIndexedTagName( $data, 'fe' );
463 return $this->getResult()->addValue( 'query', $property, $data );
464 }
465
466 protected function appendExtensions( $property ) {
467 global $wgExtensionCredits;
468 $data = array();
469 foreach ( $wgExtensionCredits as $type => $extensions ) {
470 foreach ( $extensions as $ext ) {
471 $ret = array();
472 $ret['type'] = $type;
473 if ( isset( $ext['name'] ) ) {
474 $ret['name'] = $ext['name'];
475 }
476 if ( isset( $ext['description'] ) ) {
477 $ret['description'] = $ext['description'];
478 }
479 if ( isset( $ext['descriptionmsg'] ) ) {
480 // Can be a string or array( key, param1, param2, ... )
481 if ( is_array( $ext['descriptionmsg'] ) ) {
482 $ret['descriptionmsg'] = $ext['descriptionmsg'][0];
483 $ret['descriptionmsgparams'] = array_slice( $ext['descriptionmsg'], 1 );
484 $this->getResult()->setIndexedTagName( $ret['descriptionmsgparams'], 'param' );
485 } else {
486 $ret['descriptionmsg'] = $ext['descriptionmsg'];
487 }
488 }
489 if ( isset( $ext['author'] ) ) {
490 $ret['author'] = is_array( $ext['author'] ) ?
491 implode( ', ', $ext['author'] ) : $ext['author'];
492 }
493 if ( isset( $ext['url'] ) ) {
494 $ret['url'] = $ext['url'];
495 }
496 if ( isset( $ext['version'] ) ) {
497 $ret['version'] = $ext['version'];
498 } elseif ( isset( $ext['svn-revision'] ) &&
499 preg_match( '/\$(?:Rev|LastChangedRevision|Revision): *(\d+)/',
500 $ext['svn-revision'], $m ) )
501 {
502 $ret['version'] = 'r' . $m[1];
503 }
504 $data[] = $ret;
505 }
506 }
507
508 $this->getResult()->setIndexedTagName( $data, 'ext' );
509 return $this->getResult()->addValue( 'query', $property, $data );
510 }
511
512 protected function appendRightsInfo( $property ) {
513 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
514 $title = Title::newFromText( $wgRightsPage );
515 $url = $title ? wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ) : $wgRightsUrl;
516 $text = $wgRightsText;
517 if ( !$text && $title ) {
518 $text = $title->getPrefixedText();
519 }
520
521 $data = array(
522 'url' => $url ? $url : '',
523 'text' => $text ? $text : ''
524 );
525
526 return $this->getResult()->addValue( 'query', $property, $data );
527 }
528
529 public function appendLanguages( $property ) {
530 $params = $this->extractRequestParams();
531 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
532 $langNames = Language::fetchLanguageNames( $langCode );
533
534 $data = array();
535
536 foreach ( $langNames as $code => $name ) {
537 $lang = array( 'code' => $code );
538 ApiResult::setContent( $lang, $name );
539 $data[] = $lang;
540 }
541 $this->getResult()->setIndexedTagName( $data, 'lang' );
542 return $this->getResult()->addValue( 'query', $property, $data );
543 }
544
545 public function appendSkins( $property ) {
546 $data = array();
547 foreach ( Skin::getSkinNames() as $name => $displayName ) {
548 $skin = array( 'code' => $name );
549 ApiResult::setContent( $skin, $displayName );
550 $data[] = $skin;
551 }
552 $this->getResult()->setIndexedTagName( $data, 'skin' );
553 return $this->getResult()->addValue( 'query', $property, $data );
554 }
555
556 public function appendExtensionTags( $property ) {
557 global $wgParser;
558 $wgParser->firstCallInit();
559 $tags = array_map( array( $this, 'formatParserTags' ), $wgParser->getTags() );
560 $this->getResult()->setIndexedTagName( $tags, 't' );
561 return $this->getResult()->addValue( 'query', $property, $tags );
562 }
563
564 public function appendFunctionHooks( $property ) {
565 global $wgParser;
566 $wgParser->firstCallInit();
567 $hooks = $wgParser->getFunctionHooks();
568 $this->getResult()->setIndexedTagName( $hooks, 'h' );
569 return $this->getResult()->addValue( 'query', $property, $hooks );
570 }
571
572 public function appendVariables( $property ) {
573 $variables = MagicWord::getVariableIDs();
574 $this->getResult()->setIndexedTagName( $variables, 'v' );
575 return $this->getResult()->addValue( 'query', $property, $variables );
576 }
577
578 public function appendProtocols( $property ) {
579 global $wgUrlProtocols;
580 // Make a copy of the global so we don't try to set the _element key of it - bug 45130
581 $protocols = array_values( $wgUrlProtocols );
582 $this->getResult()->setIndexedTagName( $protocols, 'p' );
583 return $this->getResult()->addValue( 'query', $property, $protocols );
584 }
585
586 private function formatParserTags( $item ) {
587 return "<{$item}>";
588 }
589
590 public function appendSubscribedHooks( $property ) {
591 global $wgHooks;
592 $myWgHooks = $wgHooks;
593 ksort( $myWgHooks );
594
595 $data = array();
596 foreach ( $myWgHooks as $hook => $hooks ) {
597 $arr = array(
598 'name' => $hook,
599 'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $hooks ),
600 );
601
602 $this->getResult()->setIndexedTagName( $arr['subscribers'], 's' );
603 $data[] = $arr;
604 }
605
606 $this->getResult()->setIndexedTagName( $data, 'hook' );
607 return $this->getResult()->addValue( 'query', $property, $data );
608 }
609
610 public function getCacheMode( $params ) {
611 return 'public';
612 }
613
614 public function getAllowedParams() {
615 return array(
616 'prop' => array(
617 ApiBase::PARAM_DFLT => 'general',
618 ApiBase::PARAM_ISMULTI => true,
619 ApiBase::PARAM_TYPE => array(
620 'general',
621 'namespaces',
622 'namespacealiases',
623 'specialpagealiases',
624 'magicwords',
625 'interwikimap',
626 'dbrepllag',
627 'statistics',
628 'usergroups',
629 'extensions',
630 'fileextensions',
631 'rightsinfo',
632 'languages',
633 'skins',
634 'extensiontags',
635 'functionhooks',
636 'showhooks',
637 'variables',
638 'protocols',
639 )
640 ),
641 'filteriw' => array(
642 ApiBase::PARAM_TYPE => array(
643 'local',
644 '!local',
645 )
646 ),
647 'showalldb' => false,
648 'numberingroup' => false,
649 'inlanguagecode' => null,
650 );
651 }
652
653 public function getParamDescription() {
654 $p = $this->getModulePrefix();
655 return array(
656 'prop' => array(
657 'Which sysinfo properties to get:',
658 ' general - Overall system information',
659 ' namespaces - List of registered namespaces and their canonical names',
660 ' namespacealiases - List of registered namespace aliases',
661 ' specialpagealiases - List of special page aliases',
662 ' magicwords - List of magic words and their aliases',
663 ' statistics - Returns site statistics',
664 " interwikimap - Returns interwiki map (optionally filtered, (optionally localised by using {$p}inlanguagecode))",
665 ' dbrepllag - Returns database server with the highest replication lag',
666 ' usergroups - Returns user groups and the associated permissions',
667 ' extensions - Returns extensions installed on the wiki',
668 ' fileextensions - Returns list of file extensions allowed to be uploaded',
669 ' rightsinfo - Returns wiki rights (license) information if available',
670 " languages - Returns a list of languages MediaWiki supports (optionally localised by using {$p}inlanguagecode)",
671 ' skins - Returns a list of all enabled skins',
672 ' extensiontags - Returns a list of parser extension tags',
673 ' functionhooks - Returns a list of parser function hooks',
674 ' showhooks - Returns a list of all subscribed hooks (contents of $wgHooks)',
675 ' variables - Returns a list of variable IDs',
676 ' protocols - Returns a list of protocols that are allowed in external links.',
677 ),
678 'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
679 'showalldb' => 'List all database servers, not just the one lagging the most',
680 'numberingroup' => 'Lists the number of users in user groups',
681 'inlanguagecode' => 'Language code for localised language names (best effort, use CLDR extension)',
682 );
683 }
684
685 public function getDescription() {
686 return 'Return general information about the site';
687 }
688
689 public function getPossibleErrors() {
690 return array_merge( parent::getPossibleErrors(), array(
691 array( 'code' => 'includeAllDenied', 'info' => 'Cannot view all servers info unless $wgShowHostnames is true' ),
692 ) );
693 }
694
695 public function getExamples() {
696 return array(
697 'api.php?action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics',
698 'api.php?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local',
699 'api.php?action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb=',
700 );
701 }
702
703 public function getHelpUrls() {
704 return 'https://www.mediawiki.org/wiki/API:Meta#siteinfo_.2F_si';
705 }
706 }