Don't send rel=canonical to variant-neutral page
[mediawiki.git] / includes / api / ApiQuerySiteinfo.php
blobf17ac29b813ffb12814fa5835633046047eb00ae
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 $data['dbtype'] = $config->get( 'DBtype' );
142 $data['dbversion'] = $this->getDB()->getServerVersion();
144 $allowFrom = array( '' );
145 $allowException = true;
146 if ( !$config->get( 'AllowExternalImages' ) ) {
147 if ( $config->get( 'EnableImageWhitelist' ) ) {
148 $data['imagewhitelistenabled'] = '';
150 $allowFrom = $config->get( 'AllowExternalImagesFrom' );
151 $allowException = !empty( $allowFrom );
153 if ( $allowException ) {
154 $data['externalimages'] = (array)$allowFrom;
155 $this->getResult()->setIndexedTagName( $data['externalimages'], 'prefix' );
158 if ( !$config->get( 'DisableLangConversion' ) ) {
159 $data['langconversion'] = '';
162 if ( !$config->get( 'DisableTitleConversion' ) ) {
163 $data['titleconversion'] = '';
166 if ( $wgContLang->linkPrefixExtension() ) {
167 $linkPrefixCharset = $wgContLang->linkPrefixCharset();
168 $data['linkprefixcharset'] = $linkPrefixCharset;
169 // For backwards compatibility
170 $data['linkprefix'] = "/^((?>.*[^$linkPrefixCharset]|))(.+)$/sDu";
171 } else {
172 $data['linkprefixcharset'] = '';
173 $data['linkprefix'] = '';
176 $linktrail = $wgContLang->linkTrail();
177 if ( $linktrail ) {
178 $data['linktrail'] = $linktrail;
179 } else {
180 $data['linktrail'] = '';
183 global $IP;
184 $git = SpecialVersion::getGitHeadSha1( $IP );
185 if ( $git ) {
186 $data['git-hash'] = $git;
187 $data['git-branch'] =
188 SpecialVersion::getGitCurrentBranch( $GLOBALS['IP'] );
189 } else {
190 $svn = SpecialVersion::getSvnRevision( $IP );
191 if ( $svn ) {
192 $data['rev'] = $svn;
196 // 'case-insensitive' option is reserved for future
197 $data['case'] = $config->get( 'CapitalLinks' ) ? 'first-letter' : 'case-sensitive';
198 $data['lang'] = $config->get( 'LanguageCode' );
200 $fallbacks = array();
201 foreach ( $wgContLang->getFallbackLanguages() as $code ) {
202 $fallbacks[] = array( 'code' => $code );
204 $data['fallback'] = $fallbacks;
205 $this->getResult()->setIndexedTagName( $data['fallback'], 'lang' );
207 if ( $wgContLang->hasVariants() ) {
208 $variants = array();
209 foreach ( $wgContLang->getVariants() as $code ) {
210 $variants[] = array(
211 'code' => $code,
212 'name' => $wgContLang->getVariantname( $code ),
215 $data['variants'] = $variants;
216 $this->getResult()->setIndexedTagName( $data['variants'], 'lang' );
219 if ( $wgContLang->isRTL() ) {
220 $data['rtl'] = '';
222 $data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
224 if ( wfReadOnly() ) {
225 $data['readonly'] = '';
226 $data['readonlyreason'] = wfReadOnlyReason();
228 if ( $config->get( 'EnableWriteAPI' ) ) {
229 $data['writeapi'] = '';
232 $tz = $config->get( 'Localtimezone' );
233 $offset = $config->get( 'LocalTZoffset' );
234 if ( is_null( $tz ) ) {
235 $tz = 'UTC';
236 $offset = 0;
237 } elseif ( is_null( $offset ) ) {
238 $offset = 0;
240 $data['timezone'] = $tz;
241 $data['timeoffset'] = intval( $offset );
242 $data['articlepath'] = $config->get( 'ArticlePath' );
243 $data['scriptpath'] = $config->get( 'ScriptPath' );
244 $data['script'] = $config->get( 'Script' );
245 $data['variantarticlepath'] = $config->get( 'VariantArticlePath' );
246 $data['server'] = $config->get( 'Server' );
247 $data['servername'] = $config->get( 'ServerName' );
248 $data['wikiid'] = wfWikiID();
249 $data['time'] = wfTimestamp( TS_ISO_8601, time() );
251 if ( $config->get( 'MiserMode' ) ) {
252 $data['misermode'] = '';
255 $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
257 $data['thumblimits'] = $config->get( 'ThumbLimits' );
258 $this->getResult()->setIndexedTagName( $data['thumblimits'], 'limit' );
259 $data['imagelimits'] = array();
260 $this->getResult()->setIndexedTagName( $data['imagelimits'], 'limit' );
261 foreach ( $config->get( 'ImageLimits' ) as $k => $limit ) {
262 $data['imagelimits'][$k] = array( 'width' => $limit[0], 'height' => $limit[1] );
265 $favicon = $config->get( 'Favicon' );
266 if ( !empty( $favicon ) ) {
267 // wgFavicon can either be a relative or an absolute path
268 // make sure we always return an absolute path
269 $data['favicon'] = wfExpandUrl( $favicon, PROTO_RELATIVE );
272 wfRunHooks( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
274 return $this->getResult()->addValue( 'query', $property, $data );
277 protected function appendNamespaces( $property ) {
278 global $wgContLang;
279 $data = array();
280 foreach ( $wgContLang->getFormattedNamespaces() as $ns => $title ) {
281 $data[$ns] = array(
282 'id' => intval( $ns ),
283 'case' => MWNamespace::isCapitalized( $ns ) ? 'first-letter' : 'case-sensitive',
285 ApiResult::setContent( $data[$ns], $title );
286 $canonical = MWNamespace::getCanonicalName( $ns );
288 if ( MWNamespace::hasSubpages( $ns ) ) {
289 $data[$ns]['subpages'] = '';
292 if ( $canonical ) {
293 $data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
296 if ( MWNamespace::isContent( $ns ) ) {
297 $data[$ns]['content'] = '';
300 if ( MWNamespace::isNonincludable( $ns ) ) {
301 $data[$ns]['nonincludable'] = '';
304 $contentmodel = MWNamespace::getNamespaceContentModel( $ns );
305 if ( $contentmodel ) {
306 $data[$ns]['defaultcontentmodel'] = $contentmodel;
310 $this->getResult()->setIndexedTagName( $data, 'ns' );
312 return $this->getResult()->addValue( 'query', $property, $data );
315 protected function appendNamespaceAliases( $property ) {
316 global $wgContLang;
317 $aliases = array_merge( $this->getConfig()->get( 'NamespaceAliases' ),
318 $wgContLang->getNamespaceAliases() );
319 $namespaces = $wgContLang->getNamespaces();
320 $data = array();
321 foreach ( $aliases as $title => $ns ) {
322 if ( $namespaces[$ns] == $title ) {
323 // Don't list duplicates
324 continue;
326 $item = array(
327 'id' => intval( $ns )
329 ApiResult::setContent( $item, strtr( $title, '_', ' ' ) );
330 $data[] = $item;
333 sort( $data );
335 $this->getResult()->setIndexedTagName( $data, 'ns' );
337 return $this->getResult()->addValue( 'query', $property, $data );
340 protected function appendSpecialPageAliases( $property ) {
341 global $wgContLang;
342 $data = array();
343 $aliases = $wgContLang->getSpecialPageAliases();
344 foreach ( SpecialPageFactory::getList() as $specialpage => $stuff ) {
345 if ( isset( $aliases[$specialpage] ) ) {
346 $arr = array( 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] );
347 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
348 $data[] = $arr;
351 $this->getResult()->setIndexedTagName( $data, 'specialpage' );
353 return $this->getResult()->addValue( 'query', $property, $data );
356 protected function appendMagicWords( $property ) {
357 global $wgContLang;
358 $data = array();
359 foreach ( $wgContLang->getMagicWords() as $magicword => $aliases ) {
360 $caseSensitive = array_shift( $aliases );
361 $arr = array( 'name' => $magicword, 'aliases' => $aliases );
362 if ( $caseSensitive ) {
363 $arr['case-sensitive'] = '';
365 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
366 $data[] = $arr;
368 $this->getResult()->setIndexedTagName( $data, 'magicword' );
370 return $this->getResult()->addValue( 'query', $property, $data );
373 protected function appendInterwikiMap( $property, $filter ) {
374 $local = null;
375 if ( $filter === 'local' ) {
376 $local = 1;
377 } elseif ( $filter === '!local' ) {
378 $local = 0;
379 } elseif ( $filter ) {
380 ApiBase::dieDebug( __METHOD__, "Unknown filter=$filter" );
383 $params = $this->extractRequestParams();
384 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
385 $langNames = Language::fetchLanguageNames( $langCode );
387 $getPrefixes = Interwiki::getAllPrefixes( $local );
388 $extraLangPrefixes = $this->getConfig()->get( 'ExtraInterlanguageLinkPrefixes' );
389 $localInterwikis = $this->getConfig()->get( 'LocalInterwikis' );
390 $data = array();
392 foreach ( $getPrefixes as $row ) {
393 $prefix = $row['iw_prefix'];
394 $val = array();
395 $val['prefix'] = $prefix;
396 if ( isset( $row['iw_local'] ) && $row['iw_local'] == '1' ) {
397 $val['local'] = '';
399 if ( $row['iw_trans'] == '1' ) {
400 $val['trans'] = '';
403 if ( isset( $langNames[$prefix] ) ) {
404 $val['language'] = $langNames[$prefix];
406 if ( in_array( $prefix, $localInterwikis ) ) {
407 $val['localinterwiki'] = '';
409 if ( in_array( $prefix, $extraLangPrefixes ) ) {
410 $val['extralanglink'] = '';
412 $linktext = wfMessage( "interlanguage-link-$prefix" );
413 if ( !$linktext->isDisabled() ) {
414 $val['linktext'] = $linktext->text();
417 $sitename = wfMessage( "interlanguage-link-sitename-$prefix" );
418 if ( !$sitename->isDisabled() ) {
419 $val['sitename'] = $sitename->text();
423 $val['url'] = wfExpandUrl( $row['iw_url'], PROTO_CURRENT );
424 if ( substr( $row['iw_url'], 0, 2 ) == '//' ) {
425 $val['protorel'] = '';
427 if ( isset( $row['iw_wikiid'] ) ) {
428 $val['wikiid'] = $row['iw_wikiid'];
430 if ( isset( $row['iw_api'] ) ) {
431 $val['api'] = $row['iw_api'];
434 $data[] = $val;
437 $this->getResult()->setIndexedTagName( $data, 'iw' );
439 return $this->getResult()->addValue( 'query', $property, $data );
442 protected function appendDbReplLagInfo( $property, $includeAll ) {
443 $data = array();
444 $lb = wfGetLB();
445 $showHostnames = $this->getConfig()->get( 'ShowHostnames' );
446 if ( $includeAll ) {
447 if ( !$showHostnames ) {
448 $this->dieUsage(
449 'Cannot view all servers info unless $wgShowHostnames is true',
450 'includeAllDenied'
454 $lags = $lb->getLagTimes();
455 foreach ( $lags as $i => $lag ) {
456 $data[] = array(
457 'host' => $lb->getServerName( $i ),
458 'lag' => $lag
461 } else {
462 list( , $lag, $index ) = $lb->getMaxLag();
463 $data[] = array(
464 'host' => $showHostnames
465 ? $lb->getServerName( $index )
466 : '',
467 'lag' => intval( $lag )
471 $result = $this->getResult();
472 $result->setIndexedTagName( $data, 'db' );
474 return $this->getResult()->addValue( 'query', $property, $data );
477 protected function appendStatistics( $property ) {
478 $data = array();
479 $data['pages'] = intval( SiteStats::pages() );
480 $data['articles'] = intval( SiteStats::articles() );
481 if ( !$this->getConfig()->get( 'DisableCounters' ) ) {
482 $data['views'] = intval( SiteStats::views() );
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 foreach ( $config->get( 'GroupPermissions' ) as $group => $permissions ) {
502 $arr = array(
503 'name' => $group,
504 'rights' => array_keys( $permissions, true ),
507 if ( $numberInGroup ) {
508 $autopromote = $config->get( 'Autopromote' );
510 if ( $group == 'user' ) {
511 $arr['number'] = SiteStats::users();
512 // '*' and autopromote groups have no size
513 } elseif ( $group !== '*' && !isset( $autopromote[$group] ) ) {
514 $arr['number'] = SiteStats::numberInGroup( $group );
518 $groupArr = array(
519 'add' => $config->get( 'AddGroups' ),
520 'remove' => $config->get( 'RemoveGroups' ),
521 'add-self' => $config->get( 'GroupsAddToSelf' ),
522 'remove-self' => $config->get( 'GroupsRemoveFromSelf' )
525 foreach ( $groupArr as $type => $rights ) {
526 if ( isset( $rights[$group] ) ) {
527 $arr[$type] = $rights[$group];
528 $result->setIndexedTagName( $arr[$type], 'group' );
532 $result->setIndexedTagName( $arr['rights'], 'permission' );
533 $data[] = $arr;
536 $result->setIndexedTagName( $data, 'group' );
538 return $result->addValue( 'query', $property, $data );
541 protected function appendFileExtensions( $property ) {
542 $data = array();
543 foreach ( array_unique( $this->getConfig()->get( 'FileExtensions' ) ) as $ext ) {
544 $data[] = array( 'ext' => $ext );
546 $this->getResult()->setIndexedTagName( $data, 'fe' );
548 return $this->getResult()->addValue( 'query', $property, $data );
551 protected function appendExtensions( $property ) {
552 $data = array();
553 foreach ( $this->getConfig()->get( 'ExtensionCredits' ) as $type => $extensions ) {
554 foreach ( $extensions as $ext ) {
555 $ret = array();
556 $ret['type'] = $type;
557 if ( isset( $ext['name'] ) ) {
558 $ret['name'] = $ext['name'];
560 if ( isset( $ext['namemsg'] ) ) {
561 $ret['namemsg'] = $ext['namemsg'];
563 if ( isset( $ext['description'] ) ) {
564 $ret['description'] = $ext['description'];
566 if ( isset( $ext['descriptionmsg'] ) ) {
567 // Can be a string or array( key, param1, param2, ... )
568 if ( is_array( $ext['descriptionmsg'] ) ) {
569 $ret['descriptionmsg'] = $ext['descriptionmsg'][0];
570 $ret['descriptionmsgparams'] = array_slice( $ext['descriptionmsg'], 1 );
571 $this->getResult()->setIndexedTagName( $ret['descriptionmsgparams'], 'param' );
572 } else {
573 $ret['descriptionmsg'] = $ext['descriptionmsg'];
576 if ( isset( $ext['author'] ) ) {
577 $ret['author'] = is_array( $ext['author'] ) ?
578 implode( ', ', $ext['author'] ) : $ext['author'];
580 if ( isset( $ext['url'] ) ) {
581 $ret['url'] = $ext['url'];
583 if ( isset( $ext['version'] ) ) {
584 $ret['version'] = $ext['version'];
585 } elseif ( isset( $ext['svn-revision'] ) &&
586 preg_match( '/\$(?:Rev|LastChangedRevision|Revision): *(\d+)/',
587 $ext['svn-revision'], $m )
589 $ret['version'] = 'r' . $m[1];
591 if ( isset( $ext['path'] ) ) {
592 $extensionPath = dirname( $ext['path'] );
593 $gitInfo = new GitInfo( $extensionPath );
594 $vcsVersion = $gitInfo->getHeadSHA1();
595 if ( $vcsVersion !== false ) {
596 $ret['vcs-system'] = 'git';
597 $ret['vcs-version'] = $vcsVersion;
598 $ret['vcs-url'] = $gitInfo->getHeadViewUrl();
599 $vcsDate = $gitInfo->getHeadCommitDate();
600 if ( $vcsDate !== false ) {
601 $ret['vcs-date'] = wfTimestamp( TS_ISO_8601, $vcsDate );
603 } else {
604 $svnInfo = SpecialVersion::getSvnInfo( $extensionPath );
605 if ( $svnInfo !== false ) {
606 $ret['vcs-system'] = 'svn';
607 $ret['vcs-version'] = $svnInfo['checkout-rev'];
608 $ret['vcs-url'] = isset( $svnInfo['viewvc-url'] ) ? $svnInfo['viewvc-url'] : '';
612 if ( SpecialVersion::getExtLicenseFileName( $extensionPath ) ) {
613 $ret['license-name'] = isset( $ext['license-name'] ) ? $ext['license-name'] : '';
614 $ret['license'] = SpecialPage::getTitleFor(
615 'Version',
616 "License/{$ext['name']}"
617 )->getLinkURL();
620 if ( SpecialVersion::getExtAuthorsFileName( $extensionPath ) ) {
621 $ret['credits'] = SpecialPage::getTitleFor(
622 'Version',
623 "Credits/{$ext['name']}"
624 )->getLinkURL();
627 $data[] = $ret;
631 $this->getResult()->setIndexedTagName( $data, 'ext' );
633 return $this->getResult()->addValue( 'query', $property, $data );
636 protected function appendRightsInfo( $property ) {
637 $config = $this->getConfig();
638 $title = Title::newFromText( $config->get( 'RightsPage' ) );
639 $url = $title ? wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ) : $config->get( 'RightsUrl' );
640 $text = $config->get( 'RightsText' );
641 if ( !$text && $title ) {
642 $text = $title->getPrefixedText();
645 $data = array(
646 'url' => $url ? $url : '',
647 'text' => $text ? $text : ''
650 return $this->getResult()->addValue( 'query', $property, $data );
653 protected function appendRestrictions( $property ) {
654 $config = $this->getConfig();
655 $data = array(
656 'types' => $config->get( 'RestrictionTypes' ),
657 'levels' => $config->get( 'RestrictionLevels' ),
658 'cascadinglevels' => $config->get( 'CascadingRestrictionLevels' ),
659 'semiprotectedlevels' => $config->get( 'SemiprotectedRestrictionLevels' ),
662 $this->getResult()->setIndexedTagName( $data['types'], 'type' );
663 $this->getResult()->setIndexedTagName( $data['levels'], 'level' );
664 $this->getResult()->setIndexedTagName( $data['cascadinglevels'], 'level' );
665 $this->getResult()->setIndexedTagName( $data['semiprotectedlevels'], 'level' );
667 return $this->getResult()->addValue( 'query', $property, $data );
670 public function appendLanguages( $property ) {
671 $params = $this->extractRequestParams();
672 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
673 $langNames = Language::fetchLanguageNames( $langCode );
675 $data = array();
677 foreach ( $langNames as $code => $name ) {
678 $lang = array( 'code' => $code );
679 ApiResult::setContent( $lang, $name );
680 $data[] = $lang;
682 $this->getResult()->setIndexedTagName( $data, 'lang' );
684 return $this->getResult()->addValue( 'query', $property, $data );
687 public function appendSkins( $property ) {
688 $data = array();
689 $allowed = Skin::getAllowedSkins();
690 $default = Skin::normalizeKey( 'default' );
691 foreach ( Skin::getSkinNames() as $name => $displayName ) {
692 $skin = array( 'code' => $name );
693 ApiResult::setContent( $skin, $displayName );
694 if ( !isset( $allowed[$name] ) ) {
695 $skin['unusable'] = '';
697 if ( $name === $default ) {
698 $skin['default'] = '';
700 $data[] = $skin;
702 $this->getResult()->setIndexedTagName( $data, 'skin' );
704 return $this->getResult()->addValue( 'query', $property, $data );
707 public function appendExtensionTags( $property ) {
708 global $wgParser;
709 $wgParser->firstCallInit();
710 $tags = array_map( array( $this, 'formatParserTags' ), $wgParser->getTags() );
711 $this->getResult()->setIndexedTagName( $tags, 't' );
713 return $this->getResult()->addValue( 'query', $property, $tags );
716 public function appendFunctionHooks( $property ) {
717 global $wgParser;
718 $wgParser->firstCallInit();
719 $hooks = $wgParser->getFunctionHooks();
720 $this->getResult()->setIndexedTagName( $hooks, 'h' );
722 return $this->getResult()->addValue( 'query', $property, $hooks );
725 public function appendVariables( $property ) {
726 $variables = MagicWord::getVariableIDs();
727 $this->getResult()->setIndexedTagName( $variables, 'v' );
729 return $this->getResult()->addValue( 'query', $property, $variables );
732 public function appendProtocols( $property ) {
733 // Make a copy of the global so we don't try to set the _element key of it - bug 45130
734 $protocols = array_values( $this->getConfig()->get( 'UrlProtocols' ) );
735 $this->getResult()->setIndexedTagName( $protocols, 'p' );
737 return $this->getResult()->addValue( 'query', $property, $protocols );
740 public function appendDefaultOptions( $property ) {
741 return $this->getResult()->addValue( 'query', $property, User::getDefaultOptions() );
744 private function formatParserTags( $item ) {
745 return "<{$item}>";
748 public function appendSubscribedHooks( $property ) {
749 $hooks = $this->getConfig()->get( 'Hooks' );
750 $myWgHooks = $hooks;
751 ksort( $myWgHooks );
753 $data = array();
754 foreach ( $myWgHooks as $name => $subscribers ) {
755 $arr = array(
756 'name' => $name,
757 'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $subscribers ),
760 $this->getResult()->setIndexedTagName( $arr['subscribers'], 's' );
761 $data[] = $arr;
764 $this->getResult()->setIndexedTagName( $data, 'hook' );
766 return $this->getResult()->addValue( 'query', $property, $data );
769 public function getCacheMode( $params ) {
770 // Messages for $wgExtraInterlanguageLinkPrefixes depend on user language
771 if (
772 count( $this->getConfig()->get( 'ExtraInterlanguageLinkPrefixes' ) ) &&
773 !is_null( $params['prop'] ) &&
774 in_array( 'interwikimap', $params['prop'] )
776 return 'anon-public-user-private';
779 return 'public';
782 public function getAllowedParams() {
783 return array(
784 'prop' => array(
785 ApiBase::PARAM_DFLT => 'general',
786 ApiBase::PARAM_ISMULTI => true,
787 ApiBase::PARAM_TYPE => array(
788 'general',
789 'namespaces',
790 'namespacealiases',
791 'specialpagealiases',
792 'magicwords',
793 'interwikimap',
794 'dbrepllag',
795 'statistics',
796 'usergroups',
797 'extensions',
798 'fileextensions',
799 'rightsinfo',
800 'restrictions',
801 'languages',
802 'skins',
803 'extensiontags',
804 'functionhooks',
805 'showhooks',
806 'variables',
807 'protocols',
808 'defaultoptions',
811 'filteriw' => array(
812 ApiBase::PARAM_TYPE => array(
813 'local',
814 '!local',
817 'showalldb' => false,
818 'numberingroup' => false,
819 'inlanguagecode' => null,
823 public function getParamDescription() {
824 $p = $this->getModulePrefix();
826 return array(
827 'prop' => array(
828 'Which sysinfo properties to get:',
829 ' general - Overall system information',
830 ' namespaces - List of registered namespaces and their canonical names',
831 ' namespacealiases - List of registered namespace aliases',
832 ' specialpagealiases - List of special page aliases',
833 ' magicwords - List of magic words and their aliases',
834 ' statistics - Returns site statistics',
835 ' interwikimap - Returns interwiki map ' .
836 "(optionally filtered, (optionally localised by using {$p}inlanguagecode))",
837 ' dbrepllag - Returns database server with the highest replication lag',
838 ' usergroups - Returns user groups and the associated permissions',
839 ' extensions - Returns extensions installed on the wiki',
840 ' fileextensions - Returns list of file extensions allowed to be uploaded',
841 ' rightsinfo - Returns wiki rights (license) information if available',
842 ' restrictions - Returns information on available restriction (protection) types',
843 ' languages - Returns a list of languages MediaWiki supports' .
844 "(optionally localised by using {$p}inlanguagecode)",
845 ' skins - Returns a list of all enabled skins',
846 ' extensiontags - Returns a list of parser extension tags',
847 ' functionhooks - Returns a list of parser function hooks',
848 ' showhooks - Returns a list of all subscribed hooks (contents of $wgHooks)',
849 ' variables - Returns a list of variable IDs',
850 ' protocols - Returns a list of protocols that are allowed in external links.',
851 ' defaultoptions - Returns the default values for user preferences.',
853 'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
854 'showalldb' => 'List all database servers, not just the one lagging the most',
855 'numberingroup' => 'Lists the number of users in user groups',
856 'inlanguagecode' => 'Language code for localised language names ' .
857 '(best effort, use CLDR extension)',
861 public function getDescription() {
862 return 'Return general information about the site.';
865 public function getExamples() {
866 return array(
867 'api.php?action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics',
868 'api.php?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local',
869 'api.php?action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb=',
873 public function getHelpUrls() {
874 return 'https://www.mediawiki.org/wiki/API:Meta#siteinfo_.2F_si';