API: allow disabling TOC in action=parse
[mediawiki.git] / includes / api / ApiQuerySiteinfo.php
bloba94f5bbf0af57dd38d0b5ae8ed5d91d6f58a1492
1 <?php
2 /**
5 * Created on Sep 25, 2006
7 * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
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.
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.
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
24 * @file
27 /**
28 * A query action to return meta information about the wiki site.
30 * @ingroup API
32 class ApiQuerySiteinfo extends ApiQueryBase {
34 public function __construct( $query, $moduleName ) {
35 parent::__construct( $query, $moduleName, 'si' );
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 case 'defaultoptions':
103 $fit = $this->appendDefaultOptions( $p );
104 break;
105 default:
106 ApiBase::dieDebug( __METHOD__, "Unknown prop=$p" );
108 if ( !$fit ) {
109 // Abuse siprop as a query-continue parameter
110 // and set it to all unprocessed props
111 $this->setContinueEnumParameter( 'prop', implode( '|',
112 array_diff( $params['prop'], $done ) ) );
113 break;
115 $done[] = $p;
119 protected function appendGeneralInfo( $property ) {
120 global $wgContLang, $wgDisableLangConversion, $wgDisableTitleConversion;
122 $data = array();
123 $mainPage = Title::newMainPage();
124 $data['mainpage'] = $mainPage->getPrefixedText();
125 $data['base'] = wfExpandUrl( $mainPage->getFullURL(), PROTO_CURRENT );
126 $data['sitename'] = $GLOBALS['wgSitename'];
127 $data['logo'] = $GLOBALS['wgLogo'];
128 $data['generator'] = "MediaWiki {$GLOBALS['wgVersion']}";
129 $data['phpversion'] = phpversion();
130 $data['phpsapi'] = PHP_SAPI;
131 $data['dbtype'] = $GLOBALS['wgDBtype'];
132 $data['dbversion'] = $this->getDB()->getServerVersion();
134 $allowFrom = array( '' );
135 $allowException = true;
136 if ( !$GLOBALS['wgAllowExternalImages'] ) {
137 if ( $GLOBALS['wgEnableImageWhitelist'] ) {
138 $data['imagewhitelistenabled'] = '';
140 $allowFrom = $GLOBALS['wgAllowExternalImagesFrom'];
141 $allowException = !empty( $allowFrom );
143 if ( $allowException ) {
144 $data['externalimages'] = (array)$allowFrom;
145 $this->getResult()->setIndexedTagName( $data['externalimages'], 'prefix' );
148 if ( !$wgDisableLangConversion ) {
149 $data['langconversion'] = '';
152 if ( !$wgDisableTitleConversion ) {
153 $data['titleconversion'] = '';
156 if ( $wgContLang->linkPrefixExtension() ) {
157 $linkPrefixCharset = $wgContLang->linkPrefixCharset();
158 $data['linkprefixcharset'] = $linkPrefixCharset;
159 // For backwards compatability
160 $data['linkprefix'] = "/^((?>.*[^$linkPrefixCharset]|))(.+)$/sDu";
161 } else {
162 $data['linkprefixcharset'] = '';
163 $data['linkprefix'] = '';
166 $linktrail = $wgContLang->linkTrail();
167 if ( $linktrail ) {
168 $data['linktrail'] = $linktrail;
169 } else {
170 $data['linktrail'] = '';
173 $git = SpecialVersion::getGitHeadSha1( $GLOBALS['IP'] );
174 if ( $git ) {
175 $data['git-hash'] = $git;
176 } else {
177 $svn = SpecialVersion::getSvnRevision( $GLOBALS['IP'] );
178 if ( $svn ) {
179 $data['rev'] = $svn;
183 // 'case-insensitive' option is reserved for future
184 $data['case'] = $GLOBALS['wgCapitalLinks'] ? 'first-letter' : 'case-sensitive';
186 if ( isset( $GLOBALS['wgRightsCode'] ) ) {
187 $data['rightscode'] = $GLOBALS['wgRightsCode'];
189 $data['rights'] = $GLOBALS['wgRightsText'];
190 $data['lang'] = $GLOBALS['wgLanguageCode'];
192 $fallbacks = array();
193 foreach ( $wgContLang->getFallbackLanguages() as $code ) {
194 $fallbacks[] = array( 'code' => $code );
196 $data['fallback'] = $fallbacks;
197 $this->getResult()->setIndexedTagName( $data['fallback'], 'lang' );
199 if ( $wgContLang->hasVariants() ) {
200 $variants = array();
201 foreach ( $wgContLang->getVariants() as $code ) {
202 $variants[] = array( 'code' => $code );
204 $data['variants'] = $variants;
205 $this->getResult()->setIndexedTagName( $data['variants'], 'lang' );
208 if ( $wgContLang->isRTL() ) {
209 $data['rtl'] = '';
211 $data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
213 if ( wfReadOnly() ) {
214 $data['readonly'] = '';
215 $data['readonlyreason'] = wfReadOnlyReason();
217 if ( $GLOBALS['wgEnableWriteAPI'] ) {
218 $data['writeapi'] = '';
221 $tz = $GLOBALS['wgLocaltimezone'];
222 $offset = $GLOBALS['wgLocalTZoffset'];
223 if ( is_null( $tz ) ) {
224 $tz = 'UTC';
225 $offset = 0;
226 } elseif ( is_null( $offset ) ) {
227 $offset = 0;
229 $data['timezone'] = $tz;
230 $data['timeoffset'] = intval( $offset );
231 $data['articlepath'] = $GLOBALS['wgArticlePath'];
232 $data['scriptpath'] = $GLOBALS['wgScriptPath'];
233 $data['script'] = $GLOBALS['wgScript'];
234 $data['variantarticlepath'] = $GLOBALS['wgVariantArticlePath'];
235 $data['server'] = $GLOBALS['wgServer'];
236 $data['wikiid'] = wfWikiID();
237 $data['time'] = wfTimestamp( TS_ISO_8601, time() );
239 if ( $GLOBALS['wgMiserMode'] ) {
240 $data['misermode'] = '';
243 $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
245 $data['thumblimits'] = $GLOBALS['wgThumbLimits'];
246 $this->getResult()->setIndexedTagName( $data['thumblimits'], 'limit' );
247 $data['imagelimits'] = array();
248 $this->getResult()->setIndexedTagName( $data['imagelimits'], 'limit' );
249 foreach ( $GLOBALS['wgImageLimits'] as $k => $limit ) {
250 $data['imagelimits'][$k] = array( 'width' => $limit[0], 'height' => $limit[1] );
253 wfRunHooks( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
255 return $this->getResult()->addValue( 'query', $property, $data );
258 protected function appendNamespaces( $property ) {
259 global $wgContLang;
260 $data = array();
261 foreach ( $wgContLang->getFormattedNamespaces() as $ns => $title ) {
262 $data[$ns] = array(
263 'id' => intval( $ns ),
264 'case' => MWNamespace::isCapitalized( $ns ) ? 'first-letter' : 'case-sensitive',
266 ApiResult::setContent( $data[$ns], $title );
267 $canonical = MWNamespace::getCanonicalName( $ns );
269 if ( MWNamespace::hasSubpages( $ns ) ) {
270 $data[$ns]['subpages'] = '';
273 if ( $canonical ) {
274 $data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
277 if ( MWNamespace::isContent( $ns ) ) {
278 $data[$ns]['content'] = '';
281 if ( MWNamespace::isNonincludable( $ns ) ) {
282 $data[$ns]['nonincludable'] = '';
285 $contentmodel = MWNamespace::getNamespaceContentModel( $ns );
286 if ( $contentmodel ) {
287 $data[$ns]['defaultcontentmodel'] = $contentmodel;
291 $this->getResult()->setIndexedTagName( $data, 'ns' );
293 return $this->getResult()->addValue( 'query', $property, $data );
296 protected function appendNamespaceAliases( $property ) {
297 global $wgNamespaceAliases, $wgContLang;
298 $aliases = array_merge( $wgNamespaceAliases, $wgContLang->getNamespaceAliases() );
299 $namespaces = $wgContLang->getNamespaces();
300 $data = array();
301 foreach ( $aliases as $title => $ns ) {
302 if ( $namespaces[$ns] == $title ) {
303 // Don't list duplicates
304 continue;
306 $item = array(
307 'id' => intval( $ns )
309 ApiResult::setContent( $item, strtr( $title, '_', ' ' ) );
310 $data[] = $item;
313 sort( $data );
315 $this->getResult()->setIndexedTagName( $data, 'ns' );
317 return $this->getResult()->addValue( 'query', $property, $data );
320 protected function appendSpecialPageAliases( $property ) {
321 global $wgContLang;
322 $data = array();
323 $aliases = $wgContLang->getSpecialPageAliases();
324 foreach ( SpecialPageFactory::getList() as $specialpage => $stuff ) {
325 if ( isset( $aliases[$specialpage] ) ) {
326 $arr = array( 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] );
327 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
328 $data[] = $arr;
331 $this->getResult()->setIndexedTagName( $data, 'specialpage' );
333 return $this->getResult()->addValue( 'query', $property, $data );
336 protected function appendMagicWords( $property ) {
337 global $wgContLang;
338 $data = array();
339 foreach ( $wgContLang->getMagicWords() as $magicword => $aliases ) {
340 $caseSensitive = array_shift( $aliases );
341 $arr = array( 'name' => $magicword, 'aliases' => $aliases );
342 if ( $caseSensitive ) {
343 $arr['case-sensitive'] = '';
345 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
346 $data[] = $arr;
348 $this->getResult()->setIndexedTagName( $data, 'magicword' );
350 return $this->getResult()->addValue( 'query', $property, $data );
353 protected function appendInterwikiMap( $property, $filter ) {
354 $local = null;
355 if ( $filter === 'local' ) {
356 $local = 1;
357 } elseif ( $filter === '!local' ) {
358 $local = 0;
359 } elseif ( $filter ) {
360 ApiBase::dieDebug( __METHOD__, "Unknown filter=$filter" );
363 $params = $this->extractRequestParams();
364 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
365 $langNames = Language::fetchLanguageNames( $langCode );
367 $getPrefixes = Interwiki::getAllPrefixes( $local );
368 $data = array();
370 foreach ( $getPrefixes as $row ) {
371 $prefix = $row['iw_prefix'];
372 $val = array();
373 $val['prefix'] = $prefix;
374 if ( $row['iw_local'] == '1' ) {
375 $val['local'] = '';
377 if ( $row['iw_trans'] == '1' ) {
378 $val['trans'] = '';
380 if ( isset( $langNames[$prefix] ) ) {
381 $val['language'] = $langNames[$prefix];
383 $val['url'] = wfExpandUrl( $row['iw_url'], PROTO_CURRENT );
384 if ( isset( $row['iw_wikiid'] ) ) {
385 $val['wikiid'] = $row['iw_wikiid'];
387 if ( isset( $row['iw_api'] ) ) {
388 $val['api'] = $row['iw_api'];
391 $data[] = $val;
394 $this->getResult()->setIndexedTagName( $data, 'iw' );
396 return $this->getResult()->addValue( 'query', $property, $data );
399 protected function appendDbReplLagInfo( $property, $includeAll ) {
400 global $wgShowHostnames;
401 $data = array();
402 $lb = wfGetLB();
403 if ( $includeAll ) {
404 if ( !$wgShowHostnames ) {
405 $this->dieUsage(
406 'Cannot view all servers info unless $wgShowHostnames is true',
407 'includeAllDenied'
411 $lags = $lb->getLagTimes();
412 foreach ( $lags as $i => $lag ) {
413 $data[] = array(
414 'host' => $lb->getServerName( $i ),
415 'lag' => $lag
418 } else {
419 list( , $lag, $index ) = $lb->getMaxLag();
420 $data[] = array(
421 'host' => $wgShowHostnames
422 ? $lb->getServerName( $index )
423 : '',
424 'lag' => intval( $lag )
428 $result = $this->getResult();
429 $result->setIndexedTagName( $data, 'db' );
431 return $this->getResult()->addValue( 'query', $property, $data );
434 protected function appendStatistics( $property ) {
435 global $wgDisableCounters;
436 $data = array();
437 $data['pages'] = intval( SiteStats::pages() );
438 $data['articles'] = intval( SiteStats::articles() );
439 if ( !$wgDisableCounters ) {
440 $data['views'] = intval( SiteStats::views() );
442 $data['edits'] = intval( SiteStats::edits() );
443 $data['images'] = intval( SiteStats::images() );
444 $data['users'] = intval( SiteStats::users() );
445 $data['activeusers'] = intval( SiteStats::activeUsers() );
446 $data['admins'] = intval( SiteStats::numberingroup( 'sysop' ) );
447 $data['jobs'] = intval( SiteStats::jobs() );
449 wfRunHooks( 'APIQuerySiteInfoStatisticsInfo', array( &$data ) );
451 return $this->getResult()->addValue( 'query', $property, $data );
454 protected function appendUserGroups( $property, $numberInGroup ) {
455 global $wgGroupPermissions, $wgAddGroups, $wgRemoveGroups;
456 global $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf;
458 $data = array();
459 $result = $this->getResult();
460 foreach ( $wgGroupPermissions as $group => $permissions ) {
461 $arr = array(
462 'name' => $group,
463 'rights' => array_keys( $permissions, true ),
466 if ( $numberInGroup ) {
467 global $wgAutopromote;
469 if ( $group == 'user' ) {
470 $arr['number'] = SiteStats::users();
471 // '*' and autopromote groups have no size
472 } elseif ( $group !== '*' && !isset( $wgAutopromote[$group] ) ) {
473 $arr['number'] = SiteStats::numberInGroup( $group );
477 $groupArr = array(
478 'add' => $wgAddGroups,
479 'remove' => $wgRemoveGroups,
480 'add-self' => $wgGroupsAddToSelf,
481 'remove-self' => $wgGroupsRemoveFromSelf
484 foreach ( $groupArr as $type => $rights ) {
485 if ( isset( $rights[$group] ) ) {
486 $arr[$type] = $rights[$group];
487 $result->setIndexedTagName( $arr[$type], 'group' );
491 $result->setIndexedTagName( $arr['rights'], 'permission' );
492 $data[] = $arr;
495 $result->setIndexedTagName( $data, 'group' );
497 return $result->addValue( 'query', $property, $data );
500 protected function appendFileExtensions( $property ) {
501 global $wgFileExtensions;
503 $data = array();
504 foreach ( array_unique( $wgFileExtensions ) as $ext ) {
505 $data[] = array( 'ext' => $ext );
507 $this->getResult()->setIndexedTagName( $data, 'fe' );
509 return $this->getResult()->addValue( 'query', $property, $data );
512 protected function appendExtensions( $property ) {
513 global $wgExtensionCredits;
514 $data = array();
515 foreach ( $wgExtensionCredits as $type => $extensions ) {
516 foreach ( $extensions as $ext ) {
517 $ret = array();
518 $ret['type'] = $type;
519 if ( isset( $ext['name'] ) ) {
520 $ret['name'] = $ext['name'];
522 if ( isset( $ext['description'] ) ) {
523 $ret['description'] = $ext['description'];
525 if ( isset( $ext['descriptionmsg'] ) ) {
526 // Can be a string or array( key, param1, param2, ... )
527 if ( is_array( $ext['descriptionmsg'] ) ) {
528 $ret['descriptionmsg'] = $ext['descriptionmsg'][0];
529 $ret['descriptionmsgparams'] = array_slice( $ext['descriptionmsg'], 1 );
530 $this->getResult()->setIndexedTagName( $ret['descriptionmsgparams'], 'param' );
531 } else {
532 $ret['descriptionmsg'] = $ext['descriptionmsg'];
535 if ( isset( $ext['author'] ) ) {
536 $ret['author'] = is_array( $ext['author'] ) ?
537 implode( ', ', $ext['author'] ) : $ext['author'];
539 if ( isset( $ext['url'] ) ) {
540 $ret['url'] = $ext['url'];
542 if ( isset( $ext['version'] ) ) {
543 $ret['version'] = $ext['version'];
544 } elseif ( isset( $ext['svn-revision'] ) &&
545 preg_match( '/\$(?:Rev|LastChangedRevision|Revision): *(\d+)/',
546 $ext['svn-revision'], $m )
548 $ret['version'] = 'r' . $m[1];
550 $data[] = $ret;
554 $this->getResult()->setIndexedTagName( $data, 'ext' );
556 return $this->getResult()->addValue( 'query', $property, $data );
559 protected function appendRightsInfo( $property ) {
560 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
561 $title = Title::newFromText( $wgRightsPage );
562 $url = $title ? wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ) : $wgRightsUrl;
563 $text = $wgRightsText;
564 if ( !$text && $title ) {
565 $text = $title->getPrefixedText();
568 $data = array(
569 'url' => $url ? $url : '',
570 'text' => $text ? $text : ''
573 return $this->getResult()->addValue( 'query', $property, $data );
576 public function appendLanguages( $property ) {
577 $params = $this->extractRequestParams();
578 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
579 $langNames = Language::fetchLanguageNames( $langCode );
581 $data = array();
583 foreach ( $langNames as $code => $name ) {
584 $lang = array( 'code' => $code );
585 ApiResult::setContent( $lang, $name );
586 $data[] = $lang;
588 $this->getResult()->setIndexedTagName( $data, 'lang' );
590 return $this->getResult()->addValue( 'query', $property, $data );
593 public function appendSkins( $property ) {
594 $data = array();
595 $usable = Skin::getUsableSkins();
596 $default = Skin::normalizeKey( 'default' );
597 foreach ( Skin::getSkinNames() as $name => $displayName ) {
598 $skin = array( 'code' => $name );
599 ApiResult::setContent( $skin, $displayName );
600 if ( !isset( $usable[$name] ) ) {
601 $skin['unusable'] = '';
603 if ( $name === $default ) {
604 $skin['default'] = '';
606 $data[] = $skin;
608 $this->getResult()->setIndexedTagName( $data, 'skin' );
610 return $this->getResult()->addValue( 'query', $property, $data );
613 public function appendExtensionTags( $property ) {
614 global $wgParser;
615 $wgParser->firstCallInit();
616 $tags = array_map( array( $this, 'formatParserTags' ), $wgParser->getTags() );
617 $this->getResult()->setIndexedTagName( $tags, 't' );
619 return $this->getResult()->addValue( 'query', $property, $tags );
622 public function appendFunctionHooks( $property ) {
623 global $wgParser;
624 $wgParser->firstCallInit();
625 $hooks = $wgParser->getFunctionHooks();
626 $this->getResult()->setIndexedTagName( $hooks, 'h' );
628 return $this->getResult()->addValue( 'query', $property, $hooks );
631 public function appendVariables( $property ) {
632 $variables = MagicWord::getVariableIDs();
633 $this->getResult()->setIndexedTagName( $variables, 'v' );
635 return $this->getResult()->addValue( 'query', $property, $variables );
638 public function appendProtocols( $property ) {
639 global $wgUrlProtocols;
640 // Make a copy of the global so we don't try to set the _element key of it - bug 45130
641 $protocols = array_values( $wgUrlProtocols );
642 $this->getResult()->setIndexedTagName( $protocols, 'p' );
644 return $this->getResult()->addValue( 'query', $property, $protocols );
647 public function appendDefaultOptions( $property ) {
648 return $this->getResult()->addValue( 'query', $property, User::getDefaultOptions() );
651 private function formatParserTags( $item ) {
652 return "<{$item}>";
655 public function appendSubscribedHooks( $property ) {
656 global $wgHooks;
657 $myWgHooks = $wgHooks;
658 ksort( $myWgHooks );
660 $data = array();
661 foreach ( $myWgHooks as $hook => $hooks ) {
662 $arr = array(
663 'name' => $hook,
664 'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $hooks ),
667 $this->getResult()->setIndexedTagName( $arr['subscribers'], 's' );
668 $data[] = $arr;
671 $this->getResult()->setIndexedTagName( $data, 'hook' );
673 return $this->getResult()->addValue( 'query', $property, $data );
676 public function getCacheMode( $params ) {
677 return 'public';
680 public function getAllowedParams() {
681 return array(
682 'prop' => array(
683 ApiBase::PARAM_DFLT => 'general',
684 ApiBase::PARAM_ISMULTI => true,
685 ApiBase::PARAM_TYPE => array(
686 'general',
687 'namespaces',
688 'namespacealiases',
689 'specialpagealiases',
690 'magicwords',
691 'interwikimap',
692 'dbrepllag',
693 'statistics',
694 'usergroups',
695 'extensions',
696 'fileextensions',
697 'rightsinfo',
698 'languages',
699 'skins',
700 'extensiontags',
701 'functionhooks',
702 'showhooks',
703 'variables',
704 'protocols',
705 'defaultoptions',
708 'filteriw' => array(
709 ApiBase::PARAM_TYPE => array(
710 'local',
711 '!local',
714 'showalldb' => false,
715 'numberingroup' => false,
716 'inlanguagecode' => null,
720 public function getParamDescription() {
721 $p = $this->getModulePrefix();
723 return array(
724 'prop' => array(
725 'Which sysinfo properties to get:',
726 ' general - Overall system information',
727 ' namespaces - List of registered namespaces and their canonical names',
728 ' namespacealiases - List of registered namespace aliases',
729 ' specialpagealiases - List of special page aliases',
730 ' magicwords - List of magic words and their aliases',
731 ' statistics - Returns site statistics',
732 ' interwikimap - Returns interwiki map ' .
733 "(optionally filtered, (optionally localised by using {$p}inlanguagecode))",
734 ' dbrepllag - Returns database server with the highest replication lag',
735 ' usergroups - Returns user groups and the associated permissions',
736 ' extensions - Returns extensions installed on the wiki',
737 ' fileextensions - Returns list of file extensions allowed to be uploaded',
738 ' rightsinfo - Returns wiki rights (license) information if available',
739 ' languages - Returns a list of languages MediaWiki supports' .
740 "(optionally localised by using {$p}inlanguagecode)",
741 ' skins - Returns a list of all enabled skins',
742 ' extensiontags - Returns a list of parser extension tags',
743 ' functionhooks - Returns a list of parser function hooks',
744 ' showhooks - Returns a list of all subscribed hooks (contents of $wgHooks)',
745 ' variables - Returns a list of variable IDs',
746 ' protocols - Returns a list of protocols that are allowed in external links.',
747 ' defaultoptions - Returns the default values for user preferences.',
749 'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
750 'showalldb' => 'List all database servers, not just the one lagging the most',
751 'numberingroup' => 'Lists the number of users in user groups',
752 'inlanguagecode' => 'Language code for localised language names ' .
753 '(best effort, use CLDR extension)',
757 public function getDescription() {
758 return 'Return general information about the site';
761 public function getPossibleErrors() {
762 return array_merge( parent::getPossibleErrors(), array( array(
763 'code' => 'includeAllDenied',
764 'info' => 'Cannot view all servers info unless $wgShowHostnames is true'
765 ), ) );
768 public function getExamples() {
769 return array(
770 'api.php?action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics',
771 'api.php?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local',
772 'api.php?action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb=',
776 public function getHelpUrls() {
777 return 'https://www.mediawiki.org/wiki/API:Meta#siteinfo_.2F_si';