Re-remove experiment code for moduleStorage
[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 wfRunHooks( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
257
258 return $this->getResult()->addValue( 'query', $property, $data );
259 }
260
261 protected function appendNamespaces( $property ) {
262 global $wgContLang;
263 $data = array();
264 foreach ( $wgContLang->getFormattedNamespaces() as $ns => $title ) {
265 $data[$ns] = array(
266 'id' => intval( $ns ),
267 'case' => MWNamespace::isCapitalized( $ns ) ? 'first-letter' : 'case-sensitive',
268 );
269 ApiResult::setContent( $data[$ns], $title );
270 $canonical = MWNamespace::getCanonicalName( $ns );
271
272 if ( MWNamespace::hasSubpages( $ns ) ) {
273 $data[$ns]['subpages'] = '';
274 }
275
276 if ( $canonical ) {
277 $data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
278 }
279
280 if ( MWNamespace::isContent( $ns ) ) {
281 $data[$ns]['content'] = '';
282 }
283
284 if ( MWNamespace::isNonincludable( $ns ) ) {
285 $data[$ns]['nonincludable'] = '';
286 }
287
288 $contentmodel = MWNamespace::getNamespaceContentModel( $ns );
289 if ( $contentmodel ) {
290 $data[$ns]['defaultcontentmodel'] = $contentmodel;
291 }
292 }
293
294 $this->getResult()->setIndexedTagName( $data, 'ns' );
295
296 return $this->getResult()->addValue( 'query', $property, $data );
297 }
298
299 protected function appendNamespaceAliases( $property ) {
300 global $wgNamespaceAliases, $wgContLang;
301 $aliases = array_merge( $wgNamespaceAliases, $wgContLang->getNamespaceAliases() );
302 $namespaces = $wgContLang->getNamespaces();
303 $data = array();
304 foreach ( $aliases as $title => $ns ) {
305 if ( $namespaces[$ns] == $title ) {
306 // Don't list duplicates
307 continue;
308 }
309 $item = array(
310 'id' => intval( $ns )
311 );
312 ApiResult::setContent( $item, strtr( $title, '_', ' ' ) );
313 $data[] = $item;
314 }
315
316 sort( $data );
317
318 $this->getResult()->setIndexedTagName( $data, 'ns' );
319
320 return $this->getResult()->addValue( 'query', $property, $data );
321 }
322
323 protected function appendSpecialPageAliases( $property ) {
324 global $wgContLang;
325 $data = array();
326 $aliases = $wgContLang->getSpecialPageAliases();
327 foreach ( SpecialPageFactory::getList() as $specialpage => $stuff ) {
328 if ( isset( $aliases[$specialpage] ) ) {
329 $arr = array( 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] );
330 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
331 $data[] = $arr;
332 }
333 }
334 $this->getResult()->setIndexedTagName( $data, 'specialpage' );
335
336 return $this->getResult()->addValue( 'query', $property, $data );
337 }
338
339 protected function appendMagicWords( $property ) {
340 global $wgContLang;
341 $data = array();
342 foreach ( $wgContLang->getMagicWords() as $magicword => $aliases ) {
343 $caseSensitive = array_shift( $aliases );
344 $arr = array( 'name' => $magicword, 'aliases' => $aliases );
345 if ( $caseSensitive ) {
346 $arr['case-sensitive'] = '';
347 }
348 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
349 $data[] = $arr;
350 }
351 $this->getResult()->setIndexedTagName( $data, 'magicword' );
352
353 return $this->getResult()->addValue( 'query', $property, $data );
354 }
355
356 protected function appendInterwikiMap( $property, $filter ) {
357 $local = null;
358 if ( $filter === 'local' ) {
359 $local = 1;
360 } elseif ( $filter === '!local' ) {
361 $local = 0;
362 } elseif ( $filter ) {
363 ApiBase::dieDebug( __METHOD__, "Unknown filter=$filter" );
364 }
365
366 $params = $this->extractRequestParams();
367 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
368 $langNames = Language::fetchLanguageNames( $langCode );
369
370 $getPrefixes = Interwiki::getAllPrefixes( $local );
371 $data = array();
372
373 foreach ( $getPrefixes as $row ) {
374 $prefix = $row['iw_prefix'];
375 $val = array();
376 $val['prefix'] = $prefix;
377 if ( $row['iw_local'] == '1' ) {
378 $val['local'] = '';
379 }
380 if ( $row['iw_trans'] == '1' ) {
381 $val['trans'] = '';
382 }
383 if ( isset( $langNames[$prefix] ) ) {
384 $val['language'] = $langNames[$prefix];
385 }
386 $val['url'] = wfExpandUrl( $row['iw_url'], PROTO_CURRENT );
387 if ( isset( $row['iw_wikiid'] ) ) {
388 $val['wikiid'] = $row['iw_wikiid'];
389 }
390 if ( isset( $row['iw_api'] ) ) {
391 $val['api'] = $row['iw_api'];
392 }
393
394 $data[] = $val;
395 }
396
397 $this->getResult()->setIndexedTagName( $data, 'iw' );
398
399 return $this->getResult()->addValue( 'query', $property, $data );
400 }
401
402 protected function appendDbReplLagInfo( $property, $includeAll ) {
403 global $wgShowHostnames;
404 $data = array();
405 $lb = wfGetLB();
406 if ( $includeAll ) {
407 if ( !$wgShowHostnames ) {
408 $this->dieUsage(
409 'Cannot view all servers info unless $wgShowHostnames is true',
410 'includeAllDenied'
411 );
412 }
413
414 $lags = $lb->getLagTimes();
415 foreach ( $lags as $i => $lag ) {
416 $data[] = array(
417 'host' => $lb->getServerName( $i ),
418 'lag' => $lag
419 );
420 }
421 } else {
422 list( , $lag, $index ) = $lb->getMaxLag();
423 $data[] = array(
424 'host' => $wgShowHostnames
425 ? $lb->getServerName( $index )
426 : '',
427 'lag' => intval( $lag )
428 );
429 }
430
431 $result = $this->getResult();
432 $result->setIndexedTagName( $data, 'db' );
433
434 return $this->getResult()->addValue( 'query', $property, $data );
435 }
436
437 protected function appendStatistics( $property ) {
438 global $wgDisableCounters;
439 $data = array();
440 $data['pages'] = intval( SiteStats::pages() );
441 $data['articles'] = intval( SiteStats::articles() );
442 if ( !$wgDisableCounters ) {
443 $data['views'] = intval( SiteStats::views() );
444 }
445 $data['edits'] = intval( SiteStats::edits() );
446 $data['images'] = intval( SiteStats::images() );
447 $data['users'] = intval( SiteStats::users() );
448 $data['activeusers'] = intval( SiteStats::activeUsers() );
449 $data['admins'] = intval( SiteStats::numberingroup( 'sysop' ) );
450 $data['jobs'] = intval( SiteStats::jobs() );
451
452 wfRunHooks( 'APIQuerySiteInfoStatisticsInfo', array( &$data ) );
453
454 return $this->getResult()->addValue( 'query', $property, $data );
455 }
456
457 protected function appendUserGroups( $property, $numberInGroup ) {
458 global $wgGroupPermissions, $wgAddGroups, $wgRemoveGroups;
459 global $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf;
460
461 $data = array();
462 $result = $this->getResult();
463 foreach ( $wgGroupPermissions as $group => $permissions ) {
464 $arr = array(
465 'name' => $group,
466 'rights' => array_keys( $permissions, true ),
467 );
468
469 if ( $numberInGroup ) {
470 global $wgAutopromote;
471
472 if ( $group == 'user' ) {
473 $arr['number'] = SiteStats::users();
474 // '*' and autopromote groups have no size
475 } elseif ( $group !== '*' && !isset( $wgAutopromote[$group] ) ) {
476 $arr['number'] = SiteStats::numberInGroup( $group );
477 }
478 }
479
480 $groupArr = array(
481 'add' => $wgAddGroups,
482 'remove' => $wgRemoveGroups,
483 'add-self' => $wgGroupsAddToSelf,
484 'remove-self' => $wgGroupsRemoveFromSelf
485 );
486
487 foreach ( $groupArr as $type => $rights ) {
488 if ( isset( $rights[$group] ) ) {
489 $arr[$type] = $rights[$group];
490 $result->setIndexedTagName( $arr[$type], 'group' );
491 }
492 }
493
494 $result->setIndexedTagName( $arr['rights'], 'permission' );
495 $data[] = $arr;
496 }
497
498 $result->setIndexedTagName( $data, 'group' );
499
500 return $result->addValue( 'query', $property, $data );
501 }
502
503 protected function appendFileExtensions( $property ) {
504 global $wgFileExtensions;
505
506 $data = array();
507 foreach ( array_unique( $wgFileExtensions ) as $ext ) {
508 $data[] = array( 'ext' => $ext );
509 }
510 $this->getResult()->setIndexedTagName( $data, 'fe' );
511
512 return $this->getResult()->addValue( 'query', $property, $data );
513 }
514
515 protected function appendExtensions( $property ) {
516 global $wgExtensionCredits;
517 $data = array();
518 foreach ( $wgExtensionCredits as $type => $extensions ) {
519 foreach ( $extensions as $ext ) {
520 $ret = array();
521 $ret['type'] = $type;
522 if ( isset( $ext['name'] ) ) {
523 $ret['name'] = $ext['name'];
524 }
525 if ( isset( $ext['description'] ) ) {
526 $ret['description'] = $ext['description'];
527 }
528 if ( isset( $ext['descriptionmsg'] ) ) {
529 // Can be a string or array( key, param1, param2, ... )
530 if ( is_array( $ext['descriptionmsg'] ) ) {
531 $ret['descriptionmsg'] = $ext['descriptionmsg'][0];
532 $ret['descriptionmsgparams'] = array_slice( $ext['descriptionmsg'], 1 );
533 $this->getResult()->setIndexedTagName( $ret['descriptionmsgparams'], 'param' );
534 } else {
535 $ret['descriptionmsg'] = $ext['descriptionmsg'];
536 }
537 }
538 if ( isset( $ext['author'] ) ) {
539 $ret['author'] = is_array( $ext['author'] ) ?
540 implode( ', ', $ext['author'] ) : $ext['author'];
541 }
542 if ( isset( $ext['url'] ) ) {
543 $ret['url'] = $ext['url'];
544 }
545 if ( isset( $ext['version'] ) ) {
546 $ret['version'] = $ext['version'];
547 } elseif ( isset( $ext['svn-revision'] ) &&
548 preg_match( '/\$(?:Rev|LastChangedRevision|Revision): *(\d+)/',
549 $ext['svn-revision'], $m )
550 ) {
551 $ret['version'] = 'r' . $m[1];
552 }
553 if ( isset( $ext['path'] ) ) {
554 $extensionPath = dirname( $ext['path'] );
555 $gitInfo = new GitInfo( $extensionPath );
556 $vcsVersion = $gitInfo->getHeadSHA1();
557 if ( $vcsVersion !== false ) {
558 $ret['vcs-system'] = 'git';
559 $ret['vcs-version'] = $vcsVersion;
560 $ret['vcs-url'] = $gitInfo->getHeadViewUrl();
561 $ret['vcs-date'] = wfTimestamp( TS_ISO_8601, $gitInfo->getHeadCommitDate() );
562 } else {
563 $svnInfo = SpecialVersion::getSvnInfo( $extensionPath );
564 if ( $svnInfo !== false ) {
565 $ret['vcs-system'] = 'svn';
566 $ret['vcs-version'] = $svnInfo['checkout-rev'];
567 $ret['vcs-url'] = isset( $svnInfo['viewvc-url'] ) ? $svnInfo['viewvc-url'] : '';
568 }
569 }
570 if ( SpecialVersion::getExtLicenseFileName( $extensionPath ) ) {
571 $ret['license-name'] = isset( $ext['license-name'] ) ? $ext['license-name'] : '';
572 $ret['license'] = SpecialPage::getTitleFor( 'Version', "License/{$ext['name']}" )->getLinkURL();
573 }
574 if ( SpecialVersion::getExtAuthorsFileName( $extensionPath ) ) {
575 $ret['credits'] = SpecialPage::getTitleFor( 'Version', "Credits/{$ext['name']}" )->getLinkURL();
576 }
577 }
578 $data[] = $ret;
579 }
580 }
581
582 $this->getResult()->setIndexedTagName( $data, 'ext' );
583
584 return $this->getResult()->addValue( 'query', $property, $data );
585 }
586
587 protected function appendRightsInfo( $property ) {
588 global $wgRightsPage, $wgRightsUrl, $wgRightsText;
589 $title = Title::newFromText( $wgRightsPage );
590 $url = $title ? wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ) : $wgRightsUrl;
591 $text = $wgRightsText;
592 if ( !$text && $title ) {
593 $text = $title->getPrefixedText();
594 }
595
596 $data = array(
597 'url' => $url ? $url : '',
598 'text' => $text ? $text : ''
599 );
600
601 return $this->getResult()->addValue( 'query', $property, $data );
602 }
603
604 public function appendLanguages( $property ) {
605 $params = $this->extractRequestParams();
606 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
607 $langNames = Language::fetchLanguageNames( $langCode );
608
609 $data = array();
610
611 foreach ( $langNames as $code => $name ) {
612 $lang = array( 'code' => $code );
613 ApiResult::setContent( $lang, $name );
614 $data[] = $lang;
615 }
616 $this->getResult()->setIndexedTagName( $data, 'lang' );
617
618 return $this->getResult()->addValue( 'query', $property, $data );
619 }
620
621 public function appendSkins( $property ) {
622 $data = array();
623 $usable = Skin::getUsableSkins();
624 $default = Skin::normalizeKey( 'default' );
625 foreach ( Skin::getSkinNames() as $name => $displayName ) {
626 $skin = array( 'code' => $name );
627 ApiResult::setContent( $skin, $displayName );
628 if ( !isset( $usable[$name] ) ) {
629 $skin['unusable'] = '';
630 }
631 if ( $name === $default ) {
632 $skin['default'] = '';
633 }
634 $data[] = $skin;
635 }
636 $this->getResult()->setIndexedTagName( $data, 'skin' );
637
638 return $this->getResult()->addValue( 'query', $property, $data );
639 }
640
641 public function appendExtensionTags( $property ) {
642 global $wgParser;
643 $wgParser->firstCallInit();
644 $tags = array_map( array( $this, 'formatParserTags' ), $wgParser->getTags() );
645 $this->getResult()->setIndexedTagName( $tags, 't' );
646
647 return $this->getResult()->addValue( 'query', $property, $tags );
648 }
649
650 public function appendFunctionHooks( $property ) {
651 global $wgParser;
652 $wgParser->firstCallInit();
653 $hooks = $wgParser->getFunctionHooks();
654 $this->getResult()->setIndexedTagName( $hooks, 'h' );
655
656 return $this->getResult()->addValue( 'query', $property, $hooks );
657 }
658
659 public function appendVariables( $property ) {
660 $variables = MagicWord::getVariableIDs();
661 $this->getResult()->setIndexedTagName( $variables, 'v' );
662
663 return $this->getResult()->addValue( 'query', $property, $variables );
664 }
665
666 public function appendProtocols( $property ) {
667 global $wgUrlProtocols;
668 // Make a copy of the global so we don't try to set the _element key of it - bug 45130
669 $protocols = array_values( $wgUrlProtocols );
670 $this->getResult()->setIndexedTagName( $protocols, 'p' );
671
672 return $this->getResult()->addValue( 'query', $property, $protocols );
673 }
674
675 public function appendDefaultOptions( $property ) {
676 return $this->getResult()->addValue( 'query', $property, User::getDefaultOptions() );
677 }
678
679 private function formatParserTags( $item ) {
680 return "<{$item}>";
681 }
682
683 public function appendSubscribedHooks( $property ) {
684 global $wgHooks;
685 $myWgHooks = $wgHooks;
686 ksort( $myWgHooks );
687
688 $data = array();
689 foreach ( $myWgHooks as $hook => $hooks ) {
690 $arr = array(
691 'name' => $hook,
692 'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $hooks ),
693 );
694
695 $this->getResult()->setIndexedTagName( $arr['subscribers'], 's' );
696 $data[] = $arr;
697 }
698
699 $this->getResult()->setIndexedTagName( $data, 'hook' );
700
701 return $this->getResult()->addValue( 'query', $property, $data );
702 }
703
704 public function getCacheMode( $params ) {
705 return 'public';
706 }
707
708 public function getAllowedParams() {
709 return array(
710 'prop' => array(
711 ApiBase::PARAM_DFLT => 'general',
712 ApiBase::PARAM_ISMULTI => true,
713 ApiBase::PARAM_TYPE => array(
714 'general',
715 'namespaces',
716 'namespacealiases',
717 'specialpagealiases',
718 'magicwords',
719 'interwikimap',
720 'dbrepllag',
721 'statistics',
722 'usergroups',
723 'extensions',
724 'fileextensions',
725 'rightsinfo',
726 'languages',
727 'skins',
728 'extensiontags',
729 'functionhooks',
730 'showhooks',
731 'variables',
732 'protocols',
733 'defaultoptions',
734 )
735 ),
736 'filteriw' => array(
737 ApiBase::PARAM_TYPE => array(
738 'local',
739 '!local',
740 )
741 ),
742 'showalldb' => false,
743 'numberingroup' => false,
744 'inlanguagecode' => null,
745 );
746 }
747
748 public function getParamDescription() {
749 $p = $this->getModulePrefix();
750
751 return array(
752 'prop' => array(
753 'Which sysinfo properties to get:',
754 ' general - Overall system information',
755 ' namespaces - List of registered namespaces and their canonical names',
756 ' namespacealiases - List of registered namespace aliases',
757 ' specialpagealiases - List of special page aliases',
758 ' magicwords - List of magic words and their aliases',
759 ' statistics - Returns site statistics',
760 ' interwikimap - Returns interwiki map ' .
761 "(optionally filtered, (optionally localised by using {$p}inlanguagecode))",
762 ' dbrepllag - Returns database server with the highest replication lag',
763 ' usergroups - Returns user groups and the associated permissions',
764 ' extensions - Returns extensions installed on the wiki',
765 ' fileextensions - Returns list of file extensions allowed to be uploaded',
766 ' rightsinfo - Returns wiki rights (license) information if available',
767 ' languages - Returns a list of languages MediaWiki supports' .
768 "(optionally localised by using {$p}inlanguagecode)",
769 ' skins - Returns a list of all enabled skins',
770 ' extensiontags - Returns a list of parser extension tags',
771 ' functionhooks - Returns a list of parser function hooks',
772 ' showhooks - Returns a list of all subscribed hooks (contents of $wgHooks)',
773 ' variables - Returns a list of variable IDs',
774 ' protocols - Returns a list of protocols that are allowed in external links.',
775 ' defaultoptions - Returns the default values for user preferences.',
776 ),
777 'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
778 'showalldb' => 'List all database servers, not just the one lagging the most',
779 'numberingroup' => 'Lists the number of users in user groups',
780 'inlanguagecode' => 'Language code for localised language names ' .
781 '(best effort, use CLDR extension)',
782 );
783 }
784
785 public function getDescription() {
786 return 'Return general information about the site';
787 }
788
789 public function getPossibleErrors() {
790 return array_merge( parent::getPossibleErrors(), array( array(
791 'code' => 'includeAllDenied',
792 'info' => 'Cannot view all servers info unless $wgShowHostnames is true'
793 ), ) );
794 }
795
796 public function getExamples() {
797 return array(
798 'api.php?action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics',
799 'api.php?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local',
800 'api.php?action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb=',
801 );
802 }
803
804 public function getHelpUrls() {
805 return 'https://www.mediawiki.org/wiki/API:Meta#siteinfo_.2F_si';
806 }
807 }