MediaWiki  REL1_24
ApiQuerySiteinfo.php
Go to the documentation of this file.
00001 <?php
00032 class ApiQuerySiteinfo extends ApiQueryBase {
00033 
00034     public function __construct( ApiQuery $query, $moduleName ) {
00035         parent::__construct( $query, $moduleName, 'si' );
00036     }
00037 
00038     public function execute() {
00039         $params = $this->extractRequestParams();
00040         $done = array();
00041         $fit = false;
00042         foreach ( $params['prop'] as $p ) {
00043             switch ( $p ) {
00044                 case 'general':
00045                     $fit = $this->appendGeneralInfo( $p );
00046                     break;
00047                 case 'namespaces':
00048                     $fit = $this->appendNamespaces( $p );
00049                     break;
00050                 case 'namespacealiases':
00051                     $fit = $this->appendNamespaceAliases( $p );
00052                     break;
00053                 case 'specialpagealiases':
00054                     $fit = $this->appendSpecialPageAliases( $p );
00055                     break;
00056                 case 'magicwords':
00057                     $fit = $this->appendMagicWords( $p );
00058                     break;
00059                 case 'interwikimap':
00060                     $filteriw = isset( $params['filteriw'] ) ? $params['filteriw'] : false;
00061                     $fit = $this->appendInterwikiMap( $p, $filteriw );
00062                     break;
00063                 case 'dbrepllag':
00064                     $fit = $this->appendDbReplLagInfo( $p, $params['showalldb'] );
00065                     break;
00066                 case 'statistics':
00067                     $fit = $this->appendStatistics( $p );
00068                     break;
00069                 case 'usergroups':
00070                     $fit = $this->appendUserGroups( $p, $params['numberingroup'] );
00071                     break;
00072                 case 'extensions':
00073                     $fit = $this->appendExtensions( $p );
00074                     break;
00075                 case 'fileextensions':
00076                     $fit = $this->appendFileExtensions( $p );
00077                     break;
00078                 case 'rightsinfo':
00079                     $fit = $this->appendRightsInfo( $p );
00080                     break;
00081                 case 'restrictions':
00082                     $fit = $this->appendRestrictions( $p );
00083                     break;
00084                 case 'languages':
00085                     $fit = $this->appendLanguages( $p );
00086                     break;
00087                 case 'skins':
00088                     $fit = $this->appendSkins( $p );
00089                     break;
00090                 case 'extensiontags':
00091                     $fit = $this->appendExtensionTags( $p );
00092                     break;
00093                 case 'functionhooks':
00094                     $fit = $this->appendFunctionHooks( $p );
00095                     break;
00096                 case 'showhooks':
00097                     $fit = $this->appendSubscribedHooks( $p );
00098                     break;
00099                 case 'variables':
00100                     $fit = $this->appendVariables( $p );
00101                     break;
00102                 case 'protocols':
00103                     $fit = $this->appendProtocols( $p );
00104                     break;
00105                 case 'defaultoptions':
00106                     $fit = $this->appendDefaultOptions( $p );
00107                     break;
00108                 default:
00109                     ApiBase::dieDebug( __METHOD__, "Unknown prop=$p" );
00110             }
00111             if ( !$fit ) {
00112                 // Abuse siprop as a query-continue parameter
00113                 // and set it to all unprocessed props
00114                 $this->setContinueEnumParameter( 'prop', implode( '|',
00115                     array_diff( $params['prop'], $done ) ) );
00116                 break;
00117             }
00118             $done[] = $p;
00119         }
00120     }
00121 
00122     protected function appendGeneralInfo( $property ) {
00123         global $wgContLang;
00124 
00125         $config = $this->getConfig();
00126 
00127         $data = array();
00128         $mainPage = Title::newMainPage();
00129         $data['mainpage'] = $mainPage->getPrefixedText();
00130         $data['base'] = wfExpandUrl( $mainPage->getFullURL(), PROTO_CURRENT );
00131         $data['sitename'] = $config->get( 'Sitename' );
00132 
00133         // wgLogo can either be a relative or an absolute path
00134         // make sure we always return an absolute path
00135         $data['logo'] = wfExpandUrl( $config->get( 'Logo' ), PROTO_RELATIVE );
00136 
00137         $data['generator'] = "MediaWiki {$config->get( 'Version' )}";
00138 
00139         $data['phpversion'] = PHP_VERSION;
00140         $data['phpsapi'] = PHP_SAPI;
00141         if ( defined( 'HHVM_VERSION' ) ) {
00142             $data['hhvmversion'] = HHVM_VERSION;
00143         }
00144         $data['dbtype'] = $config->get( 'DBtype' );
00145         $data['dbversion'] = $this->getDB()->getServerVersion();
00146 
00147         $allowFrom = array( '' );
00148         $allowException = true;
00149         if ( !$config->get( 'AllowExternalImages' ) ) {
00150             if ( $config->get( 'EnableImageWhitelist' ) ) {
00151                 $data['imagewhitelistenabled'] = '';
00152             }
00153             $allowFrom = $config->get( 'AllowExternalImagesFrom' );
00154             $allowException = !empty( $allowFrom );
00155         }
00156         if ( $allowException ) {
00157             $data['externalimages'] = (array)$allowFrom;
00158             $this->getResult()->setIndexedTagName( $data['externalimages'], 'prefix' );
00159         }
00160 
00161         if ( !$config->get( 'DisableLangConversion' ) ) {
00162             $data['langconversion'] = '';
00163         }
00164 
00165         if ( !$config->get( 'DisableTitleConversion' ) ) {
00166             $data['titleconversion'] = '';
00167         }
00168 
00169         if ( $wgContLang->linkPrefixExtension() ) {
00170             $linkPrefixCharset = $wgContLang->linkPrefixCharset();
00171             $data['linkprefixcharset'] = $linkPrefixCharset;
00172             // For backwards compatibility
00173             $data['linkprefix'] = "/^((?>.*[^$linkPrefixCharset]|))(.+)$/sDu";
00174         } else {
00175             $data['linkprefixcharset'] = '';
00176             $data['linkprefix'] = '';
00177         }
00178 
00179         $linktrail = $wgContLang->linkTrail();
00180         if ( $linktrail ) {
00181             $data['linktrail'] = $linktrail;
00182         } else {
00183             $data['linktrail'] = '';
00184         }
00185 
00186         global $IP;
00187         $git = SpecialVersion::getGitHeadSha1( $IP );
00188         if ( $git ) {
00189             $data['git-hash'] = $git;
00190             $data['git-branch'] =
00191                 SpecialVersion::getGitCurrentBranch( $GLOBALS['IP'] );
00192         } else {
00193             $svn = SpecialVersion::getSvnRevision( $IP );
00194             if ( $svn ) {
00195                 $data['rev'] = $svn;
00196             }
00197         }
00198 
00199         // 'case-insensitive' option is reserved for future
00200         $data['case'] = $config->get( 'CapitalLinks' ) ? 'first-letter' : 'case-sensitive';
00201         $data['lang'] = $config->get( 'LanguageCode' );
00202 
00203         $fallbacks = array();
00204         foreach ( $wgContLang->getFallbackLanguages() as $code ) {
00205             $fallbacks[] = array( 'code' => $code );
00206         }
00207         $data['fallback'] = $fallbacks;
00208         $this->getResult()->setIndexedTagName( $data['fallback'], 'lang' );
00209 
00210         if ( $wgContLang->hasVariants() ) {
00211             $variants = array();
00212             foreach ( $wgContLang->getVariants() as $code ) {
00213                 $variants[] = array(
00214                     'code' => $code,
00215                     'name' => $wgContLang->getVariantname( $code ),
00216                 );
00217             }
00218             $data['variants'] = $variants;
00219             $this->getResult()->setIndexedTagName( $data['variants'], 'lang' );
00220         }
00221 
00222         if ( $wgContLang->isRTL() ) {
00223             $data['rtl'] = '';
00224         }
00225         $data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
00226 
00227         if ( wfReadOnly() ) {
00228             $data['readonly'] = '';
00229             $data['readonlyreason'] = wfReadOnlyReason();
00230         }
00231         if ( $config->get( 'EnableWriteAPI' ) ) {
00232             $data['writeapi'] = '';
00233         }
00234 
00235         $tz = $config->get( 'Localtimezone' );
00236         $offset = $config->get( 'LocalTZoffset' );
00237         if ( is_null( $tz ) ) {
00238             $tz = 'UTC';
00239             $offset = 0;
00240         } elseif ( is_null( $offset ) ) {
00241             $offset = 0;
00242         }
00243         $data['timezone'] = $tz;
00244         $data['timeoffset'] = intval( $offset );
00245         $data['articlepath'] = $config->get( 'ArticlePath' );
00246         $data['scriptpath'] = $config->get( 'ScriptPath' );
00247         $data['script'] = $config->get( 'Script' );
00248         $data['variantarticlepath'] = $config->get( 'VariantArticlePath' );
00249         $data['server'] = $config->get( 'Server' );
00250         $data['servername'] = $config->get( 'ServerName' );
00251         $data['wikiid'] = wfWikiID();
00252         $data['time'] = wfTimestamp( TS_ISO_8601, time() );
00253 
00254         if ( $config->get( 'MiserMode' ) ) {
00255             $data['misermode'] = '';
00256         }
00257 
00258         $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
00259 
00260         $data['thumblimits'] = $config->get( 'ThumbLimits' );
00261         $this->getResult()->setIndexedTagName( $data['thumblimits'], 'limit' );
00262         $data['imagelimits'] = array();
00263         $this->getResult()->setIndexedTagName( $data['imagelimits'], 'limit' );
00264         foreach ( $config->get( 'ImageLimits' ) as $k => $limit ) {
00265             $data['imagelimits'][$k] = array( 'width' => $limit[0], 'height' => $limit[1] );
00266         }
00267 
00268         $favicon = $config->get( 'Favicon' );
00269         if ( !empty( $favicon ) ) {
00270             // wgFavicon can either be a relative or an absolute path
00271             // make sure we always return an absolute path
00272             $data['favicon'] = wfExpandUrl( $favicon, PROTO_RELATIVE );
00273         }
00274 
00275         wfRunHooks( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
00276 
00277         return $this->getResult()->addValue( 'query', $property, $data );
00278     }
00279 
00280     protected function appendNamespaces( $property ) {
00281         global $wgContLang;
00282         $data = array();
00283         foreach ( $wgContLang->getFormattedNamespaces() as $ns => $title ) {
00284             $data[$ns] = array(
00285                 'id' => intval( $ns ),
00286                 'case' => MWNamespace::isCapitalized( $ns ) ? 'first-letter' : 'case-sensitive',
00287             );
00288             ApiResult::setContent( $data[$ns], $title );
00289             $canonical = MWNamespace::getCanonicalName( $ns );
00290 
00291             if ( MWNamespace::hasSubpages( $ns ) ) {
00292                 $data[$ns]['subpages'] = '';
00293             }
00294 
00295             if ( $canonical ) {
00296                 $data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
00297             }
00298 
00299             if ( MWNamespace::isContent( $ns ) ) {
00300                 $data[$ns]['content'] = '';
00301             }
00302 
00303             if ( MWNamespace::isNonincludable( $ns ) ) {
00304                 $data[$ns]['nonincludable'] = '';
00305             }
00306 
00307             $contentmodel = MWNamespace::getNamespaceContentModel( $ns );
00308             if ( $contentmodel ) {
00309                 $data[$ns]['defaultcontentmodel'] = $contentmodel;
00310             }
00311         }
00312 
00313         $this->getResult()->setIndexedTagName( $data, 'ns' );
00314 
00315         return $this->getResult()->addValue( 'query', $property, $data );
00316     }
00317 
00318     protected function appendNamespaceAliases( $property ) {
00319         global $wgContLang;
00320         $aliases = array_merge( $this->getConfig()->get( 'NamespaceAliases' ),
00321             $wgContLang->getNamespaceAliases() );
00322         $namespaces = $wgContLang->getNamespaces();
00323         $data = array();
00324         foreach ( $aliases as $title => $ns ) {
00325             if ( $namespaces[$ns] == $title ) {
00326                 // Don't list duplicates
00327                 continue;
00328             }
00329             $item = array(
00330                 'id' => intval( $ns )
00331             );
00332             ApiResult::setContent( $item, strtr( $title, '_', ' ' ) );
00333             $data[] = $item;
00334         }
00335 
00336         sort( $data );
00337 
00338         $this->getResult()->setIndexedTagName( $data, 'ns' );
00339 
00340         return $this->getResult()->addValue( 'query', $property, $data );
00341     }
00342 
00343     protected function appendSpecialPageAliases( $property ) {
00344         global $wgContLang;
00345         $data = array();
00346         $aliases = $wgContLang->getSpecialPageAliases();
00347         foreach ( SpecialPageFactory::getNames() as $specialpage ) {
00348             if ( isset( $aliases[$specialpage] ) ) {
00349                 $arr = array( 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] );
00350                 $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
00351                 $data[] = $arr;
00352             }
00353         }
00354         $this->getResult()->setIndexedTagName( $data, 'specialpage' );
00355 
00356         return $this->getResult()->addValue( 'query', $property, $data );
00357     }
00358 
00359     protected function appendMagicWords( $property ) {
00360         global $wgContLang;
00361         $data = array();
00362         foreach ( $wgContLang->getMagicWords() as $magicword => $aliases ) {
00363             $caseSensitive = array_shift( $aliases );
00364             $arr = array( 'name' => $magicword, 'aliases' => $aliases );
00365             if ( $caseSensitive ) {
00366                 $arr['case-sensitive'] = '';
00367             }
00368             $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
00369             $data[] = $arr;
00370         }
00371         $this->getResult()->setIndexedTagName( $data, 'magicword' );
00372 
00373         return $this->getResult()->addValue( 'query', $property, $data );
00374     }
00375 
00376     protected function appendInterwikiMap( $property, $filter ) {
00377         $local = null;
00378         if ( $filter === 'local' ) {
00379             $local = 1;
00380         } elseif ( $filter === '!local' ) {
00381             $local = 0;
00382         } elseif ( $filter ) {
00383             ApiBase::dieDebug( __METHOD__, "Unknown filter=$filter" );
00384         }
00385 
00386         $params = $this->extractRequestParams();
00387         $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
00388         $langNames = Language::fetchLanguageNames( $langCode );
00389 
00390         $getPrefixes = Interwiki::getAllPrefixes( $local );
00391         $extraLangPrefixes = $this->getConfig()->get( 'ExtraInterlanguageLinkPrefixes' );
00392         $localInterwikis = $this->getConfig()->get( 'LocalInterwikis' );
00393         $data = array();
00394 
00395         foreach ( $getPrefixes as $row ) {
00396             $prefix = $row['iw_prefix'];
00397             $val = array();
00398             $val['prefix'] = $prefix;
00399             if ( isset( $row['iw_local'] ) && $row['iw_local'] == '1' ) {
00400                 $val['local'] = '';
00401             }
00402             if ( isset( $row['iw_trans'] ) && $row['iw_trans'] == '1' ) {
00403                 $val['trans'] = '';
00404             }
00405 
00406             if ( isset( $langNames[$prefix] ) ) {
00407                 $val['language'] = $langNames[$prefix];
00408             }
00409             if ( in_array( $prefix, $localInterwikis ) ) {
00410                 $val['localinterwiki'] = '';
00411             }
00412             if ( in_array( $prefix, $extraLangPrefixes ) ) {
00413                 $val['extralanglink'] = '';
00414 
00415                 $linktext = wfMessage( "interlanguage-link-$prefix" );
00416                 if ( !$linktext->isDisabled() ) {
00417                     $val['linktext'] = $linktext->text();
00418                 }
00419 
00420                 $sitename = wfMessage( "interlanguage-link-sitename-$prefix" );
00421                 if ( !$sitename->isDisabled() ) {
00422                     $val['sitename'] = $sitename->text();
00423                 }
00424             }
00425 
00426             $val['url'] = wfExpandUrl( $row['iw_url'], PROTO_CURRENT );
00427             if ( substr( $row['iw_url'], 0, 2 ) == '//' ) {
00428                 $val['protorel'] = '';
00429             }
00430             if ( isset( $row['iw_wikiid'] ) ) {
00431                 $val['wikiid'] = $row['iw_wikiid'];
00432             }
00433             if ( isset( $row['iw_api'] ) ) {
00434                 $val['api'] = $row['iw_api'];
00435             }
00436 
00437             $data[] = $val;
00438         }
00439 
00440         $this->getResult()->setIndexedTagName( $data, 'iw' );
00441 
00442         return $this->getResult()->addValue( 'query', $property, $data );
00443     }
00444 
00445     protected function appendDbReplLagInfo( $property, $includeAll ) {
00446         $data = array();
00447         $lb = wfGetLB();
00448         $showHostnames = $this->getConfig()->get( 'ShowHostnames' );
00449         if ( $includeAll ) {
00450             if ( !$showHostnames ) {
00451                 $this->dieUsage(
00452                     'Cannot view all servers info unless $wgShowHostnames is true',
00453                     'includeAllDenied'
00454                 );
00455             }
00456 
00457             $lags = $lb->getLagTimes();
00458             foreach ( $lags as $i => $lag ) {
00459                 $data[] = array(
00460                     'host' => $lb->getServerName( $i ),
00461                     'lag' => $lag
00462                 );
00463             }
00464         } else {
00465             list( , $lag, $index ) = $lb->getMaxLag();
00466             $data[] = array(
00467                 'host' => $showHostnames
00468                         ? $lb->getServerName( $index )
00469                         : '',
00470                 'lag' => intval( $lag )
00471             );
00472         }
00473 
00474         $result = $this->getResult();
00475         $result->setIndexedTagName( $data, 'db' );
00476 
00477         return $this->getResult()->addValue( 'query', $property, $data );
00478     }
00479 
00480     protected function appendStatistics( $property ) {
00481         $data = array();
00482         $data['pages'] = intval( SiteStats::pages() );
00483         $data['articles'] = intval( SiteStats::articles() );
00484         if ( !$this->getConfig()->get( 'DisableCounters' ) ) {
00485             $data['views'] = intval( SiteStats::views() );
00486         }
00487         $data['edits'] = intval( SiteStats::edits() );
00488         $data['images'] = intval( SiteStats::images() );
00489         $data['users'] = intval( SiteStats::users() );
00490         $data['activeusers'] = intval( SiteStats::activeUsers() );
00491         $data['admins'] = intval( SiteStats::numberingroup( 'sysop' ) );
00492         $data['jobs'] = intval( SiteStats::jobs() );
00493 
00494         wfRunHooks( 'APIQuerySiteInfoStatisticsInfo', array( &$data ) );
00495 
00496         return $this->getResult()->addValue( 'query', $property, $data );
00497     }
00498 
00499     protected function appendUserGroups( $property, $numberInGroup ) {
00500         $config = $this->getConfig();
00501 
00502         $data = array();
00503         $result = $this->getResult();
00504         $allGroups = User::getAllGroups();
00505         foreach ( $config->get( 'GroupPermissions' ) as $group => $permissions ) {
00506             $arr = array(
00507                 'name' => $group,
00508                 'rights' => array_keys( $permissions, true ),
00509             );
00510 
00511             if ( $numberInGroup ) {
00512                 $autopromote = $config->get( 'Autopromote' );
00513 
00514                 if ( $group == 'user' ) {
00515                     $arr['number'] = SiteStats::users();
00516                 // '*' and autopromote groups have no size
00517                 } elseif ( $group !== '*' && !isset( $autopromote[$group] ) ) {
00518                     $arr['number'] = SiteStats::numberInGroup( $group );
00519                 }
00520             }
00521 
00522             $groupArr = array(
00523                 'add' => $config->get( 'AddGroups' ),
00524                 'remove' => $config->get( 'RemoveGroups' ),
00525                 'add-self' => $config->get( 'GroupsAddToSelf' ),
00526                 'remove-self' => $config->get( 'GroupsRemoveFromSelf' )
00527             );
00528 
00529             foreach ( $groupArr as $type => $rights ) {
00530                 if ( isset( $rights[$group] ) ) {
00531                     $groups = array_intersect( $rights[$group], $allGroups );
00532                     if ( $groups ) {
00533                         $arr[$type] = $groups;
00534                         $result->setIndexedTagName( $arr[$type], 'group' );
00535                     }
00536                 }
00537             }
00538 
00539             $result->setIndexedTagName( $arr['rights'], 'permission' );
00540             $data[] = $arr;
00541         }
00542 
00543         $result->setIndexedTagName( $data, 'group' );
00544 
00545         return $result->addValue( 'query', $property, $data );
00546     }
00547 
00548     protected function appendFileExtensions( $property ) {
00549         $data = array();
00550         foreach ( array_unique( $this->getConfig()->get( 'FileExtensions' ) ) as $ext ) {
00551             $data[] = array( 'ext' => $ext );
00552         }
00553         $this->getResult()->setIndexedTagName( $data, 'fe' );
00554 
00555         return $this->getResult()->addValue( 'query', $property, $data );
00556     }
00557 
00558     protected function appendExtensions( $property ) {
00559         $data = array();
00560         foreach ( $this->getConfig()->get( 'ExtensionCredits' ) as $type => $extensions ) {
00561             foreach ( $extensions as $ext ) {
00562                 $ret = array();
00563                 $ret['type'] = $type;
00564                 if ( isset( $ext['name'] ) ) {
00565                     $ret['name'] = $ext['name'];
00566                 }
00567                 if ( isset( $ext['namemsg'] ) ) {
00568                     $ret['namemsg'] = $ext['namemsg'];
00569                 }
00570                 if ( isset( $ext['description'] ) ) {
00571                     $ret['description'] = $ext['description'];
00572                 }
00573                 if ( isset( $ext['descriptionmsg'] ) ) {
00574                     // Can be a string or array( key, param1, param2, ... )
00575                     if ( is_array( $ext['descriptionmsg'] ) ) {
00576                         $ret['descriptionmsg'] = $ext['descriptionmsg'][0];
00577                         $ret['descriptionmsgparams'] = array_slice( $ext['descriptionmsg'], 1 );
00578                         $this->getResult()->setIndexedTagName( $ret['descriptionmsgparams'], 'param' );
00579                     } else {
00580                         $ret['descriptionmsg'] = $ext['descriptionmsg'];
00581                     }
00582                 }
00583                 if ( isset( $ext['author'] ) ) {
00584                     $ret['author'] = is_array( $ext['author'] ) ?
00585                         implode( ', ', $ext['author'] ) : $ext['author'];
00586                 }
00587                 if ( isset( $ext['url'] ) ) {
00588                     $ret['url'] = $ext['url'];
00589                 }
00590                 if ( isset( $ext['version'] ) ) {
00591                     $ret['version'] = $ext['version'];
00592                 } elseif ( isset( $ext['svn-revision'] ) &&
00593                     preg_match( '/\$(?:Rev|LastChangedRevision|Revision): *(\d+)/',
00594                         $ext['svn-revision'], $m )
00595                 ) {
00596                     $ret['version'] = 'r' . $m[1];
00597                 }
00598                 if ( isset( $ext['path'] ) ) {
00599                     $extensionPath = dirname( $ext['path'] );
00600                     $gitInfo = new GitInfo( $extensionPath );
00601                     $vcsVersion = $gitInfo->getHeadSHA1();
00602                     if ( $vcsVersion !== false ) {
00603                         $ret['vcs-system'] = 'git';
00604                         $ret['vcs-version'] = $vcsVersion;
00605                         $ret['vcs-url'] = $gitInfo->getHeadViewUrl();
00606                         $vcsDate = $gitInfo->getHeadCommitDate();
00607                         if ( $vcsDate !== false ) {
00608                             $ret['vcs-date'] = wfTimestamp( TS_ISO_8601, $vcsDate );
00609                         }
00610                     } else {
00611                         $svnInfo = SpecialVersion::getSvnInfo( $extensionPath );
00612                         if ( $svnInfo !== false ) {
00613                             $ret['vcs-system'] = 'svn';
00614                             $ret['vcs-version'] = $svnInfo['checkout-rev'];
00615                             $ret['vcs-url'] = isset( $svnInfo['viewvc-url'] ) ? $svnInfo['viewvc-url'] : '';
00616                         }
00617                     }
00618 
00619                     if ( SpecialVersion::getExtLicenseFileName( $extensionPath ) ) {
00620                         $ret['license-name'] = isset( $ext['license-name'] ) ? $ext['license-name'] : '';
00621                         $ret['license'] = SpecialPage::getTitleFor(
00622                             'Version',
00623                             "License/{$ext['name']}"
00624                         )->getLinkURL();
00625                     }
00626 
00627                     if ( SpecialVersion::getExtAuthorsFileName( $extensionPath ) ) {
00628                         $ret['credits'] = SpecialPage::getTitleFor(
00629                             'Version',
00630                             "Credits/{$ext['name']}"
00631                         )->getLinkURL();
00632                     }
00633                 }
00634                 $data[] = $ret;
00635             }
00636         }
00637 
00638         $this->getResult()->setIndexedTagName( $data, 'ext' );
00639 
00640         return $this->getResult()->addValue( 'query', $property, $data );
00641     }
00642 
00643     protected function appendRightsInfo( $property ) {
00644         $config = $this->getConfig();
00645         $title = Title::newFromText( $config->get( 'RightsPage' ) );
00646         $url = $title ? wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ) : $config->get( 'RightsUrl' );
00647         $text = $config->get( 'RightsText' );
00648         if ( !$text && $title ) {
00649             $text = $title->getPrefixedText();
00650         }
00651 
00652         $data = array(
00653             'url' => $url ? $url : '',
00654             'text' => $text ? $text : ''
00655         );
00656 
00657         return $this->getResult()->addValue( 'query', $property, $data );
00658     }
00659 
00660     protected function appendRestrictions( $property ) {
00661         $config = $this->getConfig();
00662         $data = array(
00663             'types' => $config->get( 'RestrictionTypes' ),
00664             'levels' => $config->get( 'RestrictionLevels' ),
00665             'cascadinglevels' => $config->get( 'CascadingRestrictionLevels' ),
00666             'semiprotectedlevels' => $config->get( 'SemiprotectedRestrictionLevels' ),
00667         );
00668 
00669         $this->getResult()->setIndexedTagName( $data['types'], 'type' );
00670         $this->getResult()->setIndexedTagName( $data['levels'], 'level' );
00671         $this->getResult()->setIndexedTagName( $data['cascadinglevels'], 'level' );
00672         $this->getResult()->setIndexedTagName( $data['semiprotectedlevels'], 'level' );
00673 
00674         return $this->getResult()->addValue( 'query', $property, $data );
00675     }
00676 
00677     public function appendLanguages( $property ) {
00678         $params = $this->extractRequestParams();
00679         $langCode = isset( $params['inlanguagecode'] ) ? $params['inlanguagecode'] : '';
00680         $langNames = Language::fetchLanguageNames( $langCode );
00681 
00682         $data = array();
00683 
00684         foreach ( $langNames as $code => $name ) {
00685             $lang = array( 'code' => $code );
00686             ApiResult::setContent( $lang, $name );
00687             $data[] = $lang;
00688         }
00689         $this->getResult()->setIndexedTagName( $data, 'lang' );
00690 
00691         return $this->getResult()->addValue( 'query', $property, $data );
00692     }
00693 
00694     public function appendSkins( $property ) {
00695         $data = array();
00696         $allowed = Skin::getAllowedSkins();
00697         $default = Skin::normalizeKey( 'default' );
00698         foreach ( Skin::getSkinNames() as $name => $displayName ) {
00699             $msg = $this->msg( "skinname-{$name}" );
00700             $code = $this->getParameter( 'inlanguagecode' );
00701             if ( $code && Language::isValidCode( $code ) ) {
00702                 $msg->inLanguage( $code );
00703             } else {
00704                 $msg->inContentLanguage();
00705             }
00706             if ( $msg->exists() ) {
00707                 $displayName = $msg->text();
00708             }
00709             $skin = array( 'code' => $name );
00710             ApiResult::setContent( $skin, $displayName );
00711             if ( !isset( $allowed[$name] ) ) {
00712                 $skin['unusable'] = '';
00713             }
00714             if ( $name === $default ) {
00715                 $skin['default'] = '';
00716             }
00717             $data[] = $skin;
00718         }
00719         $this->getResult()->setIndexedTagName( $data, 'skin' );
00720 
00721         return $this->getResult()->addValue( 'query', $property, $data );
00722     }
00723 
00724     public function appendExtensionTags( $property ) {
00725         global $wgParser;
00726         $wgParser->firstCallInit();
00727         $tags = array_map( array( $this, 'formatParserTags' ), $wgParser->getTags() );
00728         $this->getResult()->setIndexedTagName( $tags, 't' );
00729 
00730         return $this->getResult()->addValue( 'query', $property, $tags );
00731     }
00732 
00733     public function appendFunctionHooks( $property ) {
00734         global $wgParser;
00735         $wgParser->firstCallInit();
00736         $hooks = $wgParser->getFunctionHooks();
00737         $this->getResult()->setIndexedTagName( $hooks, 'h' );
00738 
00739         return $this->getResult()->addValue( 'query', $property, $hooks );
00740     }
00741 
00742     public function appendVariables( $property ) {
00743         $variables = MagicWord::getVariableIDs();
00744         $this->getResult()->setIndexedTagName( $variables, 'v' );
00745 
00746         return $this->getResult()->addValue( 'query', $property, $variables );
00747     }
00748 
00749     public function appendProtocols( $property ) {
00750         // Make a copy of the global so we don't try to set the _element key of it - bug 45130
00751         $protocols = array_values( $this->getConfig()->get( 'UrlProtocols' ) );
00752         $this->getResult()->setIndexedTagName( $protocols, 'p' );
00753 
00754         return $this->getResult()->addValue( 'query', $property, $protocols );
00755     }
00756 
00757     public function appendDefaultOptions( $property ) {
00758         return $this->getResult()->addValue( 'query', $property, User::getDefaultOptions() );
00759     }
00760 
00761     private function formatParserTags( $item ) {
00762         return "<{$item}>";
00763     }
00764 
00765     public function appendSubscribedHooks( $property ) {
00766         $hooks = $this->getConfig()->get( 'Hooks' );
00767         $myWgHooks = $hooks;
00768         ksort( $myWgHooks );
00769 
00770         $data = array();
00771         foreach ( $myWgHooks as $name => $subscribers ) {
00772             $arr = array(
00773                 'name' => $name,
00774                 'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $subscribers ),
00775             );
00776 
00777             $this->getResult()->setIndexedTagName( $arr['subscribers'], 's' );
00778             $data[] = $arr;
00779         }
00780 
00781         $this->getResult()->setIndexedTagName( $data, 'hook' );
00782 
00783         return $this->getResult()->addValue( 'query', $property, $data );
00784     }
00785 
00786     public function getCacheMode( $params ) {
00787         // Messages for $wgExtraInterlanguageLinkPrefixes depend on user language
00788         if (
00789             count( $this->getConfig()->get( 'ExtraInterlanguageLinkPrefixes' ) ) &&
00790             !is_null( $params['prop'] ) &&
00791             in_array( 'interwikimap', $params['prop'] )
00792         ) {
00793             return 'anon-public-user-private';
00794         }
00795 
00796         return 'public';
00797     }
00798 
00799     public function getAllowedParams() {
00800         return array(
00801             'prop' => array(
00802                 ApiBase::PARAM_DFLT => 'general',
00803                 ApiBase::PARAM_ISMULTI => true,
00804                 ApiBase::PARAM_TYPE => array(
00805                     'general',
00806                     'namespaces',
00807                     'namespacealiases',
00808                     'specialpagealiases',
00809                     'magicwords',
00810                     'interwikimap',
00811                     'dbrepllag',
00812                     'statistics',
00813                     'usergroups',
00814                     'extensions',
00815                     'fileextensions',
00816                     'rightsinfo',
00817                     'restrictions',
00818                     'languages',
00819                     'skins',
00820                     'extensiontags',
00821                     'functionhooks',
00822                     'showhooks',
00823                     'variables',
00824                     'protocols',
00825                     'defaultoptions',
00826                 )
00827             ),
00828             'filteriw' => array(
00829                 ApiBase::PARAM_TYPE => array(
00830                     'local',
00831                     '!local',
00832                 )
00833             ),
00834             'showalldb' => false,
00835             'numberingroup' => false,
00836             'inlanguagecode' => null,
00837         );
00838     }
00839 
00840     public function getParamDescription() {
00841         $p = $this->getModulePrefix();
00842 
00843         return array(
00844             'prop' => array(
00845                 'Which sysinfo properties to get:',
00846                 ' general               - Overall system information',
00847                 ' namespaces            - List of registered namespaces and their canonical names',
00848                 ' namespacealiases      - List of registered namespace aliases',
00849                 ' specialpagealiases    - List of special page aliases',
00850                 ' magicwords            - List of magic words and their aliases',
00851                 ' statistics            - Returns site statistics',
00852                 ' interwikimap          - Returns interwiki map ' .
00853                     "(optionally filtered, (optionally localised by using {$p}inlanguagecode))",
00854                 ' dbrepllag             - Returns database server with the highest replication lag',
00855                 ' usergroups            - Returns user groups and the associated permissions',
00856                 ' extensions            - Returns extensions installed on the wiki',
00857                 ' fileextensions        - Returns list of file extensions allowed to be uploaded',
00858                 ' rightsinfo            - Returns wiki rights (license) information if available',
00859                 ' restrictions          - Returns information on available restriction (protection) types',
00860                 ' languages             - Returns a list of languages MediaWiki supports ' .
00861                     "(optionally localised by using {$p}inlanguagecode)",
00862                 ' skins                 - Returns a list of all enabled skins ' .
00863                     "(optionally localised by using {$p}inlanguagecode, otherwise in content language)",
00864                 ' extensiontags         - Returns a list of parser extension tags',
00865                 ' functionhooks         - Returns a list of parser function hooks',
00866                 ' showhooks             - Returns a list of all subscribed hooks (contents of $wgHooks)',
00867                 ' variables             - Returns a list of variable IDs',
00868                 ' protocols             - Returns a list of protocols that are allowed in external links.',
00869                 ' defaultoptions        - Returns the default values for user preferences.',
00870             ),
00871             'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
00872             'showalldb' => 'List all database servers, not just the one lagging the most',
00873             'numberingroup' => 'Lists the number of users in user groups',
00874             'inlanguagecode' => 'Language code for localised language names ' .
00875                 '(best effort, use CLDR extension) and skin names',
00876         );
00877     }
00878 
00879     public function getDescription() {
00880         return 'Return general information about the site.';
00881     }
00882 
00883     public function getExamples() {
00884         return array(
00885             'api.php?action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics',
00886             'api.php?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local',
00887             'api.php?action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb=',
00888         );
00889     }
00890 
00891     public function getHelpUrls() {
00892         return 'https://www.mediawiki.org/wiki/API:Meta#siteinfo_.2F_si';
00893     }
00894 }