MediaWiki REL1_30
MediaWikiServices.php
Go to the documentation of this file.
1<?php
2namespace MediaWiki;
3
24use MimeAnalyzer;
41
79
83 private static $instance = null;
84
99 public static function getInstance() {
100 if ( self::$instance === null ) {
101 // NOTE: constructing GlobalVarConfig here is not particularly pretty,
102 // but some information from the global scope has to be injected here,
103 // even if it's just a file name or database credentials to load
104 // configuration from.
105 $bootstrapConfig = new GlobalVarConfig();
106 self::$instance = self::newInstance( $bootstrapConfig, 'load' );
107 }
108
109 return self::$instance;
110 }
111
126 if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
127 throw new MWException( __METHOD__ . ' must not be used outside unit tests.' );
128 }
129
130 $old = self::getInstance();
131 self::$instance = $services;
132
133 return $old;
134 }
135
175 public static function resetGlobalInstance( Config $bootstrapConfig = null, $quick = '' ) {
176 if ( self::$instance === null ) {
177 // no global instance yet, nothing to reset
178 return;
179 }
180
181 self::failIfResetNotAllowed( __METHOD__ );
182
183 if ( $bootstrapConfig === null ) {
184 $bootstrapConfig = self::$instance->getBootstrapConfig();
185 }
186
187 $oldInstance = self::$instance;
188
189 self::$instance = self::newInstance( $bootstrapConfig, 'load' );
190 self::$instance->importWiring( $oldInstance, [ 'BootstrapConfig' ] );
191
192 if ( $quick === 'quick' ) {
193 self::$instance->salvage( $oldInstance );
194 } else {
195 $oldInstance->destroy();
196 }
197 }
198
206 private function salvage( self $other ) {
207 foreach ( $this->getServiceNames() as $name ) {
208 // The service could be new in the new instance and not registered in the
209 // other instance (e.g. an extension that was loaded after the instantiation of
210 // the other instance. Skip this service in this case. See T143974
211 try {
212 $oldService = $other->peekService( $name );
213 } catch ( NoSuchServiceException $e ) {
214 continue;
215 }
216
217 if ( $oldService instanceof SalvageableService ) {
219 $newService = $this->getService( $name );
220 $newService->salvage( $oldService );
221 }
222 }
223
224 $other->destroy();
225 }
226
242 private static function newInstance( Config $bootstrapConfig, $loadWiring = '' ) {
243 $instance = new self( $bootstrapConfig );
244
245 // Load the default wiring from the specified files.
246 if ( $loadWiring === 'load' ) {
247 $wiringFiles = $bootstrapConfig->get( 'ServiceWiringFiles' );
248 $instance->loadWiringFiles( $wiringFiles );
249 }
250
251 // Provide a traditional hook point to allow extensions to configure services.
252 Hooks::run( 'MediaWikiServices', [ $instance ] );
253
254 return $instance;
255 }
256
272 public static function disableStorageBackend() {
273 // TODO: also disable some Caches, JobQueues, etc
274 $destroy = [ 'DBLoadBalancer', 'DBLoadBalancerFactory' ];
275 $services = self::getInstance();
276
277 foreach ( $destroy as $name ) {
278 $services->disableService( $name );
279 }
280
281 ObjectCache::clear();
282 }
283
296 public static function resetChildProcessServices() {
297 // NOTE: for now, just reset everything. Since we don't know the interdependencies
298 // between services, we can't do this more selectively at this time.
299 self::resetGlobalInstance();
300
301 // Child, reseed because there is no bug in PHP:
302 // https://bugs.php.net/bug.php?id=42465
303 mt_srand( getmypid() );
304 }
305
327 public function resetServiceForTesting( $name, $destroy = true ) {
328 if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
329 throw new MWException( 'resetServiceForTesting() must not be used outside unit tests.' );
330 }
331
332 $this->resetService( $name, $destroy );
333 }
334
362 public static function failIfResetNotAllowed( $method ) {
363 if ( !defined( 'MW_PHPUNIT_TEST' )
364 && !defined( 'MW_PARSER_TEST' )
365 && !defined( 'MEDIAWIKI_INSTALL' )
366 && !defined( 'RUN_MAINTENANCE_IF_MAIN' )
367 && defined( 'MW_SERVICE_BOOTSTRAP_COMPLETE' )
368 ) {
369 throw new MWException( $method . ' may only be called during bootstrapping and unit tests!' );
370 }
371 }
372
378 public function __construct( Config $config ) {
379 parent::__construct();
380
381 // Register the given Config object as the bootstrap config service.
382 $this->defineService( 'BootstrapConfig', function () use ( $config ) {
383 return $config;
384 } );
385 }
386
387 // CONVENIENCE GETTERS ////////////////////////////////////////////////////
388
402 public function getBootstrapConfig() {
403 return $this->getService( 'BootstrapConfig' );
404 }
405
410 public function getConfigFactory() {
411 return $this->getService( 'ConfigFactory' );
412 }
413
421 public function getMainConfig() {
422 return $this->getService( 'MainConfig' );
423 }
424
429 public function getSiteLookup() {
430 return $this->getService( 'SiteLookup' );
431 }
432
437 public function getSiteStore() {
438 return $this->getService( 'SiteStore' );
439 }
440
445 public function getInterwikiLookup() {
446 return $this->getService( 'InterwikiLookup' );
447 }
448
453 public function getStatsdDataFactory() {
454 return $this->getService( 'StatsdDataFactory' );
455 }
456
461 public function getEventRelayerGroup() {
462 return $this->getService( 'EventRelayerGroup' );
463 }
464
469 public function newSearchEngine() {
470 // New engine object every time, since they keep state
471 return $this->getService( 'SearchEngineFactory' )->create();
472 }
473
478 public function getSearchEngineFactory() {
479 return $this->getService( 'SearchEngineFactory' );
480 }
481
486 public function getSearchEngineConfig() {
487 return $this->getService( 'SearchEngineConfig' );
488 }
489
494 public function getSkinFactory() {
495 return $this->getService( 'SkinFactory' );
496 }
497
502 public function getDBLoadBalancerFactory() {
503 return $this->getService( 'DBLoadBalancerFactory' );
504 }
505
510 public function getDBLoadBalancer() {
511 return $this->getService( 'DBLoadBalancer' );
512 }
513
518 public function getWatchedItemStore() {
519 return $this->getService( 'WatchedItemStore' );
520 }
521
526 public function getWatchedItemQueryService() {
527 return $this->getService( 'WatchedItemQueryService' );
528 }
529
534 public function getCryptRand() {
535 return $this->getService( 'CryptRand' );
536 }
537
542 public function getCryptHKDF() {
543 return $this->getService( 'CryptHKDF' );
544 }
545
550 public function getMediaHandlerFactory() {
551 return $this->getService( 'MediaHandlerFactory' );
552 }
553
558 public function getMimeAnalyzer() {
559 return $this->getService( 'MimeAnalyzer' );
560 }
561
566 public function getProxyLookup() {
567 return $this->getService( 'ProxyLookup' );
568 }
569
574 public function getParser() {
575 return $this->getService( 'Parser' );
576 }
577
582 public function getParserCache() {
583 return $this->getService( 'ParserCache' );
584 }
585
590 public function getGenderCache() {
591 return $this->getService( 'GenderCache' );
592 }
593
598 public function getLinkCache() {
599 return $this->getService( 'LinkCache' );
600 }
601
606 public function getLinkRendererFactory() {
607 return $this->getService( 'LinkRendererFactory' );
608 }
609
617 public function getLinkRenderer() {
618 return $this->getService( 'LinkRenderer' );
619 }
620
625 public function getTitleFormatter() {
626 return $this->getService( 'TitleFormatter' );
627 }
628
633 public function getTitleParser() {
634 return $this->getService( 'TitleParser' );
635 }
636
641 public function getMainObjectStash() {
642 return $this->getService( 'MainObjectStash' );
643 }
644
649 public function getMainWANObjectCache() {
650 return $this->getService( 'MainWANObjectCache' );
651 }
652
657 public function getLocalServerObjectCache() {
658 return $this->getService( 'LocalServerObjectCache' );
659 }
660
665 public function getVirtualRESTServiceClient() {
666 return $this->getService( 'VirtualRESTServiceClient' );
667 }
668
673 public function getConfiguredReadOnlyMode() {
674 return $this->getService( 'ConfiguredReadOnlyMode' );
675 }
676
681 public function getReadOnlyMode() {
682 return $this->getService( 'ReadOnlyMode' );
683 }
684
689 public function getShellCommandFactory() {
690 return $this->getService( 'ShellCommandFactory' );
691 }
692
694 // NOTE: When adding a service getter here, don't forget to add a test
695 // case for it in MediaWikiServicesTest::provideGetters() and in
696 // MediaWikiServicesTest::provideGetService()!
698
699}
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
Factory class to create Config objects.
Factory class for spawning EventRelayer objects using configuration.
Caches user genders when needed to use correct namespace aliases.
Accesses configuration settings from $GLOBALS.
Hooks class.
Definition Hooks.php:34
Cache for article titles (prefixed DB keys) and ids linked from one source.
Definition LinkCache.php:34
MediaWiki exception.
Class to construct MediaHandler objects.
Factory to create LinkRender objects.
Class that generates HTML links for pages.
MediaWikiServices is the service locator for the application scope of MediaWiki.
static disableStorageBackend()
Disables all storage layer services.
getMainConfig()
Returns the Config object that provides configuration for MediaWiki core.
salvage(self $other)
Salvages the state of any salvageable service instances in $other.
getLinkRenderer()
LinkRenderer instance that can be used if no custom options are needed.
static failIfResetNotAllowed( $method)
Convenience method that throws an exception unless it is called during a phase in which resetting of ...
getBootstrapConfig()
Returns the Config object containing the bootstrap configuration.
static resetChildProcessServices()
Resets any services that may have become stale after a child process returns from after pcntl_fork().
static newInstance(Config $bootstrapConfig, $loadWiring='')
Creates a new MediaWikiServices instance and initializes it according to the given $bootstrapConfig.
static forceGlobalInstance(MediaWikiServices $services)
Replaces the global MediaWikiServices instance.
static resetGlobalInstance(Config $bootstrapConfig=null, $quick='')
Creates a new instance of MediaWikiServices and sets it as the global default instance.
resetServiceForTesting( $name, $destroy=true)
Resets the given service for testing purposes.
static getInstance()
Returns the global default instance of the top level service locator.
Exception thrown when the requested service is not known.
ServiceContainer provides a generic service to manage named services using lazy instantiation based o...
Factory facilitating dependency injection for Command.
Functions to get cache objects.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:70
Configuration handling class for SearchEngine.
Factory class for SearchEngine.
Contain a class for special pages.
Factory class to create Skin objects.
Virtual HTTP service client loosely styled after a Virtual File System.
Storage layer class for WatchedItems.
An interface for generating database load balancers.
Definition LBFactory.php:38
Database connection, tracking, load balancing, and transaction manager for a cluster.
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
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:2243
Allows to change the fields on the form that will be generated $name
Definition hooks.txt:302
returning false will NOT prevent logging $e
Definition hooks.txt:2146
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:37
Interface for configuration instances.
Definition Config.php:28
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
MediaWiki adaptation of StatsdDataFactory that provides buffering functionality.
Service interface for looking up Interwiki records.
SalvageableService defines an interface for services that are able to salvage state from a previous i...
A title formatter service for MediaWiki.
A title parser service for MediaWiki.
A helper class for throttling authentication attempts.