Docs: compatability -> compatibility
[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( ApiQuery $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 '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" );
110 }
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;
117 }
118 $done[] = $p;
119 }
120 }
121
122 protected function appendGeneralInfo( $property ) {
123 global $wgContLang;
124
125 $config = $this->getConfig();
126
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' );
132
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 );
136
137 $data['generator'] = "MediaWiki {$config->get( 'Version' )}";
138
139 $data['phpversion'] = PHP_VERSION;
140 $data['phpsapi'] = PHP_SAPI;
141 $data['dbtype'] = $config->get( 'DBtype' );
142 $data['dbversion'] = $this->getDB()->getServerVersion();
143
144 $allowFrom = array( '' );
145 $allowException = true;
146 if ( !$config->get( 'AllowExternalImages' ) ) {
147 if ( $config->get( 'EnableImageWhitelist' ) ) {
148 $data['imagewhitelistenabled'] = '';
149 }
150 $allowFrom = $config->get( 'AllowExternalImagesFrom' );
151 $allowException = !empty( $allowFrom );
152 }
153 if ( $allowException ) {
154 $data['externalimages'] = (array)$allowFrom;
155 $this->getResult()->setIndexedTagName( $data['externalimages'], 'prefix' );
156 }
157
158 if ( !$config->get( 'DisableLangConversion' ) ) {
159 $data['langconversion'] = '';
160 }
161
162 if ( !$config->get( 'DisableTitleConversion' ) ) {
163 $data['titleconversion'] = '';
164 }
165
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'] = '';
174 }
175
176 $linktrail = $wgContLang->linkTrail();
177 if ( $linktrail ) {
178 $data['linktrail'] = $linktrail;
179 } else {
180 $data['linktrail'] = '';
181 }
182
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;
193 }
194 }
195
196 // 'case-insensitive' option is reserved for future
197 $data['case'] = $config->get( 'CapitalLinks' ) ? 'first-letter' : 'case-sensitive';
198 $data['lang'] = $config->get( 'LanguageCode' );
199
200 $fallbacks = array();
201 foreach ( $wgContLang->getFallbackLanguages() as $code ) {
202 $fallbacks[] = array( 'code' => $code );
203 }
204 $data['fallback'] = $fallbacks;
205 $this->getResult()->setIndexedTagName( $data['fallback'], 'lang' );
206
207 if ( $wgContLang->hasVariants() ) {
208 $variants = array();
209 foreach ( $wgContLang->getVariants() as $code ) {
210 $variants[] = array(
211 'code' => $code,
212 'name' => $wgContLang->getVariantname( $code ),
213 );
214 }
215 $data['variants'] = $variants;
216 $this->getResult()->setIndexedTagName( $data['variants'], 'lang' );
217 }
218
219 if ( $wgContLang->isRTL() ) {
220 $data['rtl'] = '';
221 }
222 $data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
223
224 if ( wfReadOnly() ) {
225 $data['readonly'] = '';
226 $data['readonlyreason'] = wfReadOnlyReason();
227 }
228 if ( $config->get( 'EnableWriteAPI' ) ) {
229 $data['writeapi'] = '';
230 }
231
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;
239 }
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() );
250
251 if ( $config->get( 'MiserMode' ) ) {
252 $data['misermode'] = '';
253 }
254
255 $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
256
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] );
263 }
264
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 );
270 }
271
272 wfRunHooks( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
273
274 return $this->getResult()->addValue( 'query', $property, $data );
275 }
276
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',
284 );
285 ApiResult::setContent( $data[$ns], $title );
286 $canonical = MWNamespace::getCanonicalName( $ns );
287
288 if ( MWNamespace::hasSubpages( $ns ) ) {
289 $data[$ns]['subpages'] = '';
290 }
291
292 if ( $canonical ) {
293 $data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
294 }
295
296 if ( MWNamespace::isContent( $ns ) ) {
297 $data[$ns]['content'] = '';
298 }
299
300 if ( MWNamespace::isNonincludable( $ns ) ) {
301 $data[$ns]['nonincludable'] = '';
302 }
303
304 $contentmodel = MWNamespace::getNamespaceContentModel( $ns );
305 if ( $contentmodel ) {
306 $data[$ns]['defaultcontentmodel'] = $contentmodel;
307 }
308 }
309
310 $this->getResult()->setIndexedTagName( $data, 'ns' );
311
312 return $this->getResult()->addValue( 'query', $property, $data );
313 }
314
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;
325 }
326 $item = array(
327 'id' => intval( $ns )
328 );
329 ApiResult::setContent( $item, strtr( $title, '_', ' ' ) );
330 $data[] = $item;
331 }
332
333 sort( $data );
334
335 $this->getResult()->setIndexedTagName( $data, 'ns' );
336
337 return $this->getResult()->addValue( 'query', $property, $data );
338 }
339
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;
349 }
350 }
351 $this->getResult()->setIndexedTagName( $data, 'specialpage' );
352
353 return $this->getResult()->addValue( 'query', $property, $data );
354 }
355
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'] = '';
364 }
365 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
366 $data[] = $arr;
367 }
368 $this->getResult()->setIndexedTagName( $data, 'magicword' );
369
370 return $this->getResult()->addValue( 'query', $property, $data );
371 }
372
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" );
381 }
382
383 $params = $this->extractRequestParams();
384 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
385 $langNames = Language::fetchLanguageNames( $langCode );
386
387 $getPrefixes = Interwiki::getAllPrefixes( $local );
388 $extraLangPrefixes = $this->getConfig()->get( 'ExtraInterlanguageLinkPrefixes' );
389 $localInterwikis = $this->getConfig()->get( 'LocalInterwikis' );
390 $data = array();
391
392 foreach ( $getPrefixes as $row ) {
393 $prefix = $row['iw_prefix'];
394 $val = array();
395 $val['prefix'] = $prefix;
396 if ( $row['iw_local'] == '1' ) {
397 $val['local'] = '';
398 }
399 if ( $row['iw_trans'] == '1' ) {
400 $val['trans'] = '';
401 }
402
403 if ( isset( $langNames[$prefix] ) ) {
404 $val['language'] = $langNames[$prefix];
405 }
406 if ( in_array( $prefix, $localInterwikis ) ) {
407 $val['localinterwiki'] = '';
408 }
409 if ( in_array( $prefix, $extraLangPrefixes ) ) {
410 $val['extralanglink'] = '';
411
412 $linktext = wfMessage( "interlanguage-link-$prefix" );
413 if ( !$linktext->isDisabled() ) {
414 $val['linktext'] = $linktext->text();
415 }
416
417 $sitename = wfMessage( "interlanguage-link-sitename-$prefix" );
418 if ( !$sitename->isDisabled() ) {
419 $val['sitename'] = $sitename->text();
420 }
421 }
422
423 $val['url'] = wfExpandUrl( $row['iw_url'], PROTO_CURRENT );
424 if ( substr( $row['iw_url'], 0, 2 ) == '//' ) {
425 $val['protorel'] = '';
426 }
427 if ( isset( $row['iw_wikiid'] ) ) {
428 $val['wikiid'] = $row['iw_wikiid'];
429 }
430 if ( isset( $row['iw_api'] ) ) {
431 $val['api'] = $row['iw_api'];
432 }
433
434 $data[] = $val;
435 }
436
437 $this->getResult()->setIndexedTagName( $data, 'iw' );
438
439 return $this->getResult()->addValue( 'query', $property, $data );
440 }
441
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'
451 );
452 }
453
454 $lags = $lb->getLagTimes();
455 foreach ( $lags as $i => $lag ) {
456 $data[] = array(
457 'host' => $lb->getServerName( $i ),
458 'lag' => $lag
459 );
460 }
461 } else {
462 list( , $lag, $index ) = $lb->getMaxLag();
463 $data[] = array(
464 'host' => $showHostnames
465 ? $lb->getServerName( $index )
466 : '',
467 'lag' => intval( $lag )
468 );
469 }
470
471 $result = $this->getResult();
472 $result->setIndexedTagName( $data, 'db' );
473
474 return $this->getResult()->addValue( 'query', $property, $data );
475 }
476
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() );
483 }
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() );
490
491 wfRunHooks( 'APIQuerySiteInfoStatisticsInfo', array( &$data ) );
492
493 return $this->getResult()->addValue( 'query', $property, $data );
494 }
495
496 protected function appendUserGroups( $property, $numberInGroup ) {
497 $config = $this->getConfig();
498
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 ),
505 );
506
507 if ( $numberInGroup ) {
508 $autopromote = $config->get( 'Autopromote' );
509
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 );
515 }
516 }
517
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' )
523 );
524
525 foreach ( $groupArr as $type => $rights ) {
526 if ( isset( $rights[$group] ) ) {
527 $arr[$type] = $rights[$group];
528 $result->setIndexedTagName( $arr[$type], 'group' );
529 }
530 }
531
532 $result->setIndexedTagName( $arr['rights'], 'permission' );
533 $data[] = $arr;
534 }
535
536 $result->setIndexedTagName( $data, 'group' );
537
538 return $result->addValue( 'query', $property, $data );
539 }
540
541 protected function appendFileExtensions( $property ) {
542 $data = array();
543 foreach ( array_unique( $this->getConfig()->get( 'FileExtensions' ) ) as $ext ) {
544 $data[] = array( 'ext' => $ext );
545 }
546 $this->getResult()->setIndexedTagName( $data, 'fe' );
547
548 return $this->getResult()->addValue( 'query', $property, $data );
549 }
550
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'];
559 }
560 if ( isset( $ext['namemsg'] ) ) {
561 $ret['namemsg'] = $ext['namemsg'];
562 }
563 if ( isset( $ext['description'] ) ) {
564 $ret['description'] = $ext['description'];
565 }
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'];
574 }
575 }
576 if ( isset( $ext['author'] ) ) {
577 $ret['author'] = is_array( $ext['author'] ) ?
578 implode( ', ', $ext['author'] ) : $ext['author'];
579 }
580 if ( isset( $ext['url'] ) ) {
581 $ret['url'] = $ext['url'];
582 }
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 )
588 ) {
589 $ret['version'] = 'r' . $m[1];
590 }
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 );
602 }
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'] : '';
609 }
610 }
611
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();
618 }
619
620 if ( SpecialVersion::getExtAuthorsFileName( $extensionPath ) ) {
621 $ret['credits'] = SpecialPage::getTitleFor(
622 'Version',
623 "Credits/{$ext['name']}"
624 )->getLinkURL();
625 }
626 }
627 $data[] = $ret;
628 }
629 }
630
631 $this->getResult()->setIndexedTagName( $data, 'ext' );
632
633 return $this->getResult()->addValue( 'query', $property, $data );
634 }
635
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();
643 }
644
645 $data = array(
646 'url' => $url ? $url : '',
647 'text' => $text ? $text : ''
648 );
649
650 return $this->getResult()->addValue( 'query', $property, $data );
651 }
652
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' ),
660 );
661
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' );
666
667 return $this->getResult()->addValue( 'query', $property, $data );
668 }
669
670 public function appendLanguages( $property ) {
671 $params = $this->extractRequestParams();
672 $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
673 $langNames = Language::fetchLanguageNames( $langCode );
674
675 $data = array();
676
677 foreach ( $langNames as $code => $name ) {
678 $lang = array( 'code' => $code );
679 ApiResult::setContent( $lang, $name );
680 $data[] = $lang;
681 }
682 $this->getResult()->setIndexedTagName( $data, 'lang' );
683
684 return $this->getResult()->addValue( 'query', $property, $data );
685 }
686
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'] = '';
696 }
697 if ( $name === $default ) {
698 $skin['default'] = '';
699 }
700 $data[] = $skin;
701 }
702 $this->getResult()->setIndexedTagName( $data, 'skin' );
703
704 return $this->getResult()->addValue( 'query', $property, $data );
705 }
706
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' );
712
713 return $this->getResult()->addValue( 'query', $property, $tags );
714 }
715
716 public function appendFunctionHooks( $property ) {
717 global $wgParser;
718 $wgParser->firstCallInit();
719 $hooks = $wgParser->getFunctionHooks();
720 $this->getResult()->setIndexedTagName( $hooks, 'h' );
721
722 return $this->getResult()->addValue( 'query', $property, $hooks );
723 }
724
725 public function appendVariables( $property ) {
726 $variables = MagicWord::getVariableIDs();
727 $this->getResult()->setIndexedTagName( $variables, 'v' );
728
729 return $this->getResult()->addValue( 'query', $property, $variables );
730 }
731
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' );
736
737 return $this->getResult()->addValue( 'query', $property, $protocols );
738 }
739
740 public function appendDefaultOptions( $property ) {
741 return $this->getResult()->addValue( 'query', $property, User::getDefaultOptions() );
742 }
743
744 private function formatParserTags( $item ) {
745 return "<{$item}>";
746 }
747
748 public function appendSubscribedHooks( $property ) {
749 $hooks = $this->getConfig()->get( 'Hooks' );
750 $myWgHooks = $hooks;
751 ksort( $myWgHooks );
752
753 $data = array();
754 foreach ( $myWgHooks as $name => $subscribers ) {
755 $arr = array(
756 'name' => $name,
757 'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $subscribers ),
758 );
759
760 $this->getResult()->setIndexedTagName( $arr['subscribers'], 's' );
761 $data[] = $arr;
762 }
763
764 $this->getResult()->setIndexedTagName( $data, 'hook' );
765
766 return $this->getResult()->addValue( 'query', $property, $data );
767 }
768
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'] )
775 ) {
776 return 'anon-public-user-private';
777 }
778
779 return 'public';
780 }
781
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',
809 )
810 ),
811 'filteriw' => array(
812 ApiBase::PARAM_TYPE => array(
813 'local',
814 '!local',
815 )
816 ),
817 'showalldb' => false,
818 'numberingroup' => false,
819 'inlanguagecode' => null,
820 );
821 }
822
823 public function getParamDescription() {
824 $p = $this->getModulePrefix();
825
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.',
852 ),
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)',
858 );
859 }
860
861 public function getDescription() {
862 return 'Return general information about the site.';
863 }
864
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=',
870 );
871 }
872
873 public function getHelpUrls() {
874 return 'https://www.mediawiki.org/wiki/API:Meta#siteinfo_.2F_si';
875 }
876 }