MediaWiki  fundraising/REL1_31
MediaWikiServices.php
Go to the documentation of this file.
1 <?php
2 namespace MediaWiki;
3 
6 use Config;
13 use Hooks;
36 use Parser;
51 
88 class MediaWikiServices extends ServiceContainer {
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 
135  public static function forceGlobalInstance( MediaWikiServices $services ) {
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 
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 
699  public function getWikiRevisionUploadImporter() {
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 }
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.
Definition: GenderCache.php:31
Accesses configuration settings from $GLOBALS.
Hooks class.
Definition: Hooks.php:34
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:203
Cache for article titles (prefixed DB keys) and ids linked from one source.
Definition: LinkCache.php:34
MediaWiki exception.
Definition: MWException.php:26
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.
The MediaWiki class is the helper class for the index.php entry point.
Definition: MediaWiki.php:34
Implements functions related to MIME types such as detection and mapping to file extension.
Functions to get cache objects.
Definition: ObjectCache.php:80
static clear()
Clear all the cached instances.
Configuration handling class for SearchEngine.
Factory class for SearchEngine.
Contain a class for special pages.
Factory class to create Skin objects.
Definition: SkinFactory.php:31
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
The MIT free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: LICENSE.txt:7
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.
Definition: TitleParser.php:33