function( MediaWikiServices $services ) { $mainConfig = $services->getMainConfig(); $lbConf = LBFactoryMW::applyDefaultConfig( $mainConfig->get( 'LBFactoryConf' ), $mainConfig ); $class = LBFactoryMW::getLBFactoryClass( $lbConf ); return new $class( $lbConf ); }, 'DBLoadBalancer' => function( MediaWikiServices $services ) { // just return the default LB from the DBLoadBalancerFactory service return $services->getDBLoadBalancerFactory()->getMainLB(); }, 'SiteStore' => function( MediaWikiServices $services ) { $rawSiteStore = new DBSiteStore( $services->getDBLoadBalancer() ); // TODO: replace wfGetCache with a CacheFactory service. // TODO: replace wfIsHHVM with a capabilities service. $cache = wfGetCache( wfIsHHVM() ? CACHE_ACCEL : CACHE_ANYTHING ); return new CachingSiteStore( $rawSiteStore, $cache ); }, 'SiteLookup' => function( MediaWikiServices $services ) { // Use the default SiteStore as the SiteLookup implementation for now return $services->getSiteStore(); }, 'ConfigFactory' => function( MediaWikiServices $services ) { // Use the bootstrap config to initialize the ConfigFactory. $registry = $services->getBootstrapConfig()->get( 'ConfigRegistry' ); $factory = new ConfigFactory(); foreach ( $registry as $name => $callback ) { $factory->register( $name, $callback ); } return $factory; }, 'MainConfig' => function( MediaWikiServices $services ) { // Use the 'main' config from the ConfigFactory service. return $services->getConfigFactory()->makeConfig( 'main' ); }, 'InterwikiLookup' => function( MediaWikiServices $services ) { global $wgContLang; // TODO: manage $wgContLang as a service $config = $services->getMainConfig(); return new ClassicInterwikiLookup( $wgContLang, ObjectCache::getMainWANInstance(), $config->get( 'InterwikiExpiry' ), $config->get( 'InterwikiCache' ), $config->get( 'InterwikiScopes' ), $config->get( 'InterwikiFallbackSite' ) ); }, 'StatsdDataFactory' => function( MediaWikiServices $services ) { return new BufferingStatsdDataFactory( rtrim( $services->getMainConfig()->get( 'StatsdMetricPrefix' ), '.' ) ); }, 'EventRelayerGroup' => function( MediaWikiServices $services ) { return new EventRelayerGroup( $services->getMainConfig()->get( 'EventRelayerConfig' ) ); }, 'SearchEngineFactory' => function( MediaWikiServices $services ) { return new SearchEngineFactory( $services->getSearchEngineConfig() ); }, 'SearchEngineConfig' => function( MediaWikiServices $services ) { global $wgContLang; return new SearchEngineConfig( $services->getMainConfig(), $wgContLang ); }, 'SkinFactory' => function( MediaWikiServices $services ) { $factory = new SkinFactory(); $names = $services->getMainConfig()->get( 'ValidSkinNames' ); foreach ( $names as $name => $skin ) { $factory->register( $name, $skin, function () use ( $name, $skin ) { $class = "Skin$skin"; return new $class( $name ); } ); } // Register a hidden "fallback" skin $factory->register( 'fallback', 'Fallback', function () { return new SkinFallback; } ); // Register a hidden skin for api output $factory->register( 'apioutput', 'ApiOutput', function () { return new SkinApi; } ); return $factory; }, 'WatchedItemStore' => function( MediaWikiServices $services ) { $store = new WatchedItemStore( $services->getDBLoadBalancer(), new HashBagOStuff( [ 'maxKeys' => 100 ] ) ); $store->setStatsdDataFactory( $services->getStatsdDataFactory() ); return $store; }, 'WatchedItemQueryService' => function( MediaWikiServices $services ) { return new WatchedItemQueryService( $services->getDBLoadBalancer() ); }, 'MediaHandlerFactory' => function( MediaWikiServices $services ) { return new MediaHandlerFactory( $services->getMainConfig()->get( 'MediaHandlers' ) ); }, 'ProxyLookup' => function( MediaWikiServices $services ) { $mainConfig = $services->getMainConfig(); return new ProxyLookup( $mainConfig->get( 'SquidServers' ), $mainConfig->get( 'SquidServersNoPurge' ) ); }, 'LinkCache' => function( MediaWikiServices $services ) { return new LinkCache( $services->getTitleFormatter(), ObjectCache::getMainWANInstance() ); }, 'LinkRendererFactory' => function( MediaWikiServices $services ) { return new LinkRendererFactory( $services->getTitleFormatter(), $services->getLinkCache() ); }, 'LinkRenderer' => function( MediaWikiServices $services ) { global $wgUser; if ( defined( 'MW_NO_SESSION' ) ) { return $services->getLinkRendererFactory()->create(); } else { return $services->getLinkRendererFactory()->createForUser( $wgUser ); } }, 'GenderCache' => function( MediaWikiServices $services ) { return new GenderCache(); }, '_MediaWikiTitleCodec' => function( MediaWikiServices $services ) { global $wgContLang; return new MediaWikiTitleCodec( $wgContLang, $services->getGenderCache(), $services->getMainConfig()->get( 'LocalInterwikis' ) ); }, 'TitleFormatter' => function( MediaWikiServices $services ) { return $services->getService( '_MediaWikiTitleCodec' ); }, 'TitleParser' => function( MediaWikiServices $services ) { return $services->getService( '_MediaWikiTitleCodec' ); }, 'VirtualRESTServiceClient' => function( MediaWikiServices $services ) { $config = $services->getMainConfig()->get( 'VirtualRestConfig' ); $vrsClient = new VirtualRESTServiceClient( new MultiHttpClient( [] ) ); foreach ( $config['paths'] as $prefix => $serviceConfig ) { $class = $serviceConfig['class']; // Merge in the global defaults $constructArg = isset( $serviceConfig['options'] ) ? $serviceConfig['options'] : []; $constructArg += $config['global']; // Make the VRS service available at the mount point $vrsClient->mount( $prefix, [ 'class' => $class, 'config' => $constructArg ] ); } return $vrsClient; }, /////////////////////////////////////////////////////////////////////////// // NOTE: When adding a service here, don't forget to add a getter function // in the MediaWikiServices class. The convenience getter should just call // $this->getService( 'FooBarService' ). /////////////////////////////////////////////////////////////////////////// ];