Merge "Make update.php file executable"
[mediawiki.git] / includes / api / ApiQuerySiteinfo.php
blob2124dc32d192ce02d8eb0d82e80e726e99e23bb8
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 'restrictions':
82 $fit = $this->appendRestrictions( $p );
83 break;
84 case 'languages':
85 $fit = $this->appendLanguages( $p );
86 break;
87 case 'skins':
88 $fit = $this->appendSkins( $p );
89 break;
90 case 'extensiontags':
91 $fit = $this->appendExtensionTags( $p );
92 break;
93 case 'functionhooks':
94 $fit = $this->appendFunctionHooks( $p );
95 break;
96 case 'showhooks':
97 $fit = $this->appendSubscribedHooks( $p );
98 break;
99 case 'variables':
100 $fit = $this->appendVariables( $p );
101 break;
102 case 'protocols':
103 $fit = $this->appendProtocols( $p );
104 break;
105 case 'defaultoptions':
106 $fit = $this->appendDefaultOptions( $p );
107 break;
108 default:
109 ApiBase::dieDebug( __METHOD__, "Unknown prop=$p" );
111 if ( !$fit ) {
112 // Abuse siprop as a query-continue parameter
113 // and set it to all unprocessed props
114 $this->setContinueEnumParameter( 'prop', implode( '|',
115 array_diff( $params['prop'], $done ) ) );
116 break;
118 $done[] = $p;
122 protected function appendGeneralInfo( $property ) {
123 global $wgContLang, $wgDisableLangConversion, $wgDisableTitleConversion;
125 $data = array();
126 $mainPage = Title::newMainPage();
127 $data['mainpage'] = $mainPage->getPrefixedText();
128 $data['base'] = wfExpandUrl( $mainPage->getFullURL(), PROTO_CURRENT );
129 $data['sitename'] = $GLOBALS['wgSitename'];
131 // wgLogo can either be a relative or an absolute path
132 // make sure we always return an absolute path
133 $data['logo'] = wfExpandUrl( $GLOBALS['wgLogo'], PROTO_RELATIVE );
135 $data['generator'] = "MediaWiki {$GLOBALS['wgVersion']}";
136 $data['phpversion'] = phpversion();
137 $data['phpsapi'] = PHP_SAPI;
138 $data['dbtype'] = $GLOBALS['wgDBtype'];
139 $data['dbversion'] = $this->getDB()->getServerVersion();
141 $allowFrom = array( '' );
142 $allowException = true;
143 if ( !$GLOBALS['wgAllowExternalImages'] ) {
144 if ( $GLOBALS['wgEnableImageWhitelist'] ) {
145 $data['imagewhitelistenabled'] = '';
147 $allowFrom = $GLOBALS['wgAllowExternalImagesFrom'];
148 $allowException = !empty( $allowFrom );
150 if ( $allowException ) {
151 $data['externalimages'] = (array)$allowFrom;
152 $this->getResult()->setIndexedTagName( $data['externalimages'], 'prefix' );
155 if ( !$wgDisableLangConversion ) {
156 $data['langconversion'] = '';
159 if ( !$wgDisableTitleConversion ) {
160 $data['titleconversion'] = '';
163 if ( $wgContLang->linkPrefixExtension() ) {
164 $linkPrefixCharset = $wgContLang->linkPrefixCharset();
165 $data['linkprefixcharset'] = $linkPrefixCharset;
166 // For backwards compatability
167 $data['linkprefix'] = "/^((?>.*[^$linkPrefixCharset]|))(.+)$/sDu";
168 } else {
169 $data['linkprefixcharset'] = '';
170 $data['linkprefix'] = '';
173 $linktrail = $wgContLang->linkTrail();
174 if ( $linktrail ) {
175 $data['linktrail'] = $linktrail;
176 } else {
177 $data['linktrail'] = '';
180 $git = SpecialVersion::getGitHeadSha1( $GLOBALS['IP'] );
181 if ( $git ) {
182 $data['git-hash'] = $git;
183 $data['git-branch'] =
184 SpecialVersion::getGitCurrentBranch( $GLOBALS['IP'] );
185 } else {
186 $svn = SpecialVersion::getSvnRevision( $GLOBALS['IP'] );
187 if ( $svn ) {
188 $data['rev'] = $svn;
192 // 'case-insensitive' option is reserved for future
193 $data['case'] = $GLOBALS['wgCapitalLinks'] ? 'first-letter' : 'case-sensitive';
195 $data['lang'] = $GLOBALS['wgLanguageCode'];
197 $fallbacks = array();
198 foreach ( $wgContLang->getFallbackLanguages() as $code ) {
199 $fallbacks[] = array( 'code' => $code );
201 $data['fallback'] = $fallbacks;
202 $this->getResult()->setIndexedTagName( $data['fallback'], 'lang' );
204 if ( $wgContLang->hasVariants() ) {
205 $variants = array();
206 foreach ( $wgContLang->getVariants() as $code ) {
207 $variants[] = array(
208 'code' => $code,
209 'name' => $wgContLang->getVariantname( $code ),
212 $data['variants'] = $variants;
213 $this->getResult()->setIndexedTagName( $data['variants'], 'lang' );
216 if ( $wgContLang->isRTL() ) {
217 $data['rtl'] = '';
219 $data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
221 if ( wfReadOnly() ) {
222 $data['readonly'] = '';
223 $data['readonlyreason'] = wfReadOnlyReason();
225 if ( $GLOBALS['wgEnableWriteAPI'] ) {
226 $data['writeapi'] = '';
229 $tz = $GLOBALS['wgLocaltimezone'];
230 $offset = $GLOBALS['wgLocalTZoffset'];
231 if ( is_null( $tz ) ) {
232 $tz = 'UTC';
233 $offset = 0;
234 } elseif ( is_null( $offset ) ) {
235 $offset = 0;
237 $data['timezone'] = $tz;
238 $data['timeoffset'] = intval( $offset );
239 $data['articlepath'] = $GLOBALS['wgArticlePath'];
240 $data['scriptpath'] = $GLOBALS['wgScriptPath'];
241 $data['script'] = $GLOBALS['wgScript'];
242 $data['variantarticlepath'] = $GLOBALS['wgVariantArticlePath'];
243 $data['server'] = $GLOBALS['wgServer'];
244 $data['servername'] = $GLOBALS['wgServerName'];
245 $data['wikiid'] = wfWikiID();
246 $data['time'] = wfTimestamp( TS_ISO_8601, time() );
248 if ( $GLOBALS['wgMiserMode'] ) {
249 $data['misermode'] = '';
252 $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
254 $data['thumblimits'] = $GLOBALS['wgThumbLimits'];
255 $this->getResult()->setIndexedTagName( $data['thumblimits'], 'limit' );
256 $data['imagelimits'] = array();
257 $this->getResult()->setIndexedTagName( $data['imagelimits'], 'limit' );
258 foreach ( $GLOBALS['wgImageLimits'] as $k => $limit ) {
259 $data['imagelimits'][$k] = array( 'width' => $limit[0], 'height' => $limit[1] );
262 if ( !empty( $GLOBALS['wgFavicon'] ) ) {
263 // wgFavicon can either be a relative or an absolute path
264 // make sure we always return an absolute path
265 $data['favicon'] = wfExpandUrl( $GLOBALS['wgFavicon'], PROTO_RELATIVE );
268 wfRunHooks( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
270 return $this->getResult()->addValue( 'query', $property, $data );
273 protected function appendNamespaces( $property ) {
274 global $wgContLang;
275 $data = array();
276 foreach ( $wgContLang->getFormattedNamespaces() as $ns => $title ) {
277 $data[$ns] = array(
278 'id' => intval( $ns ),
279 'case' => MWNamespace::isCapitalized( $ns ) ? 'first-letter' : 'case-sensitive',
281 ApiResult::setContent( $data[$ns], $title );
282 $canonical = MWNamespace::getCanonicalName( $ns );
284 if ( MWNamespace::hasSubpages( $ns ) ) {
285 $data[$ns]['subpages'] = '';
288 if ( $canonical ) {
289 $data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
292 if ( MWNamespace::isContent( $ns ) ) {
293 $data[$ns]['content'] = '';
296 if ( MWNamespace::isNonincludable( $ns ) ) {
297 $data[$ns]['nonincludable'] = '';
300 $contentmodel = MWNamespace::getNamespaceContentModel( $ns );
301 if ( $contentmodel ) {
302 $data[$ns]['defaultcontentmodel'] = $contentmodel;
306 $this->getResult()->setIndexedTagName( $data, 'ns' );
308 return $this->getResult()->addValue( 'query', $property, $data );
311 protected function appendNamespaceAliases( $property ) {
312 global $wgNamespaceAliases, $wgContLang;
313 $aliases = array_merge( $wgNamespaceAliases, $wgContLang->getNamespaceAliases() );
314 $namespaces = $wgContLang->getNamespaces();
315 $data = array();
316 foreach ( $aliases as $title => $ns ) {
317 if ( $namespaces[$ns] == $title ) {
318 // Don't list duplicates
319 continue;
321 $item = array(
322 'id' => intval( $ns )
324 ApiResult::setContent( $item, strtr( $title, '_', ' ' ) );
325 $data[] = $item;
328 sort( $data );
330 $this->getResult()->setIndexedTagName( $data, 'ns' );
332 return $this->getResult()->addValue( 'query', $property, $data );
335 protected function appendSpecialPageAliases( $property ) {
336 global $wgContLang;
337 $data = array();
338 $aliases = $wgContLang->getSpecialPageAliases();
339 foreach ( SpecialPageFactory::getList() as $specialpage => $stuff ) {
340 if ( isset( $aliases[$specialpage] ) ) {
341 $arr = array( 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] );
342 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
343 $data[] = $arr;
346 $this->getResult()->setIndexedTagName( $data, 'specialpage' );
348 return $this->getResult()->addValue( 'query', $property, $data );
351 protected function appendMagicWords( $property ) {
352 global $wgContLang;
353 $data = array();
354 foreach ( $wgContLang->getMagicWords() as $magicword => $aliases ) {
355 $caseSensitive = array_shift( $aliases );
356 $arr = array( 'name' => $magicword, 'aliases' => $aliases );
357 if ( $caseSensitive ) {
358 $arr['case-sensitive'] = '';
360 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
361 $data[] = $arr;
363 $this->getResult()->setIndexedTagName( $data, 'magicword' );
365 return $this->getResult()->addValue( 'query', $property, $data );
368 protected function appendInterwikiMap( $property, $filter ) {
369 $local = null;
370 if ( $filter === 'local' ) {
371 $local = 1;
372 } elseif ( $filter === '!local' ) {
373 $local = 0;
374 } elseif ( $filter ) {
375 ApiBase::dieDebug( __METHOD__, "Unknown filter=$filter" );
378 $params = $this->extractRequestParams();
379 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
380 $langNames = Language::fetchLanguageNames( $langCode );
382 $getPrefixes = Interwiki::getAllPrefixes( $local );
383 $data = array();
385 foreach ( $getPrefixes as $row ) {
386 $prefix = $row['iw_prefix'];
387 $val = array();
388 $val['prefix'] = $prefix;
389 if ( $row['iw_local'] == '1' ) {
390 $val['local'] = '';
392 if ( $row['iw_trans'] == '1' ) {
393 $val['trans'] = '';
395 if ( isset( $langNames[$prefix] ) ) {
396 $val['language'] = $langNames[$prefix];
398 $val['url'] = wfExpandUrl( $row['iw_url'], PROTO_CURRENT );
399 if ( isset( $row['iw_wikiid'] ) ) {
400 $val['wikiid'] = $row['iw_wikiid'];
402 if ( isset( $row['iw_api'] ) ) {
403 $val['api'] = $row['iw_api'];
406 $data[] = $val;
409 $this->getResult()->setIndexedTagName( $data, 'iw' );
411 return $this->getResult()->addValue( 'query', $property, $data );
414 protected function appendDbReplLagInfo( $property, $includeAll ) {
415 global $wgShowHostnames;
416 $data = array();
417 $lb = wfGetLB();
418 if ( $includeAll ) {
419 if ( !$wgShowHostnames ) {
420 $this->dieUsage(
421 'Cannot view all servers info unless $wgShowHostnames is true',
422 'includeAllDenied'
426 $lags = $lb->getLagTimes();
427 foreach ( $lags as $i => $lag ) {
428 $data[] = array(
429 'host' => $lb->getServerName( $i ),
430 'lag' => $lag
433 } else {
434 list( , $lag, $index ) = $lb->getMaxLag();
435 $data[] = array(
436 'host' => $wgShowHostnames
437 ? $lb->getServerName( $index )
438 : '',
439 'lag' => intval( $lag )
443 $result = $this->getResult();
444 $result->setIndexedTagName( $data, 'db' );
446 return $this->getResult()->addValue( 'query', $property, $data );
449 protected function appendStatistics( $property ) {
450 global $wgDisableCounters;
451 $data = array();
452 $data['pages'] = intval( SiteStats::pages() );
453 $data['articles'] = intval( SiteStats::articles() );
454 if ( !$wgDisableCounters ) {
455 $data['views'] = intval( SiteStats::views() );
457 $data['edits'] = intval( SiteStats::edits() );
458 $data['images'] = intval( SiteStats::images() );
459 $data['users'] = intval( SiteStats::users() );
460 $data['activeusers'] = intval( SiteStats::activeUsers() );
461 $data['admins'] = intval( SiteStats::numberingroup( 'sysop' ) );
462 $data['jobs'] = intval( SiteStats::jobs() );
464 wfRunHooks( 'APIQuerySiteInfoStatisticsInfo', array( &$data ) );
466 return $this->getResult()->addValue( 'query', $property, $data );
469 protected function appendUserGroups( $property, $numberInGroup ) {
470 global $wgGroupPermissions, $wgAddGroups, $wgRemoveGroups;
471 global $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf;
473 $data = array();
474 $result = $this->getResult();
475 foreach ( $wgGroupPermissions as $group => $permissions ) {
476 $arr = array(
477 'name' => $group,
478 'rights' => array_keys( $permissions, true ),
481 if ( $numberInGroup ) {
482 global $wgAutopromote;
484 if ( $group == 'user' ) {
485 $arr['number'] = SiteStats::users();
486 // '*' and autopromote groups have no size
487 } elseif ( $group !== '*' && !isset( $wgAutopromote[$group] ) ) {
488 $arr['number'] = SiteStats::numberInGroup( $group );
492 $groupArr = array(
493 'add' => $wgAddGroups,
494 'remove' => $wgRemoveGroups,
495 'add-self' => $wgGroupsAddToSelf,
496 'remove-self' => $wgGroupsRemoveFromSelf
499 foreach ( $groupArr as $type => $rights ) {
500 if ( isset( $rights[$group] ) ) {
501 $arr[$type] = $rights[$group];
502 $result->setIndexedTagName( $arr[$type], 'group' );
506 $result->setIndexedTagName( $arr['rights'], 'permission' );
507 $data[] = $arr;
510 $result->setIndexedTagName( $data, 'group' );
512 return $result->addValue( 'query', $property, $data );
515 protected function appendFileExtensions( $property ) {
516 global $wgFileExtensions;
518 $data = array();
519 foreach ( array_unique( $wgFileExtensions ) as $ext ) {
520 $data[] = array( 'ext' => $ext );
522 $this->getResult()->setIndexedTagName( $data, 'fe' );
524 return $this->getResult()->addValue( 'query', $property, $data );
527 protected function appendExtensions( $property ) {
528 global $wgExtensionCredits;
529 $data = array();
530 foreach ( $wgExtensionCredits as $type => $extensions ) {
531 foreach ( $extensions as $ext ) {
532 $ret = array();
533 $ret['type'] = $type;
534 if ( isset( $ext['name'] ) ) {
535 $ret['name'] = $ext['name'];
537 if ( isset( $ext['description'] ) ) {
538 $ret['description'] = $ext['description'];
540 if ( isset( $ext['descriptionmsg'] ) ) {
541 // Can be a string or array( key, param1, param2, ... )
542 if ( is_array( $ext['descriptionmsg'] ) ) {
543 $ret['descriptionmsg'] = $ext['descriptionmsg'][0];
544 $ret['descriptionmsgparams'] = array_slice( $ext['descriptionmsg'], 1 );
545 $this->getResult()->setIndexedTagName( $ret['descriptionmsgparams'], 'param' );
546 } else {
547 $ret['descriptionmsg'] = $ext['descriptionmsg'];
550 if ( isset( $ext['author'] ) ) {
551 $ret['author'] = is_array( $ext['author'] ) ?
552 implode( ', ', $ext['author'] ) : $ext['author'];
554 if ( isset( $ext['url'] ) ) {
555 $ret['url'] = $ext['url'];
557 if ( isset( $ext['version'] ) ) {
558 $ret['version'] = $ext['version'];
559 } elseif ( isset( $ext['svn-revision'] ) &&
560 preg_match( '/\$(?:Rev|LastChangedRevision|Revision): *(\d+)/',
561 $ext['svn-revision'], $m )
563 $ret['version'] = 'r' . $m[1];
565 if ( isset( $ext['path'] ) ) {
566 $extensionPath = dirname( $ext['path'] );
567 $gitInfo = new GitInfo( $extensionPath );
568 $vcsVersion = $gitInfo->getHeadSHA1();
569 if ( $vcsVersion !== false ) {
570 $ret['vcs-system'] = 'git';
571 $ret['vcs-version'] = $vcsVersion;
572 $ret['vcs-url'] = $gitInfo->getHeadViewUrl();
573 $vcsDate = $gitInfo->getHeadCommitDate();
574 if ( $vcsDate !== false ) {
575 $ret['vcs-date'] = wfTimestamp( TS_ISO_8601, $vcsDate );
577 } else {
578 $svnInfo = SpecialVersion::getSvnInfo( $extensionPath );
579 if ( $svnInfo !== false ) {
580 $ret['vcs-system'] = 'svn';
581 $ret['vcs-version'] = $svnInfo['checkout-rev'];
582 $ret['vcs-url'] = isset( $svnInfo['viewvc-url'] ) ? $svnInfo['viewvc-url'] : '';
586 if ( SpecialVersion::getExtLicenseFileName( $extensionPath ) ) {
587 $ret['license-name'] = isset( $ext['license-name'] ) ? $ext['license-name'] : '';
588 $ret['license'] = SpecialPage::getTitleFor(
589 'Version',
590 "License/{$ext['name']}"
591 )->getLinkURL();
594 if ( SpecialVersion::getExtAuthorsFileName( $extensionPath ) ) {
595 $ret['credits'] = SpecialPage::getTitleFor(
596 'Version',
597 "Credits/{$ext['name']}"
598 )->getLinkURL();
601 $data[] = $ret;
605 $this->getResult()->setIndexedTagName( $data, 'ext' );
607 return $this->getResult()->addValue( 'query', $property, $data );
610 protected function appendRightsInfo( $property ) {
611 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
612 $title = Title::newFromText( $wgRightsPage );
613 $url = $title ? wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ) : $wgRightsUrl;
614 $text = $wgRightsText;
615 if ( !$text && $title ) {
616 $text = $title->getPrefixedText();
619 $data = array(
620 'url' => $url ? $url : '',
621 'text' => $text ? $text : ''
624 return $this->getResult()->addValue( 'query', $property, $data );
627 protected function appendRestrictions( $property ) {
628 global $wgRestrictionTypes, $wgRestrictionLevels,
629 $wgCascadingRestrictionLevels, $wgSemiprotectedRestrictionLevels;
631 $data = array(
632 'types' => $wgRestrictionTypes,
633 'levels' => $wgRestrictionLevels,
634 'cascadinglevels' => $wgCascadingRestrictionLevels,
635 'semiprotectedlevels' => $wgSemiprotectedRestrictionLevels,
638 $this->getResult()->setIndexedTagName( $data['types'], 'type' );
639 $this->getResult()->setIndexedTagName( $data['levels'], 'level' );
640 $this->getResult()->setIndexedTagName( $data['cascadinglevels'], 'level' );
641 $this->getResult()->setIndexedTagName( $data['semiprotectedlevels'], 'level' );
643 return $this->getResult()->addValue( 'query', $property, $data );
646 public function appendLanguages( $property ) {
647 $params = $this->extractRequestParams();
648 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
649 $langNames = Language::fetchLanguageNames( $langCode );
651 $data = array();
653 foreach ( $langNames as $code => $name ) {
654 $lang = array( 'code' => $code );
655 ApiResult::setContent( $lang, $name );
656 $data[] = $lang;
658 $this->getResult()->setIndexedTagName( $data, 'lang' );
660 return $this->getResult()->addValue( 'query', $property, $data );
663 public function appendSkins( $property ) {
664 $data = array();
665 $allowed = Skin::getAllowedSkins();
666 $default = Skin::normalizeKey( 'default' );
667 foreach ( Skin::getSkinNames() as $name => $displayName ) {
668 $skin = array( 'code' => $name );
669 ApiResult::setContent( $skin, $displayName );
670 if ( !isset( $allowed[$name] ) ) {
671 $skin['unusable'] = '';
673 if ( $name === $default ) {
674 $skin['default'] = '';
676 $data[] = $skin;
678 $this->getResult()->setIndexedTagName( $data, 'skin' );
680 return $this->getResult()->addValue( 'query', $property, $data );
683 public function appendExtensionTags( $property ) {
684 global $wgParser;
685 $wgParser->firstCallInit();
686 $tags = array_map( array( $this, 'formatParserTags' ), $wgParser->getTags() );
687 $this->getResult()->setIndexedTagName( $tags, 't' );
689 return $this->getResult()->addValue( 'query', $property, $tags );
692 public function appendFunctionHooks( $property ) {
693 global $wgParser;
694 $wgParser->firstCallInit();
695 $hooks = $wgParser->getFunctionHooks();
696 $this->getResult()->setIndexedTagName( $hooks, 'h' );
698 return $this->getResult()->addValue( 'query', $property, $hooks );
701 public function appendVariables( $property ) {
702 $variables = MagicWord::getVariableIDs();
703 $this->getResult()->setIndexedTagName( $variables, 'v' );
705 return $this->getResult()->addValue( 'query', $property, $variables );
708 public function appendProtocols( $property ) {
709 global $wgUrlProtocols;
710 // Make a copy of the global so we don't try to set the _element key of it - bug 45130
711 $protocols = array_values( $wgUrlProtocols );
712 $this->getResult()->setIndexedTagName( $protocols, 'p' );
714 return $this->getResult()->addValue( 'query', $property, $protocols );
717 public function appendDefaultOptions( $property ) {
718 return $this->getResult()->addValue( 'query', $property, User::getDefaultOptions() );
721 private function formatParserTags( $item ) {
722 return "<{$item}>";
725 public function appendSubscribedHooks( $property ) {
726 global $wgHooks;
727 $myWgHooks = $wgHooks;
728 ksort( $myWgHooks );
730 $data = array();
731 foreach ( $myWgHooks as $hook => $hooks ) {
732 $arr = array(
733 'name' => $hook,
734 'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $hooks ),
737 $this->getResult()->setIndexedTagName( $arr['subscribers'], 's' );
738 $data[] = $arr;
741 $this->getResult()->setIndexedTagName( $data, 'hook' );
743 return $this->getResult()->addValue( 'query', $property, $data );
746 public function getCacheMode( $params ) {
747 return 'public';
750 public function getAllowedParams() {
751 return array(
752 'prop' => array(
753 ApiBase::PARAM_DFLT => 'general',
754 ApiBase::PARAM_ISMULTI => true,
755 ApiBase::PARAM_TYPE => array(
756 'general',
757 'namespaces',
758 'namespacealiases',
759 'specialpagealiases',
760 'magicwords',
761 'interwikimap',
762 'dbrepllag',
763 'statistics',
764 'usergroups',
765 'extensions',
766 'fileextensions',
767 'rightsinfo',
768 'restrictions',
769 'languages',
770 'skins',
771 'extensiontags',
772 'functionhooks',
773 'showhooks',
774 'variables',
775 'protocols',
776 'defaultoptions',
779 'filteriw' => array(
780 ApiBase::PARAM_TYPE => array(
781 'local',
782 '!local',
785 'showalldb' => false,
786 'numberingroup' => false,
787 'inlanguagecode' => null,
791 public function getParamDescription() {
792 $p = $this->getModulePrefix();
794 return array(
795 'prop' => array(
796 'Which sysinfo properties to get:',
797 ' general - Overall system information',
798 ' namespaces - List of registered namespaces and their canonical names',
799 ' namespacealiases - List of registered namespace aliases',
800 ' specialpagealiases - List of special page aliases',
801 ' magicwords - List of magic words and their aliases',
802 ' statistics - Returns site statistics',
803 ' interwikimap - Returns interwiki map ' .
804 "(optionally filtered, (optionally localised by using {$p}inlanguagecode))",
805 ' dbrepllag - Returns database server with the highest replication lag',
806 ' usergroups - Returns user groups and the associated permissions',
807 ' extensions - Returns extensions installed on the wiki',
808 ' fileextensions - Returns list of file extensions allowed to be uploaded',
809 ' rightsinfo - Returns wiki rights (license) information if available',
810 ' restrictions - Returns information on available restriction (protection) types',
811 ' languages - Returns a list of languages MediaWiki supports' .
812 "(optionally localised by using {$p}inlanguagecode)",
813 ' skins - Returns a list of all enabled skins',
814 ' extensiontags - Returns a list of parser extension tags',
815 ' functionhooks - Returns a list of parser function hooks',
816 ' showhooks - Returns a list of all subscribed hooks (contents of $wgHooks)',
817 ' variables - Returns a list of variable IDs',
818 ' protocols - Returns a list of protocols that are allowed in external links.',
819 ' defaultoptions - Returns the default values for user preferences.',
821 'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
822 'showalldb' => 'List all database servers, not just the one lagging the most',
823 'numberingroup' => 'Lists the number of users in user groups',
824 'inlanguagecode' => 'Language code for localised language names ' .
825 '(best effort, use CLDR extension)',
829 public function getDescription() {
830 return 'Return general information about the site.';
833 public function getPossibleErrors() {
834 return array_merge( parent::getPossibleErrors(), array( array(
835 'code' => 'includeAllDenied',
836 'info' => 'Cannot view all servers info unless $wgShowHostnames is true'
837 ), ) );
840 public function getExamples() {
841 return array(
842 'api.php?action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics',
843 'api.php?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local',
844 'api.php?action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb=',
848 public function getHelpUrls() {
849 return 'https://www.mediawiki.org/wiki/API:Meta#siteinfo_.2F_si';