Merge "(bug 17602) fix Monobook action tabs not quite touching the page body"
[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 $usable = Skin::getUsableSkins();
548 $default = Skin::normalizeKey( 'default' );
549 foreach ( Skin::getSkinNames() as $name => $displayName ) {
550 $skin = array( 'code' => $name );
551 ApiResult::setContent( $skin, $displayName );
552 if ( !isset( $usable[$name] ) ) {
553 $skin['unusable'] = '';
554 }
555 if ( $name === $default ) {
556 $skin['default'] = '';
557 }
558 $data[] = $skin;
559 }
560 $this->getResult()->setIndexedTagName( $data, 'skin' );
561 return $this->getResult()->addValue( 'query', $property, $data );
562 }
563
564 public function appendExtensionTags( $property ) {
565 global $wgParser;
566 $wgParser->firstCallInit();
567 $tags = array_map( array( $this, 'formatParserTags' ), $wgParser->getTags() );
568 $this->getResult()->setIndexedTagName( $tags, 't' );
569 return $this->getResult()->addValue( 'query', $property, $tags );
570 }
571
572 public function appendFunctionHooks( $property ) {
573 global $wgParser;
574 $wgParser->firstCallInit();
575 $hooks = $wgParser->getFunctionHooks();
576 $this->getResult()->setIndexedTagName( $hooks, 'h' );
577 return $this->getResult()->addValue( 'query', $property, $hooks );
578 }
579
580 public function appendVariables( $property ) {
581 $variables = MagicWord::getVariableIDs();
582 $this->getResult()->setIndexedTagName( $variables, 'v' );
583 return $this->getResult()->addValue( 'query', $property, $variables );
584 }
585
586 public function appendProtocols( $property ) {
587 global $wgUrlProtocols;
588 // Make a copy of the global so we don't try to set the _element key of it - bug 45130
589 $protocols = array_values( $wgUrlProtocols );
590 $this->getResult()->setIndexedTagName( $protocols, 'p' );
591 return $this->getResult()->addValue( 'query', $property, $protocols );
592 }
593
594 private function formatParserTags( $item ) {
595 return "<{$item}>";
596 }
597
598 public function appendSubscribedHooks( $property ) {
599 global $wgHooks;
600 $myWgHooks = $wgHooks;
601 ksort( $myWgHooks );
602
603 $data = array();
604 foreach ( $myWgHooks as $hook => $hooks ) {
605 $arr = array(
606 'name' => $hook,
607 'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $hooks ),
608 );
609
610 $this->getResult()->setIndexedTagName( $arr['subscribers'], 's' );
611 $data[] = $arr;
612 }
613
614 $this->getResult()->setIndexedTagName( $data, 'hook' );
615 return $this->getResult()->addValue( 'query', $property, $data );
616 }
617
618 public function getCacheMode( $params ) {
619 return 'public';
620 }
621
622 public function getAllowedParams() {
623 return array(
624 'prop' => array(
625 ApiBase::PARAM_DFLT => 'general',
626 ApiBase::PARAM_ISMULTI => true,
627 ApiBase::PARAM_TYPE => array(
628 'general',
629 'namespaces',
630 'namespacealiases',
631 'specialpagealiases',
632 'magicwords',
633 'interwikimap',
634 'dbrepllag',
635 'statistics',
636 'usergroups',
637 'extensions',
638 'fileextensions',
639 'rightsinfo',
640 'languages',
641 'skins',
642 'extensiontags',
643 'functionhooks',
644 'showhooks',
645 'variables',
646 'protocols',
647 )
648 ),
649 'filteriw' => array(
650 ApiBase::PARAM_TYPE => array(
651 'local',
652 '!local',
653 )
654 ),
655 'showalldb' => false,
656 'numberingroup' => false,
657 'inlanguagecode' => null,
658 );
659 }
660
661 public function getParamDescription() {
662 $p = $this->getModulePrefix();
663 return array(
664 'prop' => array(
665 'Which sysinfo properties to get:',
666 ' general - Overall system information',
667 ' namespaces - List of registered namespaces and their canonical names',
668 ' namespacealiases - List of registered namespace aliases',
669 ' specialpagealiases - List of special page aliases',
670 ' magicwords - List of magic words and their aliases',
671 ' statistics - Returns site statistics',
672 " interwikimap - Returns interwiki map (optionally filtered, (optionally localised by using {$p}inlanguagecode))",
673 ' dbrepllag - Returns database server with the highest replication lag',
674 ' usergroups - Returns user groups and the associated permissions',
675 ' extensions - Returns extensions installed on the wiki',
676 ' fileextensions - Returns list of file extensions allowed to be uploaded',
677 ' rightsinfo - Returns wiki rights (license) information if available',
678 " languages - Returns a list of languages MediaWiki supports (optionally localised by using {$p}inlanguagecode)",
679 ' skins - Returns a list of all enabled skins',
680 ' extensiontags - Returns a list of parser extension tags',
681 ' functionhooks - Returns a list of parser function hooks',
682 ' showhooks - Returns a list of all subscribed hooks (contents of $wgHooks)',
683 ' variables - Returns a list of variable IDs',
684 ' protocols - Returns a list of protocols that are allowed in external links.',
685 ),
686 'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
687 'showalldb' => 'List all database servers, not just the one lagging the most',
688 'numberingroup' => 'Lists the number of users in user groups',
689 'inlanguagecode' => 'Language code for localised language names (best effort, use CLDR extension)',
690 );
691 }
692
693 public function getDescription() {
694 return 'Return general information about the site';
695 }
696
697 public function getPossibleErrors() {
698 return array_merge( parent::getPossibleErrors(), array(
699 array( 'code' => 'includeAllDenied', 'info' => 'Cannot view all servers info unless $wgShowHostnames is true' ),
700 ) );
701 }
702
703 public function getExamples() {
704 return array(
705 'api.php?action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics',
706 'api.php?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local',
707 'api.php?action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb=',
708 );
709 }
710
711 public function getHelpUrls() {
712 return 'https://www.mediawiki.org/wiki/API:Meta#siteinfo_.2F_si';
713 }
714 }