Merge "Cleanups to DB transaction handling"
[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 default:
103 ApiBase::dieDebug( __METHOD__, "Unknown prop=$p" );
104 }
105 if ( !$fit ) {
106 // Abuse siprop as a query-continue parameter
107 // and set it to all unprocessed props
108 $this->setContinueEnumParameter( 'prop', implode( '|',
109 array_diff( $params['prop'], $done ) ) );
110 break;
111 }
112 $done[] = $p;
113 }
114 }
115
116 protected function appendGeneralInfo( $property ) {
117 global $wgContLang,
118 $wgDisableLangConversion,
119 $wgDisableTitleConversion;
120
121 $data = array();
122 $mainPage = Title::newMainPage();
123 $data['mainpage'] = $mainPage->getPrefixedText();
124 $data['base'] = wfExpandUrl( $mainPage->getFullURL(), PROTO_CURRENT );
125 $data['sitename'] = $GLOBALS['wgSitename'];
126 $data['logo'] = $GLOBALS['wgLogo'];
127 $data['generator'] = "MediaWiki {$GLOBALS['wgVersion']}";
128 $data['phpversion'] = phpversion();
129 $data['phpsapi'] = PHP_SAPI;
130 $data['dbtype'] = $GLOBALS['wgDBtype'];
131 $data['dbversion'] = $this->getDB()->getServerVersion();
132
133 $allowFrom = array( '' );
134 $allowException = true;
135 if ( !$GLOBALS['wgAllowExternalImages'] ) {
136 if ( $GLOBALS['wgEnableImageWhitelist'] ) {
137 $data['imagewhitelistenabled'] = '';
138 }
139 $allowFrom = $GLOBALS['wgAllowExternalImagesFrom'];
140 $allowException = !empty( $allowFrom );
141 }
142 if ( $allowException ) {
143 $data['externalimages'] = (array)$allowFrom;
144 $this->getResult()->setIndexedTagName( $data['externalimages'], 'prefix' );
145 }
146
147 if ( !$wgDisableLangConversion ) {
148 $data['langconversion'] = '';
149 }
150
151 if ( !$wgDisableTitleConversion ) {
152 $data['titleconversion'] = '';
153 }
154
155 if ( $wgContLang->linkPrefixExtension() ) {
156 $linkPrefixCharset = $wgContLang->linkPrefixCharset();
157 $data['linkprefixcharset'] = $linkPrefixCharset;
158 // For backwards compatability
159 $data['linkprefix'] = "/^((?>.*[^$linkPrefixCharset]|))(.+)$/sDu";
160 } else {
161 $data['linkprefixcharset'] = '';
162 $data['linkprefix'] = '';
163 }
164
165 $linktrail = $wgContLang->linkTrail();
166 if ( $linktrail ) {
167 $data['linktrail'] = $linktrail;
168 } else {
169 $data['linktrail'] = '';
170 }
171
172 $git = SpecialVersion::getGitHeadSha1( $GLOBALS['IP'] );
173 if ( $git ) {
174 $data['git-hash'] = $git;
175 } else {
176 $svn = SpecialVersion::getSvnRevision( $GLOBALS['IP'] );
177 if ( $svn ) {
178 $data['rev'] = $svn;
179 }
180 }
181
182 // 'case-insensitive' option is reserved for future
183 $data['case'] = $GLOBALS['wgCapitalLinks'] ? 'first-letter' : 'case-sensitive';
184
185 if ( isset( $GLOBALS['wgRightsCode'] ) ) {
186 $data['rightscode'] = $GLOBALS['wgRightsCode'];
187 }
188 $data['rights'] = $GLOBALS['wgRightsText'];
189 $data['lang'] = $GLOBALS['wgLanguageCode'];
190
191 $fallbacks = array();
192 foreach ( $wgContLang->getFallbackLanguages() as $code ) {
193 $fallbacks[] = array( 'code' => $code );
194 }
195 $data['fallback'] = $fallbacks;
196 $this->getResult()->setIndexedTagName( $data['fallback'], 'lang' );
197
198 if ( $wgContLang->hasVariants() ) {
199 $variants = array();
200 foreach ( $wgContLang->getVariants() as $code ) {
201 $variants[] = array( 'code' => $code );
202 }
203 $data['variants'] = $variants;
204 $this->getResult()->setIndexedTagName( $data['variants'], 'lang' );
205 }
206
207 if ( $wgContLang->isRTL() ) {
208 $data['rtl'] = '';
209 }
210 $data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
211
212 if ( wfReadOnly() ) {
213 $data['readonly'] = '';
214 $data['readonlyreason'] = wfReadOnlyReason();
215 }
216 if ( $GLOBALS['wgEnableWriteAPI'] ) {
217 $data['writeapi'] = '';
218 }
219
220 $tz = $GLOBALS['wgLocaltimezone'];
221 $offset = $GLOBALS['wgLocalTZoffset'];
222 if ( is_null( $tz ) ) {
223 $tz = 'UTC';
224 $offset = 0;
225 } elseif ( is_null( $offset ) ) {
226 $offset = 0;
227 }
228 $data['timezone'] = $tz;
229 $data['timeoffset'] = intval( $offset );
230 $data['articlepath'] = $GLOBALS['wgArticlePath'];
231 $data['scriptpath'] = $GLOBALS['wgScriptPath'];
232 $data['script'] = $GLOBALS['wgScript'];
233 $data['variantarticlepath'] = $GLOBALS['wgVariantArticlePath'];
234 $data['server'] = $GLOBALS['wgServer'];
235 $data['wikiid'] = wfWikiID();
236 $data['time'] = wfTimestamp( TS_ISO_8601, time() );
237
238 if ( $GLOBALS['wgMiserMode'] ) {
239 $data['misermode'] = '';
240 }
241
242 $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
243
244 wfRunHooks( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
245
246 return $this->getResult()->addValue( 'query', $property, $data );
247 }
248
249 protected function appendNamespaces( $property ) {
250 global $wgContLang;
251 $data = array();
252 foreach ( $wgContLang->getFormattedNamespaces() as $ns => $title ) {
253 $data[$ns] = array(
254 'id' => intval( $ns ),
255 'case' => MWNamespace::isCapitalized( $ns ) ? 'first-letter' : 'case-sensitive',
256 );
257 ApiResult::setContent( $data[$ns], $title );
258 $canonical = MWNamespace::getCanonicalName( $ns );
259
260 if ( MWNamespace::hasSubpages( $ns ) ) {
261 $data[$ns]['subpages'] = '';
262 }
263
264 if ( $canonical ) {
265 $data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
266 }
267
268 if ( MWNamespace::isContent( $ns ) ) {
269 $data[$ns]['content'] = '';
270 }
271
272 if ( MWNamespace::isNonincludable( $ns ) ) {
273 $data[$ns]['nonincludable'] = '';
274 }
275
276 $contentmodel = MWNamespace::getNamespaceContentModel( $ns );
277 if ( $contentmodel ) {
278 $data[$ns]['defaultcontentmodel'] = $contentmodel;
279 }
280 }
281
282 $this->getResult()->setIndexedTagName( $data, 'ns' );
283 return $this->getResult()->addValue( 'query', $property, $data );
284 }
285
286 protected function appendNamespaceAliases( $property ) {
287 global $wgNamespaceAliases, $wgContLang;
288 $aliases = array_merge( $wgNamespaceAliases, $wgContLang->getNamespaceAliases() );
289 $namespaces = $wgContLang->getNamespaces();
290 $data = array();
291 foreach ( $aliases as $title => $ns ) {
292 if ( $namespaces[$ns] == $title ) {
293 // Don't list duplicates
294 continue;
295 }
296 $item = array(
297 'id' => intval( $ns )
298 );
299 ApiResult::setContent( $item, strtr( $title, '_', ' ' ) );
300 $data[] = $item;
301 }
302
303 sort( $data );
304
305 $this->getResult()->setIndexedTagName( $data, 'ns' );
306 return $this->getResult()->addValue( 'query', $property, $data );
307 }
308
309 protected function appendSpecialPageAliases( $property ) {
310 global $wgContLang;
311 $data = array();
312 $aliases = $wgContLang->getSpecialPageAliases();
313 foreach ( SpecialPageFactory::getList() as $specialpage => $stuff ) {
314 if ( isset( $aliases[$specialpage] ) ) {
315 $arr = array( 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] );
316 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
317 $data[] = $arr;
318 }
319 }
320 $this->getResult()->setIndexedTagName( $data, 'specialpage' );
321 return $this->getResult()->addValue( 'query', $property, $data );
322 }
323
324 protected function appendMagicWords( $property ) {
325 global $wgContLang;
326 $data = array();
327 foreach ( $wgContLang->getMagicWords() as $magicword => $aliases ) {
328 $caseSensitive = array_shift( $aliases );
329 $arr = array( 'name' => $magicword, 'aliases' => $aliases );
330 if ( $caseSensitive ) {
331 $arr['case-sensitive'] = '';
332 }
333 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
334 $data[] = $arr;
335 }
336 $this->getResult()->setIndexedTagName( $data, 'magicword' );
337 return $this->getResult()->addValue( 'query', $property, $data );
338 }
339
340 protected function appendInterwikiMap( $property, $filter ) {
341 $local = null;
342 if ( $filter === 'local' ) {
343 $local = 1;
344 } elseif ( $filter === '!local' ) {
345 $local = 0;
346 } elseif ( $filter ) {
347 ApiBase::dieDebug( __METHOD__, "Unknown filter=$filter" );
348 }
349
350 $params = $this->extractRequestParams();
351 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
352 $langNames = Language::fetchLanguageNames( $langCode );
353
354 $getPrefixes = Interwiki::getAllPrefixes( $local );
355 $data = array();
356
357 foreach ( $getPrefixes as $row ) {
358 $prefix = $row['iw_prefix'];
359 $val = array();
360 $val['prefix'] = $prefix;
361 if ( $row['iw_local'] == '1' ) {
362 $val['local'] = '';
363 }
364 if ( $row['iw_trans'] == '1' ) {
365 $val['trans'] = '';
366 }
367 if ( isset( $langNames[$prefix] ) ) {
368 $val['language'] = $langNames[$prefix];
369 }
370 $val['url'] = wfExpandUrl( $row['iw_url'], PROTO_CURRENT );
371 if ( isset( $row['iw_wikiid'] ) ) {
372 $val['wikiid'] = $row['iw_wikiid'];
373 }
374 if ( isset( $row['iw_api'] ) ) {
375 $val['api'] = $row['iw_api'];
376 }
377
378 $data[] = $val;
379 }
380
381 $this->getResult()->setIndexedTagName( $data, 'iw' );
382 return $this->getResult()->addValue( 'query', $property, $data );
383 }
384
385 protected function appendDbReplLagInfo( $property, $includeAll ) {
386 global $wgShowHostnames;
387 $data = array();
388 $lb = wfGetLB();
389 if ( $includeAll ) {
390 if ( !$wgShowHostnames ) {
391 $this->dieUsage( 'Cannot view all servers info unless $wgShowHostnames is true', 'includeAllDenied' );
392 }
393
394 $lags = $lb->getLagTimes();
395 foreach ( $lags as $i => $lag ) {
396 $data[] = array(
397 'host' => $lb->getServerName( $i ),
398 'lag' => $lag
399 );
400 }
401 } else {
402 list( , $lag, $index ) = $lb->getMaxLag();
403 $data[] = array(
404 'host' => $wgShowHostnames
405 ? $lb->getServerName( $index )
406 : '',
407 'lag' => intval( $lag )
408 );
409 }
410
411 $result = $this->getResult();
412 $result->setIndexedTagName( $data, 'db' );
413 return $this->getResult()->addValue( 'query', $property, $data );
414 }
415
416 protected function appendStatistics( $property ) {
417 global $wgDisableCounters;
418 $data = array();
419 $data['pages'] = intval( SiteStats::pages() );
420 $data['articles'] = intval( SiteStats::articles() );
421 if ( !$wgDisableCounters ) {
422 $data['views'] = intval( SiteStats::views() );
423 }
424 $data['edits'] = intval( SiteStats::edits() );
425 $data['images'] = intval( SiteStats::images() );
426 $data['users'] = intval( SiteStats::users() );
427 $data['activeusers'] = intval( SiteStats::activeUsers() );
428 $data['admins'] = intval( SiteStats::numberingroup( 'sysop' ) );
429 $data['jobs'] = intval( SiteStats::jobs() );
430
431 wfRunHooks( 'APIQuerySiteInfoStatisticsInfo', array( &$data ) );
432
433 return $this->getResult()->addValue( 'query', $property, $data );
434 }
435
436 protected function appendUserGroups( $property, $numberInGroup ) {
437 global $wgGroupPermissions, $wgAddGroups, $wgRemoveGroups;
438 global $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf;
439
440 $data = array();
441 $result = $this->getResult();
442 foreach ( $wgGroupPermissions as $group => $permissions ) {
443 $arr = array(
444 'name' => $group,
445 'rights' => array_keys( $permissions, true ),
446 );
447
448 if ( $numberInGroup ) {
449 global $wgAutopromote;
450
451 if ( $group == 'user' ) {
452 $arr['number'] = SiteStats::users();
453
454 // '*' and autopromote groups have no size
455 } elseif ( $group !== '*' && !isset( $wgAutopromote[$group] ) ) {
456 $arr['number'] = SiteStats::numberInGroup( $group );
457 }
458 }
459
460 $groupArr = array(
461 'add' => $wgAddGroups,
462 'remove' => $wgRemoveGroups,
463 'add-self' => $wgGroupsAddToSelf,
464 'remove-self' => $wgGroupsRemoveFromSelf
465 );
466
467 foreach ( $groupArr as $type => $rights ) {
468 if ( isset( $rights[$group] ) ) {
469 $arr[$type] = $rights[$group];
470 $result->setIndexedTagName( $arr[$type], 'group' );
471 }
472 }
473
474 $result->setIndexedTagName( $arr['rights'], 'permission' );
475 $data[] = $arr;
476 }
477
478 $result->setIndexedTagName( $data, 'group' );
479 return $result->addValue( 'query', $property, $data );
480 }
481
482 protected function appendFileExtensions( $property ) {
483 global $wgFileExtensions;
484
485 $data = array();
486 foreach ( array_unique( $wgFileExtensions ) as $ext ) {
487 $data[] = array( 'ext' => $ext );
488 }
489 $this->getResult()->setIndexedTagName( $data, 'fe' );
490 return $this->getResult()->addValue( 'query', $property, $data );
491 }
492
493 protected function appendExtensions( $property ) {
494 global $wgExtensionCredits;
495 $data = array();
496 foreach ( $wgExtensionCredits as $type => $extensions ) {
497 foreach ( $extensions as $ext ) {
498 $ret = array();
499 $ret['type'] = $type;
500 if ( isset( $ext['name'] ) ) {
501 $ret['name'] = $ext['name'];
502 }
503 if ( isset( $ext['description'] ) ) {
504 $ret['description'] = $ext['description'];
505 }
506 if ( isset( $ext['descriptionmsg'] ) ) {
507 // Can be a string or array( key, param1, param2, ... )
508 if ( is_array( $ext['descriptionmsg'] ) ) {
509 $ret['descriptionmsg'] = $ext['descriptionmsg'][0];
510 $ret['descriptionmsgparams'] = array_slice( $ext['descriptionmsg'], 1 );
511 $this->getResult()->setIndexedTagName( $ret['descriptionmsgparams'], 'param' );
512 } else {
513 $ret['descriptionmsg'] = $ext['descriptionmsg'];
514 }
515 }
516 if ( isset( $ext['author'] ) ) {
517 $ret['author'] = is_array( $ext['author'] ) ?
518 implode( ', ', $ext['author'] ) : $ext['author'];
519 }
520 if ( isset( $ext['url'] ) ) {
521 $ret['url'] = $ext['url'];
522 }
523 if ( isset( $ext['version'] ) ) {
524 $ret['version'] = $ext['version'];
525 } elseif ( isset( $ext['svn-revision'] ) &&
526 preg_match( '/\$(?:Rev|LastChangedRevision|Revision): *(\d+)/',
527 $ext['svn-revision'], $m ) )
528 {
529 $ret['version'] = 'r' . $m[1];
530 }
531 $data[] = $ret;
532 }
533 }
534
535 $this->getResult()->setIndexedTagName( $data, 'ext' );
536 return $this->getResult()->addValue( 'query', $property, $data );
537 }
538
539 protected function appendRightsInfo( $property ) {
540 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
541 $title = Title::newFromText( $wgRightsPage );
542 $url = $title ? wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ) : $wgRightsUrl;
543 $text = $wgRightsText;
544 if ( !$text && $title ) {
545 $text = $title->getPrefixedText();
546 }
547
548 $data = array(
549 'url' => $url ? $url : '',
550 'text' => $text ? $text : ''
551 );
552
553 return $this->getResult()->addValue( 'query', $property, $data );
554 }
555
556 public function appendLanguages( $property ) {
557 $params = $this->extractRequestParams();
558 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
559 $langNames = Language::fetchLanguageNames( $langCode );
560
561 $data = array();
562
563 foreach ( $langNames as $code => $name ) {
564 $lang = array( 'code' => $code );
565 ApiResult::setContent( $lang, $name );
566 $data[] = $lang;
567 }
568 $this->getResult()->setIndexedTagName( $data, 'lang' );
569 return $this->getResult()->addValue( 'query', $property, $data );
570 }
571
572 public function appendSkins( $property ) {
573 $data = array();
574 $usable = Skin::getUsableSkins();
575 $default = Skin::normalizeKey( 'default' );
576 foreach ( Skin::getSkinNames() as $name => $displayName ) {
577 $skin = array( 'code' => $name );
578 ApiResult::setContent( $skin, $displayName );
579 if ( !isset( $usable[$name] ) ) {
580 $skin['unusable'] = '';
581 }
582 if ( $name === $default ) {
583 $skin['default'] = '';
584 }
585 $data[] = $skin;
586 }
587 $this->getResult()->setIndexedTagName( $data, 'skin' );
588 return $this->getResult()->addValue( 'query', $property, $data );
589 }
590
591 public function appendExtensionTags( $property ) {
592 global $wgParser;
593 $wgParser->firstCallInit();
594 $tags = array_map( array( $this, 'formatParserTags' ), $wgParser->getTags() );
595 $this->getResult()->setIndexedTagName( $tags, 't' );
596 return $this->getResult()->addValue( 'query', $property, $tags );
597 }
598
599 public function appendFunctionHooks( $property ) {
600 global $wgParser;
601 $wgParser->firstCallInit();
602 $hooks = $wgParser->getFunctionHooks();
603 $this->getResult()->setIndexedTagName( $hooks, 'h' );
604 return $this->getResult()->addValue( 'query', $property, $hooks );
605 }
606
607 public function appendVariables( $property ) {
608 $variables = MagicWord::getVariableIDs();
609 $this->getResult()->setIndexedTagName( $variables, 'v' );
610 return $this->getResult()->addValue( 'query', $property, $variables );
611 }
612
613 public function appendProtocols( $property ) {
614 global $wgUrlProtocols;
615 // Make a copy of the global so we don't try to set the _element key of it - bug 45130
616 $protocols = array_values( $wgUrlProtocols );
617 $this->getResult()->setIndexedTagName( $protocols, 'p' );
618 return $this->getResult()->addValue( 'query', $property, $protocols );
619 }
620
621 private function formatParserTags( $item ) {
622 return "<{$item}>";
623 }
624
625 public function appendSubscribedHooks( $property ) {
626 global $wgHooks;
627 $myWgHooks = $wgHooks;
628 ksort( $myWgHooks );
629
630 $data = array();
631 foreach ( $myWgHooks as $hook => $hooks ) {
632 $arr = array(
633 'name' => $hook,
634 'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $hooks ),
635 );
636
637 $this->getResult()->setIndexedTagName( $arr['subscribers'], 's' );
638 $data[] = $arr;
639 }
640
641 $this->getResult()->setIndexedTagName( $data, 'hook' );
642 return $this->getResult()->addValue( 'query', $property, $data );
643 }
644
645 public function getCacheMode( $params ) {
646 return 'public';
647 }
648
649 public function getAllowedParams() {
650 return array(
651 'prop' => array(
652 ApiBase::PARAM_DFLT => 'general',
653 ApiBase::PARAM_ISMULTI => true,
654 ApiBase::PARAM_TYPE => array(
655 'general',
656 'namespaces',
657 'namespacealiases',
658 'specialpagealiases',
659 'magicwords',
660 'interwikimap',
661 'dbrepllag',
662 'statistics',
663 'usergroups',
664 'extensions',
665 'fileextensions',
666 'rightsinfo',
667 'languages',
668 'skins',
669 'extensiontags',
670 'functionhooks',
671 'showhooks',
672 'variables',
673 'protocols',
674 )
675 ),
676 'filteriw' => array(
677 ApiBase::PARAM_TYPE => array(
678 'local',
679 '!local',
680 )
681 ),
682 'showalldb' => false,
683 'numberingroup' => false,
684 'inlanguagecode' => null,
685 );
686 }
687
688 public function getParamDescription() {
689 $p = $this->getModulePrefix();
690 return array(
691 'prop' => array(
692 'Which sysinfo properties to get:',
693 ' general - Overall system information',
694 ' namespaces - List of registered namespaces and their canonical names',
695 ' namespacealiases - List of registered namespace aliases',
696 ' specialpagealiases - List of special page aliases',
697 ' magicwords - List of magic words and their aliases',
698 ' statistics - Returns site statistics',
699 " interwikimap - Returns interwiki map " .
700 "(optionally filtered, (optionally localised by using {$p}inlanguagecode))",
701 ' dbrepllag - Returns database server with the highest replication lag',
702 ' usergroups - Returns user groups and the associated permissions',
703 ' extensions - Returns extensions installed on the wiki',
704 ' fileextensions - Returns list of file extensions allowed to be uploaded',
705 ' rightsinfo - Returns wiki rights (license) information if available',
706 " languages - Returns a list of languages MediaWiki supports" .
707 "(optionally localised by using {$p}inlanguagecode)",
708 ' skins - Returns a list of all enabled skins',
709 ' extensiontags - Returns a list of parser extension tags',
710 ' functionhooks - Returns a list of parser function hooks',
711 ' showhooks - Returns a list of all subscribed hooks (contents of $wgHooks)',
712 ' variables - Returns a list of variable IDs',
713 ' protocols - Returns a list of protocols that are allowed in external links.',
714 ),
715 'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
716 'showalldb' => 'List all database servers, not just the one lagging the most',
717 'numberingroup' => 'Lists the number of users in user groups',
718 'inlanguagecode' => 'Language code for localised language names (best effort, use CLDR extension)',
719 );
720 }
721
722 public function getDescription() {
723 return 'Return general information about the site';
724 }
725
726 public function getPossibleErrors() {
727 return array_merge( parent::getPossibleErrors(), array( array(
728 'code' => 'includeAllDenied',
729 'info' => 'Cannot view all servers info unless $wgShowHostnames is true'
730 ), ) );
731 }
732
733 public function getExamples() {
734 return array(
735 'api.php?action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics',
736 'api.php?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local',
737 'api.php?action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb=',
738 );
739 }
740
741 public function getHelpUrls() {
742 return 'https://www.mediawiki.org/wiki/API:Meta#siteinfo_.2F_si';
743 }
744 }