Remove hitcounters and associated code
[mediawiki.git] / includes / api / ApiQuerySiteinfo.php
blobfeb869e8b5d8938b07b954909704e6670fee5e68
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( ApiQuery $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;
125 $config = $this->getConfig();
127 $data = array();
128 $mainPage = Title::newMainPage();
129 $data['mainpage'] = $mainPage->getPrefixedText();
130 $data['base'] = wfExpandUrl( $mainPage->getFullURL(), PROTO_CURRENT );
131 $data['sitename'] = $config->get( 'Sitename' );
133 // wgLogo can either be a relative or an absolute path
134 // make sure we always return an absolute path
135 $data['logo'] = wfExpandUrl( $config->get( 'Logo' ), PROTO_RELATIVE );
137 $data['generator'] = "MediaWiki {$config->get( 'Version' )}";
139 $data['phpversion'] = PHP_VERSION;
140 $data['phpsapi'] = PHP_SAPI;
141 if ( defined( 'HHVM_VERSION' ) ) {
142 $data['hhvmversion'] = HHVM_VERSION;
144 $data['dbtype'] = $config->get( 'DBtype' );
145 $data['dbversion'] = $this->getDB()->getServerVersion();
147 $allowFrom = array( '' );
148 $allowException = true;
149 if ( !$config->get( 'AllowExternalImages' ) ) {
150 if ( $config->get( 'EnableImageWhitelist' ) ) {
151 $data['imagewhitelistenabled'] = '';
153 $allowFrom = $config->get( 'AllowExternalImagesFrom' );
154 $allowException = !empty( $allowFrom );
156 if ( $allowException ) {
157 $data['externalimages'] = (array)$allowFrom;
158 $this->getResult()->setIndexedTagName( $data['externalimages'], 'prefix' );
161 if ( !$config->get( 'DisableLangConversion' ) ) {
162 $data['langconversion'] = '';
165 if ( !$config->get( 'DisableTitleConversion' ) ) {
166 $data['titleconversion'] = '';
169 if ( $wgContLang->linkPrefixExtension() ) {
170 $linkPrefixCharset = $wgContLang->linkPrefixCharset();
171 $data['linkprefixcharset'] = $linkPrefixCharset;
172 // For backwards compatibility
173 $data['linkprefix'] = "/^((?>.*[^$linkPrefixCharset]|))(.+)$/sDu";
174 } else {
175 $data['linkprefixcharset'] = '';
176 $data['linkprefix'] = '';
179 $linktrail = $wgContLang->linkTrail();
180 if ( $linktrail ) {
181 $data['linktrail'] = $linktrail;
182 } else {
183 $data['linktrail'] = '';
186 global $IP;
187 $git = SpecialVersion::getGitHeadSha1( $IP );
188 if ( $git ) {
189 $data['git-hash'] = $git;
190 $data['git-branch'] =
191 SpecialVersion::getGitCurrentBranch( $GLOBALS['IP'] );
192 } else {
193 $svn = SpecialVersion::getSvnRevision( $IP );
194 if ( $svn ) {
195 $data['rev'] = $svn;
199 // 'case-insensitive' option is reserved for future
200 $data['case'] = $config->get( 'CapitalLinks' ) ? 'first-letter' : 'case-sensitive';
201 $data['lang'] = $config->get( 'LanguageCode' );
203 $fallbacks = array();
204 foreach ( $wgContLang->getFallbackLanguages() as $code ) {
205 $fallbacks[] = array( 'code' => $code );
207 $data['fallback'] = $fallbacks;
208 $this->getResult()->setIndexedTagName( $data['fallback'], 'lang' );
210 if ( $wgContLang->hasVariants() ) {
211 $variants = array();
212 foreach ( $wgContLang->getVariants() as $code ) {
213 $variants[] = array(
214 'code' => $code,
215 'name' => $wgContLang->getVariantname( $code ),
218 $data['variants'] = $variants;
219 $this->getResult()->setIndexedTagName( $data['variants'], 'lang' );
222 if ( $wgContLang->isRTL() ) {
223 $data['rtl'] = '';
225 $data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
227 if ( wfReadOnly() ) {
228 $data['readonly'] = '';
229 $data['readonlyreason'] = wfReadOnlyReason();
231 if ( $config->get( 'EnableWriteAPI' ) ) {
232 $data['writeapi'] = '';
235 $tz = $config->get( 'Localtimezone' );
236 $offset = $config->get( 'LocalTZoffset' );
237 if ( is_null( $tz ) ) {
238 $tz = 'UTC';
239 $offset = 0;
240 } elseif ( is_null( $offset ) ) {
241 $offset = 0;
243 $data['timezone'] = $tz;
244 $data['timeoffset'] = intval( $offset );
245 $data['articlepath'] = $config->get( 'ArticlePath' );
246 $data['scriptpath'] = $config->get( 'ScriptPath' );
247 $data['script'] = $config->get( 'Script' );
248 $data['variantarticlepath'] = $config->get( 'VariantArticlePath' );
249 $data['server'] = $config->get( 'Server' );
250 $data['servername'] = $config->get( 'ServerName' );
251 $data['wikiid'] = wfWikiID();
252 $data['time'] = wfTimestamp( TS_ISO_8601, time() );
254 if ( $config->get( 'MiserMode' ) ) {
255 $data['misermode'] = '';
258 $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
260 $data['thumblimits'] = $config->get( 'ThumbLimits' );
261 $this->getResult()->setIndexedTagName( $data['thumblimits'], 'limit' );
262 $data['imagelimits'] = array();
263 $this->getResult()->setIndexedTagName( $data['imagelimits'], 'limit' );
264 foreach ( $config->get( 'ImageLimits' ) as $k => $limit ) {
265 $data['imagelimits'][$k] = array( 'width' => $limit[0], 'height' => $limit[1] );
268 $favicon = $config->get( 'Favicon' );
269 if ( !empty( $favicon ) ) {
270 // wgFavicon can either be a relative or an absolute path
271 // make sure we always return an absolute path
272 $data['favicon'] = wfExpandUrl( $favicon, PROTO_RELATIVE );
275 wfRunHooks( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
277 return $this->getResult()->addValue( 'query', $property, $data );
280 protected function appendNamespaces( $property ) {
281 global $wgContLang;
282 $data = array();
283 foreach ( $wgContLang->getFormattedNamespaces() as $ns => $title ) {
284 $data[$ns] = array(
285 'id' => intval( $ns ),
286 'case' => MWNamespace::isCapitalized( $ns ) ? 'first-letter' : 'case-sensitive',
288 ApiResult::setContent( $data[$ns], $title );
289 $canonical = MWNamespace::getCanonicalName( $ns );
291 if ( MWNamespace::hasSubpages( $ns ) ) {
292 $data[$ns]['subpages'] = '';
295 if ( $canonical ) {
296 $data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
299 if ( MWNamespace::isContent( $ns ) ) {
300 $data[$ns]['content'] = '';
303 if ( MWNamespace::isNonincludable( $ns ) ) {
304 $data[$ns]['nonincludable'] = '';
307 $contentmodel = MWNamespace::getNamespaceContentModel( $ns );
308 if ( $contentmodel ) {
309 $data[$ns]['defaultcontentmodel'] = $contentmodel;
313 $this->getResult()->setIndexedTagName( $data, 'ns' );
315 return $this->getResult()->addValue( 'query', $property, $data );
318 protected function appendNamespaceAliases( $property ) {
319 global $wgContLang;
320 $aliases = array_merge( $this->getConfig()->get( 'NamespaceAliases' ),
321 $wgContLang->getNamespaceAliases() );
322 $namespaces = $wgContLang->getNamespaces();
323 $data = array();
324 foreach ( $aliases as $title => $ns ) {
325 if ( $namespaces[$ns] == $title ) {
326 // Don't list duplicates
327 continue;
329 $item = array(
330 'id' => intval( $ns )
332 ApiResult::setContent( $item, strtr( $title, '_', ' ' ) );
333 $data[] = $item;
336 sort( $data );
338 $this->getResult()->setIndexedTagName( $data, 'ns' );
340 return $this->getResult()->addValue( 'query', $property, $data );
343 protected function appendSpecialPageAliases( $property ) {
344 global $wgContLang;
345 $data = array();
346 $aliases = $wgContLang->getSpecialPageAliases();
347 foreach ( SpecialPageFactory::getNames() as $specialpage ) {
348 if ( isset( $aliases[$specialpage] ) ) {
349 $arr = array( 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] );
350 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
351 $data[] = $arr;
354 $this->getResult()->setIndexedTagName( $data, 'specialpage' );
356 return $this->getResult()->addValue( 'query', $property, $data );
359 protected function appendMagicWords( $property ) {
360 global $wgContLang;
361 $data = array();
362 foreach ( $wgContLang->getMagicWords() as $magicword => $aliases ) {
363 $caseSensitive = array_shift( $aliases );
364 $arr = array( 'name' => $magicword, 'aliases' => $aliases );
365 if ( $caseSensitive ) {
366 $arr['case-sensitive'] = '';
368 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
369 $data[] = $arr;
371 $this->getResult()->setIndexedTagName( $data, 'magicword' );
373 return $this->getResult()->addValue( 'query', $property, $data );
376 protected function appendInterwikiMap( $property, $filter ) {
377 $local = null;
378 if ( $filter === 'local' ) {
379 $local = 1;
380 } elseif ( $filter === '!local' ) {
381 $local = 0;
382 } elseif ( $filter ) {
383 ApiBase::dieDebug( __METHOD__, "Unknown filter=$filter" );
386 $params = $this->extractRequestParams();
387 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
388 $langNames = Language::fetchLanguageNames( $langCode );
390 $getPrefixes = Interwiki::getAllPrefixes( $local );
391 $extraLangPrefixes = $this->getConfig()->get( 'ExtraInterlanguageLinkPrefixes' );
392 $localInterwikis = $this->getConfig()->get( 'LocalInterwikis' );
393 $data = array();
395 foreach ( $getPrefixes as $row ) {
396 $prefix = $row['iw_prefix'];
397 $val = array();
398 $val['prefix'] = $prefix;
399 if ( isset( $row['iw_local'] ) && $row['iw_local'] == '1' ) {
400 $val['local'] = '';
402 if ( isset( $row['iw_trans'] ) && $row['iw_trans'] == '1' ) {
403 $val['trans'] = '';
406 if ( isset( $langNames[$prefix] ) ) {
407 $val['language'] = $langNames[$prefix];
409 if ( in_array( $prefix, $localInterwikis ) ) {
410 $val['localinterwiki'] = '';
412 if ( in_array( $prefix, $extraLangPrefixes ) ) {
413 $val['extralanglink'] = '';
415 $linktext = wfMessage( "interlanguage-link-$prefix" );
416 if ( !$linktext->isDisabled() ) {
417 $val['linktext'] = $linktext->text();
420 $sitename = wfMessage( "interlanguage-link-sitename-$prefix" );
421 if ( !$sitename->isDisabled() ) {
422 $val['sitename'] = $sitename->text();
426 $val['url'] = wfExpandUrl( $row['iw_url'], PROTO_CURRENT );
427 if ( substr( $row['iw_url'], 0, 2 ) == '//' ) {
428 $val['protorel'] = '';
430 if ( isset( $row['iw_wikiid'] ) ) {
431 $val['wikiid'] = $row['iw_wikiid'];
433 if ( isset( $row['iw_api'] ) ) {
434 $val['api'] = $row['iw_api'];
437 $data[] = $val;
440 $this->getResult()->setIndexedTagName( $data, 'iw' );
442 return $this->getResult()->addValue( 'query', $property, $data );
445 protected function appendDbReplLagInfo( $property, $includeAll ) {
446 $data = array();
447 $lb = wfGetLB();
448 $showHostnames = $this->getConfig()->get( 'ShowHostnames' );
449 if ( $includeAll ) {
450 if ( !$showHostnames ) {
451 $this->dieUsage(
452 'Cannot view all servers info unless $wgShowHostnames is true',
453 'includeAllDenied'
457 $lags = $lb->getLagTimes();
458 foreach ( $lags as $i => $lag ) {
459 $data[] = array(
460 'host' => $lb->getServerName( $i ),
461 'lag' => $lag
464 } else {
465 list( , $lag, $index ) = $lb->getMaxLag();
466 $data[] = array(
467 'host' => $showHostnames
468 ? $lb->getServerName( $index )
469 : '',
470 'lag' => intval( $lag )
474 $result = $this->getResult();
475 $result->setIndexedTagName( $data, 'db' );
477 return $this->getResult()->addValue( 'query', $property, $data );
480 protected function appendStatistics( $property ) {
481 $data = array();
482 $data['pages'] = intval( SiteStats::pages() );
483 $data['articles'] = intval( SiteStats::articles() );
484 $data['edits'] = intval( SiteStats::edits() );
485 $data['images'] = intval( SiteStats::images() );
486 $data['users'] = intval( SiteStats::users() );
487 $data['activeusers'] = intval( SiteStats::activeUsers() );
488 $data['admins'] = intval( SiteStats::numberingroup( 'sysop' ) );
489 $data['jobs'] = intval( SiteStats::jobs() );
491 wfRunHooks( 'APIQuerySiteInfoStatisticsInfo', array( &$data ) );
493 return $this->getResult()->addValue( 'query', $property, $data );
496 protected function appendUserGroups( $property, $numberInGroup ) {
497 $config = $this->getConfig();
499 $data = array();
500 $result = $this->getResult();
501 $allGroups = User::getAllGroups();
502 foreach ( $config->get( 'GroupPermissions' ) as $group => $permissions ) {
503 $arr = array(
504 'name' => $group,
505 'rights' => array_keys( $permissions, true ),
508 if ( $numberInGroup ) {
509 $autopromote = $config->get( 'Autopromote' );
511 if ( $group == 'user' ) {
512 $arr['number'] = SiteStats::users();
513 // '*' and autopromote groups have no size
514 } elseif ( $group !== '*' && !isset( $autopromote[$group] ) ) {
515 $arr['number'] = SiteStats::numberInGroup( $group );
519 $groupArr = array(
520 'add' => $config->get( 'AddGroups' ),
521 'remove' => $config->get( 'RemoveGroups' ),
522 'add-self' => $config->get( 'GroupsAddToSelf' ),
523 'remove-self' => $config->get( 'GroupsRemoveFromSelf' )
526 foreach ( $groupArr as $type => $rights ) {
527 if ( isset( $rights[$group] ) ) {
528 $groups = array_intersect( $rights[$group], $allGroups );
529 if ( $groups ) {
530 $arr[$type] = $groups;
531 $result->setIndexedTagName( $arr[$type], 'group' );
536 $result->setIndexedTagName( $arr['rights'], 'permission' );
537 $data[] = $arr;
540 $result->setIndexedTagName( $data, 'group' );
542 return $result->addValue( 'query', $property, $data );
545 protected function appendFileExtensions( $property ) {
546 $data = array();
547 foreach ( array_unique( $this->getConfig()->get( 'FileExtensions' ) ) as $ext ) {
548 $data[] = array( 'ext' => $ext );
550 $this->getResult()->setIndexedTagName( $data, 'fe' );
552 return $this->getResult()->addValue( 'query', $property, $data );
555 protected function appendExtensions( $property ) {
556 $data = array();
557 foreach ( $this->getConfig()->get( 'ExtensionCredits' ) as $type => $extensions ) {
558 foreach ( $extensions as $ext ) {
559 $ret = array();
560 $ret['type'] = $type;
561 if ( isset( $ext['name'] ) ) {
562 $ret['name'] = $ext['name'];
564 if ( isset( $ext['namemsg'] ) ) {
565 $ret['namemsg'] = $ext['namemsg'];
567 if ( isset( $ext['description'] ) ) {
568 $ret['description'] = $ext['description'];
570 if ( isset( $ext['descriptionmsg'] ) ) {
571 // Can be a string or array( key, param1, param2, ... )
572 if ( is_array( $ext['descriptionmsg'] ) ) {
573 $ret['descriptionmsg'] = $ext['descriptionmsg'][0];
574 $ret['descriptionmsgparams'] = array_slice( $ext['descriptionmsg'], 1 );
575 $this->getResult()->setIndexedTagName( $ret['descriptionmsgparams'], 'param' );
576 } else {
577 $ret['descriptionmsg'] = $ext['descriptionmsg'];
580 if ( isset( $ext['author'] ) ) {
581 $ret['author'] = is_array( $ext['author'] ) ?
582 implode( ', ', $ext['author'] ) : $ext['author'];
584 if ( isset( $ext['url'] ) ) {
585 $ret['url'] = $ext['url'];
587 if ( isset( $ext['version'] ) ) {
588 $ret['version'] = $ext['version'];
589 } elseif ( isset( $ext['svn-revision'] ) &&
590 preg_match( '/\$(?:Rev|LastChangedRevision|Revision): *(\d+)/',
591 $ext['svn-revision'], $m )
593 $ret['version'] = 'r' . $m[1];
595 if ( isset( $ext['path'] ) ) {
596 $extensionPath = dirname( $ext['path'] );
597 $gitInfo = new GitInfo( $extensionPath );
598 $vcsVersion = $gitInfo->getHeadSHA1();
599 if ( $vcsVersion !== false ) {
600 $ret['vcs-system'] = 'git';
601 $ret['vcs-version'] = $vcsVersion;
602 $ret['vcs-url'] = $gitInfo->getHeadViewUrl();
603 $vcsDate = $gitInfo->getHeadCommitDate();
604 if ( $vcsDate !== false ) {
605 $ret['vcs-date'] = wfTimestamp( TS_ISO_8601, $vcsDate );
607 } else {
608 $svnInfo = SpecialVersion::getSvnInfo( $extensionPath );
609 if ( $svnInfo !== false ) {
610 $ret['vcs-system'] = 'svn';
611 $ret['vcs-version'] = $svnInfo['checkout-rev'];
612 $ret['vcs-url'] = isset( $svnInfo['viewvc-url'] ) ? $svnInfo['viewvc-url'] : '';
616 if ( SpecialVersion::getExtLicenseFileName( $extensionPath ) ) {
617 $ret['license-name'] = isset( $ext['license-name'] ) ? $ext['license-name'] : '';
618 $ret['license'] = SpecialPage::getTitleFor(
619 'Version',
620 "License/{$ext['name']}"
621 )->getLinkURL();
624 if ( SpecialVersion::getExtAuthorsFileName( $extensionPath ) ) {
625 $ret['credits'] = SpecialPage::getTitleFor(
626 'Version',
627 "Credits/{$ext['name']}"
628 )->getLinkURL();
631 $data[] = $ret;
635 $this->getResult()->setIndexedTagName( $data, 'ext' );
637 return $this->getResult()->addValue( 'query', $property, $data );
640 protected function appendRightsInfo( $property ) {
641 $config = $this->getConfig();
642 $title = Title::newFromText( $config->get( 'RightsPage' ) );
643 $url = $title ? wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ) : $config->get( 'RightsUrl' );
644 $text = $config->get( 'RightsText' );
645 if ( !$text && $title ) {
646 $text = $title->getPrefixedText();
649 $data = array(
650 'url' => $url ? $url : '',
651 'text' => $text ? $text : ''
654 return $this->getResult()->addValue( 'query', $property, $data );
657 protected function appendRestrictions( $property ) {
658 $config = $this->getConfig();
659 $data = array(
660 'types' => $config->get( 'RestrictionTypes' ),
661 'levels' => $config->get( 'RestrictionLevels' ),
662 'cascadinglevels' => $config->get( 'CascadingRestrictionLevels' ),
663 'semiprotectedlevels' => $config->get( 'SemiprotectedRestrictionLevels' ),
666 $this->getResult()->setIndexedTagName( $data['types'], 'type' );
667 $this->getResult()->setIndexedTagName( $data['levels'], 'level' );
668 $this->getResult()->setIndexedTagName( $data['cascadinglevels'], 'level' );
669 $this->getResult()->setIndexedTagName( $data['semiprotectedlevels'], 'level' );
671 return $this->getResult()->addValue( 'query', $property, $data );
674 public function appendLanguages( $property ) {
675 $params = $this->extractRequestParams();
676 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
677 $langNames = Language::fetchLanguageNames( $langCode );
679 $data = array();
681 foreach ( $langNames as $code => $name ) {
682 $lang = array( 'code' => $code );
683 ApiResult::setContent( $lang, $name );
684 $data[] = $lang;
686 $this->getResult()->setIndexedTagName( $data, 'lang' );
688 return $this->getResult()->addValue( 'query', $property, $data );
691 public function appendSkins( $property ) {
692 $data = array();
693 $allowed = Skin::getAllowedSkins();
694 $default = Skin::normalizeKey( 'default' );
695 foreach ( Skin::getSkinNames() as $name => $displayName ) {
696 $msg = $this->msg( "skinname-{$name}" );
697 $code = $this->getParameter( 'inlanguagecode' );
698 if ( $code && Language::isValidCode( $code ) ) {
699 $msg->inLanguage( $code );
700 } else {
701 $msg->inContentLanguage();
703 if ( $msg->exists() ) {
704 $displayName = $msg->text();
706 $skin = array( 'code' => $name );
707 ApiResult::setContent( $skin, $displayName );
708 if ( !isset( $allowed[$name] ) ) {
709 $skin['unusable'] = '';
711 if ( $name === $default ) {
712 $skin['default'] = '';
714 $data[] = $skin;
716 $this->getResult()->setIndexedTagName( $data, 'skin' );
718 return $this->getResult()->addValue( 'query', $property, $data );
721 public function appendExtensionTags( $property ) {
722 global $wgParser;
723 $wgParser->firstCallInit();
724 $tags = array_map( array( $this, 'formatParserTags' ), $wgParser->getTags() );
725 $this->getResult()->setIndexedTagName( $tags, 't' );
727 return $this->getResult()->addValue( 'query', $property, $tags );
730 public function appendFunctionHooks( $property ) {
731 global $wgParser;
732 $wgParser->firstCallInit();
733 $hooks = $wgParser->getFunctionHooks();
734 $this->getResult()->setIndexedTagName( $hooks, 'h' );
736 return $this->getResult()->addValue( 'query', $property, $hooks );
739 public function appendVariables( $property ) {
740 $variables = MagicWord::getVariableIDs();
741 $this->getResult()->setIndexedTagName( $variables, 'v' );
743 return $this->getResult()->addValue( 'query', $property, $variables );
746 public function appendProtocols( $property ) {
747 // Make a copy of the global so we don't try to set the _element key of it - bug 45130
748 $protocols = array_values( $this->getConfig()->get( 'UrlProtocols' ) );
749 $this->getResult()->setIndexedTagName( $protocols, 'p' );
751 return $this->getResult()->addValue( 'query', $property, $protocols );
754 public function appendDefaultOptions( $property ) {
755 return $this->getResult()->addValue( 'query', $property, User::getDefaultOptions() );
758 private function formatParserTags( $item ) {
759 return "<{$item}>";
762 public function appendSubscribedHooks( $property ) {
763 $hooks = $this->getConfig()->get( 'Hooks' );
764 $myWgHooks = $hooks;
765 ksort( $myWgHooks );
767 $data = array();
768 foreach ( $myWgHooks as $name => $subscribers ) {
769 $arr = array(
770 'name' => $name,
771 'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $subscribers ),
774 $this->getResult()->setIndexedTagName( $arr['subscribers'], 's' );
775 $data[] = $arr;
778 $this->getResult()->setIndexedTagName( $data, 'hook' );
780 return $this->getResult()->addValue( 'query', $property, $data );
783 public function getCacheMode( $params ) {
784 // Messages for $wgExtraInterlanguageLinkPrefixes depend on user language
785 if (
786 count( $this->getConfig()->get( 'ExtraInterlanguageLinkPrefixes' ) ) &&
787 !is_null( $params['prop'] ) &&
788 in_array( 'interwikimap', $params['prop'] )
790 return 'anon-public-user-private';
793 return 'public';
796 public function getAllowedParams() {
797 return array(
798 'prop' => array(
799 ApiBase::PARAM_DFLT => 'general',
800 ApiBase::PARAM_ISMULTI => true,
801 ApiBase::PARAM_TYPE => array(
802 'general',
803 'namespaces',
804 'namespacealiases',
805 'specialpagealiases',
806 'magicwords',
807 'interwikimap',
808 'dbrepllag',
809 'statistics',
810 'usergroups',
811 'extensions',
812 'fileextensions',
813 'rightsinfo',
814 'restrictions',
815 'languages',
816 'skins',
817 'extensiontags',
818 'functionhooks',
819 'showhooks',
820 'variables',
821 'protocols',
822 'defaultoptions',
825 'filteriw' => array(
826 ApiBase::PARAM_TYPE => array(
827 'local',
828 '!local',
831 'showalldb' => false,
832 'numberingroup' => false,
833 'inlanguagecode' => null,
837 public function getParamDescription() {
838 $p = $this->getModulePrefix();
840 return array(
841 'prop' => array(
842 'Which sysinfo properties to get:',
843 ' general - Overall system information',
844 ' namespaces - List of registered namespaces and their canonical names',
845 ' namespacealiases - List of registered namespace aliases',
846 ' specialpagealiases - List of special page aliases',
847 ' magicwords - List of magic words and their aliases',
848 ' statistics - Returns site statistics',
849 ' interwikimap - Returns interwiki map ' .
850 "(optionally filtered, (optionally localised by using {$p}inlanguagecode))",
851 ' dbrepllag - Returns database server with the highest replication lag',
852 ' usergroups - Returns user groups and the associated permissions',
853 ' extensions - Returns extensions installed on the wiki',
854 ' fileextensions - Returns list of file extensions allowed to be uploaded',
855 ' rightsinfo - Returns wiki rights (license) information if available',
856 ' restrictions - Returns information on available restriction (protection) types',
857 ' languages - Returns a list of languages MediaWiki supports ' .
858 "(optionally localised by using {$p}inlanguagecode)",
859 ' skins - Returns a list of all enabled skins ' .
860 "(optionally localised by using {$p}inlanguagecode, otherwise in content language)",
861 ' extensiontags - Returns a list of parser extension tags',
862 ' functionhooks - Returns a list of parser function hooks',
863 ' showhooks - Returns a list of all subscribed hooks (contents of $wgHooks)',
864 ' variables - Returns a list of variable IDs',
865 ' protocols - Returns a list of protocols that are allowed in external links.',
866 ' defaultoptions - Returns the default values for user preferences.',
868 'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
869 'showalldb' => 'List all database servers, not just the one lagging the most',
870 'numberingroup' => 'Lists the number of users in user groups',
871 'inlanguagecode' => 'Language code for localised language names ' .
872 '(best effort, use CLDR extension) and skin names',
876 public function getDescription() {
877 return 'Return general information about the site.';
880 public function getExamples() {
881 return array(
882 'api.php?action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics',
883 'api.php?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local',
884 'api.php?action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb=',
888 public function getHelpUrls() {
889 return 'https://www.mediawiki.org/wiki/API:Meta#siteinfo_.2F_si';