MediaWiki REL1_31
MediaWikiServices.php
Go to the documentation of this file.
1<?php
2namespace MediaWiki;
3
34use MimeAnalyzer;
51
89
93 private static $instance = null;
94
109 public static function getInstance() {
110 if ( self::$instance === null ) {
111 // NOTE: constructing GlobalVarConfig here is not particularly pretty,
112 // but some information from the global scope has to be injected here,
113 // even if it's just a file name or database credentials to load
114 // configuration from.
115 $bootstrapConfig = new GlobalVarConfig();
116 self::$instance = self::newInstance( $bootstrapConfig, 'load' );
117 }
118
119 return self::$instance;
120 }
121
136 if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
137 throw new MWException( __METHOD__ . ' must not be used outside unit tests.' );
138 }
139
140 $old = self::getInstance();
141 self::$instance = $services;
142
143 return $old;
144 }
145
185 public static function resetGlobalInstance( Config $bootstrapConfig = null, $quick = '' ) {
186 if ( self::$instance === null ) {
187 // no global instance yet, nothing to reset
188 return;
189 }
190
191 self::failIfResetNotAllowed( __METHOD__ );
192
193 if ( $bootstrapConfig === null ) {
194 $bootstrapConfig = self::$instance->getBootstrapConfig();
195 }
196
197 $oldInstance = self::$instance;
198
199 self::$instance = self::newInstance( $bootstrapConfig, 'load' );
200 self::$instance->importWiring( $oldInstance, [ 'BootstrapConfig' ] );
201
202 if ( $quick === 'quick' ) {
203 self::$instance->salvage( $oldInstance );
204 } else {
205 $oldInstance->destroy();
206 }
207 }
208
216 private function salvage( self $other ) {
217 foreach ( $this->getServiceNames() as $name ) {
218 // The service could be new in the new instance and not registered in the
219 // other instance (e.g. an extension that was loaded after the instantiation of
220 // the other instance. Skip this service in this case. See T143974
221 try {
222 $oldService = $other->peekService( $name );
223 } catch ( NoSuchServiceException $e ) {
224 continue;
225 }
226
227 if ( $oldService instanceof SalvageableService ) {
229 $newService = $this->getService( $name );
230 $newService->salvage( $oldService );
231 }
232 }
233
234 $other->destroy();
235 }
236
252 private static function newInstance( Config $bootstrapConfig, $loadWiring = '' ) {
253 $instance = new self( $bootstrapConfig );
254
255 // Load the default wiring from the specified files.
256 if ( $loadWiring === 'load' ) {
257 $wiringFiles = $bootstrapConfig->get( 'ServiceWiringFiles' );
258 $instance->loadWiringFiles( $wiringFiles );
259 }
260
261 // Provide a traditional hook point to allow extensions to configure services.
262 Hooks::run( 'MediaWikiServices', [ $instance ] );
263
264 return $instance;
265 }
266
282 public static function disableStorageBackend() {
283 // TODO: also disable some Caches, JobQueues, etc
284 $destroy = [ 'DBLoadBalancer', 'DBLoadBalancerFactory' ];
285 $services = self::getInstance();
286
287 foreach ( $destroy as $name ) {
288 $services->disableService( $name );
289 }
290
291 ObjectCache::clear();
292 }
293
306 public static function resetChildProcessServices() {
307 // NOTE: for now, just reset everything. Since we don't know the interdependencies
308 // between services, we can't do this more selectively at this time.
309 self::resetGlobalInstance();
310
311 // Child, reseed because there is no bug in PHP:
312 // https://bugs.php.net/bug.php?id=42465
313 mt_srand( getmypid() );
314 }
315
337 public function resetServiceForTesting( $name, $destroy = true ) {
338 if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
339 throw new MWException( 'resetServiceForTesting() must not be used outside unit tests.' );
340 }
341
342 $this->resetService( $name, $destroy );
343 }
344
372 public static function failIfResetNotAllowed( $method ) {
373 if ( !defined( 'MW_PHPUNIT_TEST' )
374 && !defined( 'MW_PARSER_TEST' )
375 && !defined( 'MEDIAWIKI_INSTALL' )
376 && !defined( 'RUN_MAINTENANCE_IF_MAIN' )
377 && defined( 'MW_SERVICE_BOOTSTRAP_COMPLETE' )
378 ) {
379 throw new MWException( $method . ' may only be called during bootstrapping and unit tests!' );
380 }
381 }
382
388 public function __construct( Config $config ) {
389 parent::__construct();
390
391 // Register the given Config object as the bootstrap config service.
392 $this->defineService( 'BootstrapConfig', function () use ( $config ) {
393 return $config;
394 } );
395 }
396
397 // CONVENIENCE GETTERS ////////////////////////////////////////////////////
398
412 public function getBootstrapConfig() {
413 return $this->getService( 'BootstrapConfig' );
414 }
415
420 public function getConfigFactory() {
421 return $this->getService( 'ConfigFactory' );
422 }
423
431 public function getMainConfig() {
432 return $this->getService( 'MainConfig' );
433 }
434
439 public function getSiteLookup() {
440 return $this->getService( 'SiteLookup' );
441 }
442
447 public function getSiteStore() {
448 return $this->getService( 'SiteStore' );
449 }
450
455 public function getInterwikiLookup() {
456 return $this->getService( 'InterwikiLookup' );
457 }
458
463 public function getStatsdDataFactory() {
464 return $this->getService( 'StatsdDataFactory' );
465 }
466
471 public function getEventRelayerGroup() {
472 return $this->getService( 'EventRelayerGroup' );
473 }
474
479 public function newSearchEngine() {
480 // New engine object every time, since they keep state
481 return $this->getService( 'SearchEngineFactory' )->create();
482 }
483
488 public function getSearchEngineFactory() {
489 return $this->getService( 'SearchEngineFactory' );
490 }
491
496 public function getSearchEngineConfig() {
497 return $this->getService( 'SearchEngineConfig' );
498 }
499
504 public function getSkinFactory() {
505 return $this->getService( 'SkinFactory' );
506 }
507
512 public function getDBLoadBalancerFactory() {
513 return $this->getService( 'DBLoadBalancerFactory' );
514 }
515
520 public function getDBLoadBalancer() {
521 return $this->getService( 'DBLoadBalancer' );
522 }
523
528 public function getWatchedItemStore() {
529 return $this->getService( 'WatchedItemStore' );
530 }
531
536 public function getWatchedItemQueryService() {
537 return $this->getService( 'WatchedItemQueryService' );
538 }
539
544 public function getCryptRand() {
545 return $this->getService( 'CryptRand' );
546 }
547
552 public function getCryptHKDF() {
553 return $this->getService( 'CryptHKDF' );
554 }
555
560 public function getMediaHandlerFactory() {
561 return $this->getService( 'MediaHandlerFactory' );
562 }
563
568 public function getMimeAnalyzer() {
569 return $this->getService( 'MimeAnalyzer' );
570 }
571
576 public function getProxyLookup() {
577 return $this->getService( 'ProxyLookup' );
578 }
579
584 public function getParser() {
585 return $this->getService( 'Parser' );
586 }
587
592 public function getParserCache() {
593 return $this->getService( 'ParserCache' );
594 }
595
600 public function getGenderCache() {
601 return $this->getService( 'GenderCache' );
602 }
603
608 public function getLinkCache() {
609 return $this->getService( 'LinkCache' );
610 }
611
616 public function getLinkRendererFactory() {
617 return $this->getService( 'LinkRendererFactory' );
618 }
619
627 public function getLinkRenderer() {
628 return $this->getService( 'LinkRenderer' );
629 }
630
635 public function getTitleFormatter() {
636 return $this->getService( 'TitleFormatter' );
637 }
638
643 public function getTitleParser() {
644 return $this->getService( 'TitleParser' );
645 }
646
651 public function getMainObjectStash() {
652 return $this->getService( 'MainObjectStash' );
653 }
654
659 public function getMainWANObjectCache() {
660 return $this->getService( 'MainWANObjectCache' );
661 }
662
667 public function getLocalServerObjectCache() {
668 return $this->getService( 'LocalServerObjectCache' );
669 }
670
675 public function getVirtualRESTServiceClient() {
676 return $this->getService( 'VirtualRESTServiceClient' );
677 }
678
683 public function getConfiguredReadOnlyMode() {
684 return $this->getService( 'ConfiguredReadOnlyMode' );
685 }
686
691 public function getReadOnlyMode() {
692 return $this->getService( 'ReadOnlyMode' );
693 }
694
700 return $this->getService( 'UploadRevisionImporter' );
701 }
702
708 return $this->getService( 'OldRevisionImporter' );
709 }
710
716 return $this->getService( 'WikiRevisionOldRevisionImporterNoUpdates' );
717 }
718
723 public function getShellCommandFactory() {
724 return $this->getService( 'ShellCommandFactory' );
725 }
726
731 public function getExternalStoreFactory() {
732 return $this->getService( 'ExternalStoreFactory' );
733 }
734
739 public function getBlobStoreFactory() {
740 return $this->getService( 'BlobStoreFactory' );
741 }
742
747 public function getBlobStore() {
748 return $this->getService( '_SqlBlobStore' );
749 }
750
755 public function getRevisionStore() {
756 return $this->getService( 'RevisionStore' );
757 }
758
763 public function getRevisionLookup() {
764 return $this->getService( 'RevisionLookup' );
765 }
766
771 public function getRevisionFactory() {
772 return $this->getService( 'RevisionFactory' );
773 }
774
779 public function getContentModelStore() {
780 return $this->getService( 'ContentModelStore' );
781 }
782
787 public function getSlotRoleStore() {
788 return $this->getService( 'SlotRoleStore' );
789 }
790
795 public function getPreferencesFactory() {
796 return $this->getService( 'PreferencesFactory' );
797 }
798
803 public function getHttpRequestFactory() {
804 return $this->getService( 'HttpRequestFactory' );
805 }
806
811 public function getCommentStore() {
812 return $this->getService( 'CommentStore' );
813 }
814
819 public function getActorMigration() {
820 return $this->getService( 'ActorMigration' );
821 }
822
824 // NOTE: When adding a service getter here, don't forget to add a test
825 // case for it in MediaWikiServicesTest::provideGetters() and in
826 // MediaWikiServicesTest::provideGetService()!
828
829}
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
This class handles the logic for the actor table migration.
CommentStore handles storage of comments (edit summaries, log reasons, etc) in the database.
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 creating MWHttpRequest 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.
Service for instantiating BlobStores.
Service for looking up page revisions.
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.
An interface for generating database load balancers.
Definition LBFactory.php:39
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:2273
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:2176
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.
A PreferencesFactory is a MediaWiki service that provides the definitions of preferences for a given ...
SalvageableService defines an interface for services that are able to salvage state from a previous i...
Service for loading and storing data blobs.
Definition BlobStore.php:33
Service for constructing revision objects.
Service for looking up page revisions.
A title formatter service for MediaWiki.
A title parser service for MediaWiki.
A helper class for throttling authentication attempts.