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