MediaWiki  master
MediaWikiServices.php
Go to the documentation of this file.
1 <?php
2 namespace MediaWiki;
3 
4 use Config;
9 use Hooks;
12 use Liuggio\StatsdClient\Factory\StatsdDataFactory;
31 
68 class MediaWikiServices extends ServiceContainer {
69 
73  private static $instance = null;
74 
89  public static function getInstance() {
90  if ( self::$instance === null ) {
91  // NOTE: constructing GlobalVarConfig here is not particularly pretty,
92  // but some information from the global scope has to be injected here,
93  // even if it's just a file name or database credentials to load
94  // configuration from.
95  $bootstrapConfig = new GlobalVarConfig();
96  self::$instance = self::newInstance( $bootstrapConfig, 'load' );
97  }
98 
99  return self::$instance;
100  }
101 
115  public static function forceGlobalInstance( MediaWikiServices $services ) {
116  if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
117  throw new MWException( __METHOD__ . ' must not be used outside unit tests.' );
118  }
119 
120  $old = self::getInstance();
121  self::$instance = $services;
122 
123  return $old;
124  }
125 
165  public static function resetGlobalInstance( Config $bootstrapConfig = null, $quick = '' ) {
166  if ( self::$instance === null ) {
167  // no global instance yet, nothing to reset
168  return;
169  }
170 
171  self::failIfResetNotAllowed( __METHOD__ );
172 
173  if ( $bootstrapConfig === null ) {
174  $bootstrapConfig = self::$instance->getBootstrapConfig();
175  }
176 
177  $oldInstance = self::$instance;
178 
179  self::$instance = self::newInstance( $bootstrapConfig );
180  self::$instance->importWiring( $oldInstance, [ 'BootstrapConfig' ] );
181 
182  if ( $quick === 'quick' ) {
183  self::$instance->salvage( $oldInstance );
184  } else {
185  $oldInstance->destroy();
186  }
187 
188  }
189 
197  private function salvage( self $other ) {
198  foreach ( $this->getServiceNames() as $name ) {
199  $oldService = $other->peekService( $name );
200 
201  if ( $oldService instanceof SalvageableService ) {
203  $newService = $this->getService( $name );
204  $newService->salvage( $oldService );
205  }
206  }
207 
208  $other->destroy();
209  }
210 
226  private static function newInstance( Config $bootstrapConfig, $loadWiring = '' ) {
227  $instance = new self( $bootstrapConfig );
228 
229  // Load the default wiring from the specified files.
230  if ( $loadWiring === 'load' ) {
231  $wiringFiles = $bootstrapConfig->get( 'ServiceWiringFiles' );
232  $instance->loadWiringFiles( $wiringFiles );
233  }
234 
235  // Provide a traditional hook point to allow extensions to configure services.
236  Hooks::run( 'MediaWikiServices', [ $instance ] );
237 
238  return $instance;
239  }
240 
256  public static function disableStorageBackend() {
257  // TODO: also disable some Caches, JobQueues, etc
258  $destroy = [ 'DBLoadBalancer', 'DBLoadBalancerFactory' ];
259  $services = self::getInstance();
260 
261  foreach ( $destroy as $name ) {
262  $services->disableService( $name );
263  }
264 
266  }
267 
280  public static function resetChildProcessServices() {
281  // NOTE: for now, just reset everything. Since we don't know the interdependencies
282  // between services, we can't do this more selectively at this time.
283  self::resetGlobalInstance();
284 
285  // Child, reseed because there is no bug in PHP:
286  // http://bugs.php.net/bug.php?id=42465
287  mt_srand( getmypid() );
288  }
289 
311  public function resetServiceForTesting( $name, $destroy = true ) {
312  if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
313  throw new MWException( 'resetServiceForTesting() must not be used outside unit tests.' );
314  }
315 
316  $this->resetService( $name, $destroy );
317  }
318 
346  public static function failIfResetNotAllowed( $method ) {
347  if ( !defined( 'MW_PHPUNIT_TEST' )
348  && !defined( 'MW_PARSER_TEST' )
349  && !defined( 'MEDIAWIKI_INSTALL' )
350  && !defined( 'RUN_MAINTENANCE_IF_MAIN' )
351  && defined( 'MW_SERVICE_BOOTSTRAP_COMPLETE' )
352  ) {
353  throw new MWException( $method . ' may only be called during bootstrapping and unit tests!' );
354  }
355  }
356 
362  public function __construct( Config $config ) {
363  parent::__construct();
364 
365  // Register the given Config object as the bootstrap config service.
366  $this->defineService( 'BootstrapConfig', function() use ( $config ) {
367  return $config;
368  } );
369  }
370 
371  // CONVENIENCE GETTERS ////////////////////////////////////////////////////
372 
386  public function getBootstrapConfig() {
387  return $this->getService( 'BootstrapConfig' );
388  }
389 
394  public function getConfigFactory() {
395  return $this->getService( 'ConfigFactory' );
396  }
397 
405  public function getMainConfig() {
406  return $this->getService( 'MainConfig' );
407  }
408 
413  public function getSiteLookup() {
414  return $this->getService( 'SiteLookup' );
415  }
416 
421  public function getSiteStore() {
422  return $this->getService( 'SiteStore' );
423  }
424 
429  public function getInterwikiLookup() {
430  return $this->getService( 'InterwikiLookup' );
431  }
432 
437  public function getStatsdDataFactory() {
438  return $this->getService( 'StatsdDataFactory' );
439  }
440 
445  public function getEventRelayerGroup() {
446  return $this->getService( 'EventRelayerGroup' );
447  }
448 
453  public function newSearchEngine() {
454  // New engine object every time, since they keep state
455  return $this->getService( 'SearchEngineFactory' )->create();
456  }
457 
462  public function getSearchEngineFactory() {
463  return $this->getService( 'SearchEngineFactory' );
464  }
465 
470  public function getSearchEngineConfig() {
471  return $this->getService( 'SearchEngineConfig' );
472  }
473 
478  public function getSkinFactory() {
479  return $this->getService( 'SkinFactory' );
480  }
481 
486  public function getDBLoadBalancerFactory() {
487  return $this->getService( 'DBLoadBalancerFactory' );
488  }
489 
494  public function getDBLoadBalancer() {
495  return $this->getService( 'DBLoadBalancer' );
496  }
497 
502  public function getWatchedItemStore() {
503  return $this->getService( 'WatchedItemStore' );
504  }
505 
510  public function getWatchedItemQueryService() {
511  return $this->getService( 'WatchedItemQueryService' );
512  }
513 
518  public function getGenderCache() {
519  return $this->getService( 'GenderCache' );
520  }
521 
526  public function getLinkCache() {
527  return $this->getService( 'LinkCache' );
528  }
529 
534  public function getLinkRendererFactory() {
535  return $this->getService( 'LinkRendererFactory' );
536  }
537 
545  public function getLinkRenderer() {
546  return $this->getService( 'LinkRenderer' );
547  }
548 
553  public function getTitleFormatter() {
554  return $this->getService( 'TitleFormatter' );
555  }
556 
561  public function getTitleParser() {
562  return $this->getService( 'TitleParser' );
563  }
564 
566  // NOTE: When adding a service getter here, don't forget to add a test
567  // case for it in MediaWikiServicesTest::provideGetters() and in
568  // MediaWikiServicesTest::provideGetService()!
570 
571 }
Factory class to create Skin objects.
Definition: SkinFactory.php:31
Factory class to create Config objects.
getLinkRenderer()
LinkRenderer instance that can be used if no custom options are needed.
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
salvage(self $other)
Salvages the state of any salvageable service instances in $other.
ServiceContainer provides a generic service to manage named services using lazy instantiation based o...
The MediaWiki class is the helper class for the index.php entry point.
Definition: MediaWiki.php:28
Hooks class.
Definition: Hooks.php:34
Configuration handling class for SearchEngine.
static getInstance()
Returns the global default instance of the top level service locator.
get($name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
Storage layer class for WatchedItems.
Factory class for spawning EventRelayer objects using configuration.
Accesses configuration settings from $GLOBALS.
Database load balancing object.
resetServiceForTesting($name, $destroy=true)
Resets the given service for testing purposes.
Class that generates HTML links for pages.
Interface for configuration instances.
Definition: Config.php:28
An interface for generating database load balancers.
Definition: LBFactory.php:33
getMainConfig()
Returns the Config object that provides configuration for MediaWiki core.
static resetChildProcessServices()
Resets any services that may have become stale after a child process returns from after pcntl_fork()...
A title parser service for MediaWiki.
Definition: TitleParser.php:34
static disableStorageBackend()
Disables all storage layer services.
MediaWiki exception.
Definition: MWException.php:26
static run($event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:131
static resetGlobalInstance(Config $bootstrapConfig=null, $quick= '')
Creates a new instance of MediaWikiServices and sets it as the global default instance.
Service interface for looking up Interwiki records.
static configuration should be added through ResourceLoaderGetConfigVars instead can be used to get the real title after the basic globals have been set but before ordinary actions take place or wrap services the preferred way to define a new service is the $wgServiceWiringFiles array $services
Definition: hooks.txt:2044
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
Factory class for SearchEngine.
static failIfResetNotAllowed($method)
Convenience method that throws an exception unless it is called during a phase in which resetting of ...
Caches user genders when needed to use correct namespace aliases.
Definition: GenderCache.php:31
A title formatter service for MediaWiki.
Cache for article titles (prefixed DB keys) and ids linked from one source.
Definition: LinkCache.php:31
Contain a class for special pages.
Factory to create LinkRender objects.
static newInstance(Config $bootstrapConfig, $loadWiring= '')
Creates a new MediaWikiServices instance and initializes it according to the given $bootstrapConfig...
getBootstrapConfig()
Returns the Config object containing the bootstrap configuration.
static clear()
Clear all the cached instances.
SalvageableService defines an interface for services that are able to salvage state from a previous i...
MediaWikiServices is the service locator for the application scope of MediaWiki.
Functions to get cache objects.
Definition: ObjectCache.php:81
static forceGlobalInstance(MediaWikiServices $services)
Replaces the global MediaWikiServices instance.
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:310