Add $wgFavicon to siteinfo API
[lhc/web/wiklou.git] / includes / api / ApiQuerySiteinfo.php
1 <?php
2 /**
3 *
4 *
5 * Created on Sep 25, 2006
6 *
7 * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 * http://www.gnu.org/copyleft/gpl.html
23 *
24 * @file
25 */
26
27 /**
28 * A query action to return meta information about the wiki site.
29 *
30 * @ingroup API
31 */
32 class ApiQuerySiteinfo extends ApiQueryBase {
33
34 public function __construct( $query, $moduleName ) {
35 parent::__construct( $query, $moduleName, 'si' );
36 }
37
38 public function execute() {
39 $params = $this->extractRequestParams();
40 $done = array();
41 $fit = false;
42 foreach ( $params['prop'] as $p ) {
43 switch ( $p ) {
44 case 'general':
45 $fit = $this->appendGeneralInfo( $p );
46 break;
47 case 'namespaces':
48 $fit = $this->appendNamespaces( $p );
49 break;
50 case 'namespacealiases':
51 $fit = $this->appendNamespaceAliases( $p );
52 break;
53 case 'specialpagealiases':
54 $fit = $this->appendSpecialPageAliases( $p );
55 break;
56 case 'magicwords':
57 $fit = $this->appendMagicWords( $p );
58 break;
59 case 'interwikimap':
60 $filteriw = isset( $params['filteriw'] ) ? $params['filteriw'] : false;
61 $fit = $this->appendInterwikiMap( $p, $filteriw );
62 break;
63 case 'dbrepllag':
64 $fit = $this->appendDbReplLagInfo( $p, $params['showalldb'] );
65 break;
66 case 'statistics':
67 $fit = $this->appendStatistics( $p );
68 break;
69 case 'usergroups':
70 $fit = $this->appendUserGroups( $p, $params['numberingroup'] );
71 break;
72 case 'extensions':
73 $fit = $this->appendExtensions( $p );
74 break;
75 case 'fileextensions':
76 $fit = $this->appendFileExtensions( $p );
77 break;
78 case 'rightsinfo':
79 $fit = $this->appendRightsInfo( $p );
80 break;
81 case 'languages':
82 $fit = $this->appendLanguages( $p );
83 break;
84 case 'skins':
85 $fit = $this->appendSkins( $p );
86 break;
87 case 'extensiontags':
88 $fit = $this->appendExtensionTags( $p );
89 break;
90 case 'functionhooks':
91 $fit = $this->appendFunctionHooks( $p );
92 break;
93 case 'showhooks':
94 $fit = $this->appendSubscribedHooks( $p );
95 break;
96 case 'variables':
97 $fit = $this->appendVariables( $p );
98 break;
99 case 'protocols':
100 $fit = $this->appendProtocols( $p );
101 break;
102 case 'defaultoptions':
103 $fit = $this->appendDefaultOptions( $p );
104 break;
105 default:
106 ApiBase::dieDebug( __METHOD__, "Unknown prop=$p" );
107 }
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;
114 }
115 $done[] = $p;
116 }
117 }
118
119 protected function appendGeneralInfo( $property ) {
120 global $wgContLang, $wgDisableLangConversion, $wgDisableTitleConversion;
121
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();
133
134 $allowFrom = array( '' );
135 $allowException = true;
136 if ( !$GLOBALS['wgAllowExternalImages'] ) {
137 if ( $GLOBALS['wgEnableImageWhitelist'] ) {
138 $data['imagewhitelistenabled'] = '';
139 }
140 $allowFrom = $GLOBALS['wgAllowExternalImagesFrom'];
141 $allowException = !empty( $allowFrom );
142 }
143 if ( $allowException ) {
144 $data['externalimages'] = (array)$allowFrom;
145 $this->getResult()->setIndexedTagName( $data['externalimages'], 'prefix' );
146 }
147
148 if ( !$wgDisableLangConversion ) {
149 $data['langconversion'] = '';
150 }
151
152 if ( !$wgDisableTitleConversion ) {
153 $data['titleconversion'] = '';
154 }
155
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'] = '';
164 }
165
166 $linktrail = $wgContLang->linkTrail();
167 if ( $linktrail ) {
168 $data['linktrail'] = $linktrail;
169 } else {
170 $data['linktrail'] = '';
171 }
172
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;
180 }
181 }
182
183 // 'case-insensitive' option is reserved for future
184 $data['case'] = $GLOBALS['wgCapitalLinks'] ? 'first-letter' : 'case-sensitive';
185
186 if ( isset( $GLOBALS['wgRightsCode'] ) ) {
187 $data['rightscode'] = $GLOBALS['wgRightsCode'];
188 }
189 $data['rights'] = $GLOBALS['wgRightsText'];
190 $data['lang'] = $GLOBALS['wgLanguageCode'];
191
192 $fallbacks = array();
193 foreach ( $wgContLang->getFallbackLanguages() as $code ) {
194 $fallbacks[] = array( 'code' => $code );
195 }
196 $data['fallback'] = $fallbacks;
197 $this->getResult()->setIndexedTagName( $data['fallback'], 'lang' );
198
199 if ( $wgContLang->hasVariants() ) {
200 $variants = array();
201 foreach ( $wgContLang->getVariants() as $code ) {
202 $variants[] = array(
203 'code' => $code,
204 'name' => $wgContLang->getVariantname( $code ),
205 );
206 }
207 $data['variants'] = $variants;
208 $this->getResult()->setIndexedTagName( $data['variants'], 'lang' );
209 }
210
211 if ( $wgContLang->isRTL() ) {
212 $data['rtl'] = '';
213 }
214 $data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
215
216 if ( wfReadOnly() ) {
217 $data['readonly'] = '';
218 $data['readonlyreason'] = wfReadOnlyReason();
219 }
220 if ( $GLOBALS['wgEnableWriteAPI'] ) {
221 $data['writeapi'] = '';
222 }
223
224 $tz = $GLOBALS['wgLocaltimezone'];
225 $offset = $GLOBALS['wgLocalTZoffset'];
226 if ( is_null( $tz ) ) {
227 $tz = 'UTC';
228 $offset = 0;
229 } elseif ( is_null( $offset ) ) {
230 $offset = 0;
231 }
232 $data['timezone'] = $tz;
233 $data['timeoffset'] = intval( $offset );
234 $data['articlepath'] = $GLOBALS['wgArticlePath'];
235 $data['scriptpath'] = $GLOBALS['wgScriptPath'];
236 $data['script'] = $GLOBALS['wgScript'];
237 $data['variantarticlepath'] = $GLOBALS['wgVariantArticlePath'];
238 $data['server'] = $GLOBALS['wgServer'];
239 $data['wikiid'] = wfWikiID();
240 $data['time'] = wfTimestamp( TS_ISO_8601, time() );
241
242 if ( $GLOBALS['wgMiserMode'] ) {
243 $data['misermode'] = '';
244 }
245
246 $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
247
248 $data['thumblimits'] = $GLOBALS['wgThumbLimits'];
249 $this->getResult()->setIndexedTagName( $data['thumblimits'], 'limit' );
250 $data['imagelimits'] = array();
251 $this->getResult()->setIndexedTagName( $data['imagelimits'], 'limit' );
252 foreach ( $GLOBALS['wgImageLimits'] as $k => $limit ) {
253 $data['imagelimits'][$k] = array( 'width' => $limit[0], 'height' => $limit[1] );
254 }
255
256 if ( !empty( $GLOBALS['wgFavicon'] ) ) {
257 $data['favicon'] = $GLOBALS['wgFavicon'];
258 }
259
260 wfRunHooks( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
261
262 return $this->getResult()->addValue( 'query', $property, $data );
263 }
264
265 protected function appendNamespaces( $property ) {
266 global $wgContLang;
267 $data = array();
268 foreach ( $wgContLang->getFormattedNamespaces() as $ns => $title ) {
269 $data[$ns] = array(
270 'id' => intval( $ns ),
271 'case' => MWNamespace::isCapitalized( $ns ) ? 'first-letter' : 'case-sensitive',
272 );
273 ApiResult::setContent( $data[$ns], $title );
274 $canonical = MWNamespace::getCanonicalName( $ns );
275
276 if ( MWNamespace::hasSubpages( $ns ) ) {
277 $data[$ns]['subpages'] = '';
278 }
279
280 if ( $canonical ) {
281 $data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
282 }
283
284 if ( MWNamespace::isContent( $ns ) ) {
285 $data[$ns]['content'] = '';
286 }
287
288 if ( MWNamespace::isNonincludable( $ns ) ) {
289 $data[$ns]['nonincludable'] = '';
290 }
291
292 $contentmodel = MWNamespace::getNamespaceContentModel( $ns );
293 if ( $contentmodel ) {
294 $data[$ns]['defaultcontentmodel'] = $contentmodel;
295 }
296 }
297
298 $this->getResult()->setIndexedTagName( $data, 'ns' );
299
300 return $this->getResult()->addValue( 'query', $property, $data );
301 }
302
303 protected function appendNamespaceAliases( $property ) {
304 global $wgNamespaceAliases, $wgContLang;
305 $aliases = array_merge( $wgNamespaceAliases, $wgContLang->getNamespaceAliases() );
306 $namespaces = $wgContLang->getNamespaces();
307 $data = array();
308 foreach ( $aliases as $title => $ns ) {
309 if ( $namespaces[$ns] == $title ) {
310 // Don't list duplicates
311 continue;
312 }
313 $item = array(
314 'id' => intval( $ns )
315 );
316 ApiResult::setContent( $item, strtr( $title, '_', ' ' ) );
317 $data[] = $item;
318 }
319
320 sort( $data );
321
322 $this->getResult()->setIndexedTagName( $data, 'ns' );
323
324 return $this->getResult()->addValue( 'query', $property, $data );
325 }
326
327 protected function appendSpecialPageAliases( $property ) {
328 global $wgContLang;
329 $data = array();
330 $aliases = $wgContLang->getSpecialPageAliases();
331 foreach ( SpecialPageFactory::getList() as $specialpage => $stuff ) {
332 if ( isset( $aliases[$specialpage] ) ) {
333 $arr = array( 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] );
334 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
335 $data[] = $arr;
336 }
337 }
338 $this->getResult()->setIndexedTagName( $data, 'specialpage' );
339
340 return $this->getResult()->addValue( 'query', $property, $data );
341 }
342
343 protected function appendMagicWords( $property ) {
344 global $wgContLang;
345 $data = array();
346 foreach ( $wgContLang->getMagicWords() as $magicword => $aliases ) {
347 $caseSensitive = array_shift( $aliases );
348 $arr = array( 'name' => $magicword, 'aliases' => $aliases );
349 if ( $caseSensitive ) {
350 $arr['case-sensitive'] = '';
351 }
352 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
353 $data[] = $arr;
354 }
355 $this->getResult()->setIndexedTagName( $data, 'magicword' );
356
357 return $this->getResult()->addValue( 'query', $property, $data );
358 }
359
360 protected function appendInterwikiMap( $property, $filter ) {
361 $local = null;
362 if ( $filter === 'local' ) {
363 $local = 1;
364 } elseif ( $filter === '!local' ) {
365 $local = 0;
366 } elseif ( $filter ) {
367 ApiBase::dieDebug( __METHOD__, "Unknown filter=$filter" );
368 }
369
370 $params = $this->extractRequestParams();
371 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
372 $langNames = Language::fetchLanguageNames( $langCode );
373
374 $getPrefixes = Interwiki::getAllPrefixes( $local );
375 $data = array();
376
377 foreach ( $getPrefixes as $row ) {
378 $prefix = $row['iw_prefix'];
379 $val = array();
380 $val['prefix'] = $prefix;
381 if ( $row['iw_local'] == '1' ) {
382 $val['local'] = '';
383 }
384 if ( $row['iw_trans'] == '1' ) {
385 $val['trans'] = '';
386 }
387 if ( isset( $langNames[$prefix] ) ) {
388 $val['language'] = $langNames[$prefix];
389 }
390 $val['url'] = wfExpandUrl( $row['iw_url'], PROTO_CURRENT );
391 if ( isset( $row['iw_wikiid'] ) ) {
392 $val['wikiid'] = $row['iw_wikiid'];
393 }
394 if ( isset( $row['iw_api'] ) ) {
395 $val['api'] = $row['iw_api'];
396 }
397
398 $data[] = $val;
399 }
400
401 $this->getResult()->setIndexedTagName( $data, 'iw' );
402
403 return $this->getResult()->addValue( 'query', $property, $data );
404 }
405
406 protected function appendDbReplLagInfo( $property, $includeAll ) {
407 global $wgShowHostnames;
408 $data = array();
409 $lb = wfGetLB();
410 if ( $includeAll ) {
411 if ( !$wgShowHostnames ) {
412 $this->dieUsage(
413 'Cannot view all servers info unless $wgShowHostnames is true',
414 'includeAllDenied'
415 );
416 }
417
418 $lags = $lb->getLagTimes();
419 foreach ( $lags as $i => $lag ) {
420 $data[] = array(
421 'host' => $lb->getServerName( $i ),
422 'lag' => $lag
423 );
424 }
425 } else {
426 list( , $lag, $index ) = $lb->getMaxLag();
427 $data[] = array(
428 'host' => $wgShowHostnames
429 ? $lb->getServerName( $index )
430 : '',
431 'lag' => intval( $lag )
432 );
433 }
434
435 $result = $this->getResult();
436 $result->setIndexedTagName( $data, 'db' );
437
438 return $this->getResult()->addValue( 'query', $property, $data );
439 }
440
441 protected function appendStatistics( $property ) {
442 global $wgDisableCounters;
443 $data = array();
444 $data['pages'] = intval( SiteStats::pages() );
445 $data['articles'] = intval( SiteStats::articles() );
446 if ( !$wgDisableCounters ) {
447 $data['views'] = intval( SiteStats::views() );
448 }
449 $data['edits'] = intval( SiteStats::edits() );
450 $data['images'] = intval( SiteStats::images() );
451 $data['users'] = intval( SiteStats::users() );
452 $data['activeusers'] = intval( SiteStats::activeUsers() );
453 $data['admins'] = intval( SiteStats::numberingroup( 'sysop' ) );
454 $data['jobs'] = intval( SiteStats::jobs() );
455
456 wfRunHooks( 'APIQuerySiteInfoStatisticsInfo', array( &$data ) );
457
458 return $this->getResult()->addValue( 'query', $property, $data );
459 }
460
461 protected function appendUserGroups( $property, $numberInGroup ) {
462 global $wgGroupPermissions, $wgAddGroups, $wgRemoveGroups;
463 global $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf;
464
465 $data = array();
466 $result = $this->getResult();
467 foreach ( $wgGroupPermissions as $group => $permissions ) {
468 $arr = array(
469 'name' => $group,
470 'rights' => array_keys( $permissions, true ),
471 );
472
473 if ( $numberInGroup ) {
474 global $wgAutopromote;
475
476 if ( $group == 'user' ) {
477 $arr['number'] = SiteStats::users();
478 // '*' and autopromote groups have no size
479 } elseif ( $group !== '*' && !isset( $wgAutopromote[$group] ) ) {
480 $arr['number'] = SiteStats::numberInGroup( $group );
481 }
482 }
483
484 $groupArr = array(
485 'add' => $wgAddGroups,
486 'remove' => $wgRemoveGroups,
487 'add-self' => $wgGroupsAddToSelf,
488 'remove-self' => $wgGroupsRemoveFromSelf
489 );
490
491 foreach ( $groupArr as $type => $rights ) {
492 if ( isset( $rights[$group] ) ) {
493 $arr[$type] = $rights[$group];
494 $result->setIndexedTagName( $arr[$type], 'group' );
495 }
496 }
497
498 $result->setIndexedTagName( $arr['rights'], 'permission' );
499 $data[] = $arr;
500 }
501
502 $result->setIndexedTagName( $data, 'group' );
503
504 return $result->addValue( 'query', $property, $data );
505 }
506
507 protected function appendFileExtensions( $property ) {
508 global $wgFileExtensions;
509
510 $data = array();
511 foreach ( array_unique( $wgFileExtensions ) as $ext ) {
512 $data[] = array( 'ext' => $ext );
513 }
514 $this->getResult()->setIndexedTagName( $data, 'fe' );
515
516 return $this->getResult()->addValue( 'query', $property, $data );
517 }
518
519 protected function appendExtensions( $property ) {
520 global $wgExtensionCredits;
521 $data = array();
522 foreach ( $wgExtensionCredits as $type => $extensions ) {
523 foreach ( $extensions as $ext ) {
524 $ret = array();
525 $ret['type'] = $type;
526 if ( isset( $ext['name'] ) ) {
527 $ret['name'] = $ext['name'];
528 }
529 if ( isset( $ext['description'] ) ) {
530 $ret['description'] = $ext['description'];
531 }
532 if ( isset( $ext['descriptionmsg'] ) ) {
533 // Can be a string or array( key, param1, param2, ... )
534 if ( is_array( $ext['descriptionmsg'] ) ) {
535 $ret['descriptionmsg'] = $ext['descriptionmsg'][0];
536 $ret['descriptionmsgparams'] = array_slice( $ext['descriptionmsg'], 1 );
537 $this->getResult()->setIndexedTagName( $ret['descriptionmsgparams'], 'param' );
538 } else {
539 $ret['descriptionmsg'] = $ext['descriptionmsg'];
540 }
541 }
542 if ( isset( $ext['author'] ) ) {
543 $ret['author'] = is_array( $ext['author'] ) ?
544 implode( ', ', $ext['author'] ) : $ext['author'];
545 }
546 if ( isset( $ext['url'] ) ) {
547 $ret['url'] = $ext['url'];
548 }
549 if ( isset( $ext['version'] ) ) {
550 $ret['version'] = $ext['version'];
551 } elseif ( isset( $ext['svn-revision'] ) &&
552 preg_match( '/\$(?:Rev|LastChangedRevision|Revision): *(\d+)/',
553 $ext['svn-revision'], $m )
554 ) {
555 $ret['version'] = 'r' . $m[1];
556 }
557 if ( isset( $ext['path'] ) ) {
558 $extensionPath = dirname( $ext['path'] );
559 $gitInfo = new GitInfo( $extensionPath );
560 $vcsVersion = $gitInfo->getHeadSHA1();
561 if ( $vcsVersion !== false ) {
562 $ret['vcs-system'] = 'git';
563 $ret['vcs-version'] = $vcsVersion;
564 $ret['vcs-url'] = $gitInfo->getHeadViewUrl();
565 $ret['vcs-date'] = wfTimestamp( TS_ISO_8601, $gitInfo->getHeadCommitDate() );
566 } else {
567 $svnInfo = SpecialVersion::getSvnInfo( $extensionPath );
568 if ( $svnInfo !== false ) {
569 $ret['vcs-system'] = 'svn';
570 $ret['vcs-version'] = $svnInfo['checkout-rev'];
571 $ret['vcs-url'] = isset( $svnInfo['viewvc-url'] ) ? $svnInfo['viewvc-url'] : '';
572 }
573 }
574 if ( SpecialVersion::getExtLicenseFileName( $extensionPath ) ) {
575 $ret['license-name'] = isset( $ext['license-name'] ) ? $ext['license-name'] : '';
576 $ret['license'] = SpecialPage::getTitleFor( 'Version', "License/{$ext['name']}" )->getLinkURL();
577 }
578 if ( SpecialVersion::getExtAuthorsFileName( $extensionPath ) ) {
579 $ret['credits'] = SpecialPage::getTitleFor( 'Version', "Credits/{$ext['name']}" )->getLinkURL();
580 }
581 }
582 $data[] = $ret;
583 }
584 }
585
586 $this->getResult()->setIndexedTagName( $data, 'ext' );
587
588 return $this->getResult()->addValue( 'query', $property, $data );
589 }
590
591 protected function appendRightsInfo( $property ) {
592 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
593 $title = Title::newFromText( $wgRightsPage );
594 $url = $title ? wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ) : $wgRightsUrl;
595 $text = $wgRightsText;
596 if ( !$text && $title ) {
597 $text = $title->getPrefixedText();
598 }
599
600 $data = array(
601 'url' => $url ? $url : '',
602 'text' => $text ? $text : ''
603 );
604
605 return $this->getResult()->addValue( 'query', $property, $data );
606 }
607
608 public function appendLanguages( $property ) {
609 $params = $this->extractRequestParams();
610 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
611 $langNames = Language::fetchLanguageNames( $langCode );
612
613 $data = array();
614
615 foreach ( $langNames as $code => $name ) {
616 $lang = array( 'code' => $code );
617 ApiResult::setContent( $lang, $name );
618 $data[] = $lang;
619 }
620 $this->getResult()->setIndexedTagName( $data, 'lang' );
621
622 return $this->getResult()->addValue( 'query', $property, $data );
623 }
624
625 public function appendSkins( $property ) {
626 $data = array();
627 $usable = Skin::getUsableSkins();
628 $default = Skin::normalizeKey( 'default' );
629 foreach ( Skin::getSkinNames() as $name => $displayName ) {
630 $skin = array( 'code' => $name );
631 ApiResult::setContent( $skin, $displayName );
632 if ( !isset( $usable[$name] ) ) {
633 $skin['unusable'] = '';
634 }
635 if ( $name === $default ) {
636 $skin['default'] = '';
637 }
638 $data[] = $skin;
639 }
640 $this->getResult()->setIndexedTagName( $data, 'skin' );
641
642 return $this->getResult()->addValue( 'query', $property, $data );
643 }
644
645 public function appendExtensionTags( $property ) {
646 global $wgParser;
647 $wgParser->firstCallInit();
648 $tags = array_map( array( $this, 'formatParserTags' ), $wgParser->getTags() );
649 $this->getResult()->setIndexedTagName( $tags, 't' );
650
651 return $this->getResult()->addValue( 'query', $property, $tags );
652 }
653
654 public function appendFunctionHooks( $property ) {
655 global $wgParser;
656 $wgParser->firstCallInit();
657 $hooks = $wgParser->getFunctionHooks();
658 $this->getResult()->setIndexedTagName( $hooks, 'h' );
659
660 return $this->getResult()->addValue( 'query', $property, $hooks );
661 }
662
663 public function appendVariables( $property ) {
664 $variables = MagicWord::getVariableIDs();
665 $this->getResult()->setIndexedTagName( $variables, 'v' );
666
667 return $this->getResult()->addValue( 'query', $property, $variables );
668 }
669
670 public function appendProtocols( $property ) {
671 global $wgUrlProtocols;
672 // Make a copy of the global so we don't try to set the _element key of it - bug 45130
673 $protocols = array_values( $wgUrlProtocols );
674 $this->getResult()->setIndexedTagName( $protocols, 'p' );
675
676 return $this->getResult()->addValue( 'query', $property, $protocols );
677 }
678
679 public function appendDefaultOptions( $property ) {
680 return $this->getResult()->addValue( 'query', $property, User::getDefaultOptions() );
681 }
682
683 private function formatParserTags( $item ) {
684 return "<{$item}>";
685 }
686
687 public function appendSubscribedHooks( $property ) {
688 global $wgHooks;
689 $myWgHooks = $wgHooks;
690 ksort( $myWgHooks );
691
692 $data = array();
693 foreach ( $myWgHooks as $hook => $hooks ) {
694 $arr = array(
695 'name' => $hook,
696 'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $hooks ),
697 );
698
699 $this->getResult()->setIndexedTagName( $arr['subscribers'], 's' );
700 $data[] = $arr;
701 }
702
703 $this->getResult()->setIndexedTagName( $data, 'hook' );
704
705 return $this->getResult()->addValue( 'query', $property, $data );
706 }
707
708 public function getCacheMode( $params ) {
709 return 'public';
710 }
711
712 public function getAllowedParams() {
713 return array(
714 'prop' => array(
715 ApiBase::PARAM_DFLT => 'general',
716 ApiBase::PARAM_ISMULTI => true,
717 ApiBase::PARAM_TYPE => array(
718 'general',
719 'namespaces',
720 'namespacealiases',
721 'specialpagealiases',
722 'magicwords',
723 'interwikimap',
724 'dbrepllag',
725 'statistics',
726 'usergroups',
727 'extensions',
728 'fileextensions',
729 'rightsinfo',
730 'languages',
731 'skins',
732 'extensiontags',
733 'functionhooks',
734 'showhooks',
735 'variables',
736 'protocols',
737 'defaultoptions',
738 )
739 ),
740 'filteriw' => array(
741 ApiBase::PARAM_TYPE => array(
742 'local',
743 '!local',
744 )
745 ),
746 'showalldb' => false,
747 'numberingroup' => false,
748 'inlanguagecode' => null,
749 );
750 }
751
752 public function getParamDescription() {
753 $p = $this->getModulePrefix();
754
755 return array(
756 'prop' => array(
757 'Which sysinfo properties to get:',
758 ' general - Overall system information',
759 ' namespaces - List of registered namespaces and their canonical names',
760 ' namespacealiases - List of registered namespace aliases',
761 ' specialpagealiases - List of special page aliases',
762 ' magicwords - List of magic words and their aliases',
763 ' statistics - Returns site statistics',
764 ' interwikimap - Returns interwiki map ' .
765 "(optionally filtered, (optionally localised by using {$p}inlanguagecode))",
766 ' dbrepllag - Returns database server with the highest replication lag',
767 ' usergroups - Returns user groups and the associated permissions',
768 ' extensions - Returns extensions installed on the wiki',
769 ' fileextensions - Returns list of file extensions allowed to be uploaded',
770 ' rightsinfo - Returns wiki rights (license) information if available',
771 ' languages - Returns a list of languages MediaWiki supports' .
772 "(optionally localised by using {$p}inlanguagecode)",
773 ' skins - Returns a list of all enabled skins',
774 ' extensiontags - Returns a list of parser extension tags',
775 ' functionhooks - Returns a list of parser function hooks',
776 ' showhooks - Returns a list of all subscribed hooks (contents of $wgHooks)',
777 ' variables - Returns a list of variable IDs',
778 ' protocols - Returns a list of protocols that are allowed in external links.',
779 ' defaultoptions - Returns the default values for user preferences.',
780 ),
781 'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
782 'showalldb' => 'List all database servers, not just the one lagging the most',
783 'numberingroup' => 'Lists the number of users in user groups',
784 'inlanguagecode' => 'Language code for localised language names ' .
785 '(best effort, use CLDR extension)',
786 );
787 }
788
789 public function getDescription() {
790 return 'Return general information about the site';
791 }
792
793 public function getPossibleErrors() {
794 return array_merge( parent::getPossibleErrors(), array( array(
795 'code' => 'includeAllDenied',
796 'info' => 'Cannot view all servers info unless $wgShowHostnames is true'
797 ), ) );
798 }
799
800 public function getExamples() {
801 return array(
802 'api.php?action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics',
803 'api.php?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local',
804 'api.php?action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb=',
805 );
806 }
807
808 public function getHelpUrls() {
809 return 'https://www.mediawiki.org/wiki/API:Meta#siteinfo_.2F_si';
810 }
811 }