Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
88.58% covered (warning)
88.58%
287 / 324
93.24% covered (success)
93.24%
207 / 222
CRAP
0.00% covered (danger)
0.00%
0 / 1
MediaWikiServices
88.58% covered (warning)
88.58%
287 / 324
93.24% covered (success)
93.24%
207 / 222
337.86
0.00% covered (danger)
0.00%
0 / 1
 allowGlobalInstance
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 disallowGlobalInstanceInUnitTests
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 allowGlobalInstanceAfterUnitTests
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 hasInstance
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getInstance
30.00% covered (danger)
30.00%
3 / 10
0.00% covered (danger)
0.00%
0 / 1
9.49
 getService
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
 forceGlobalInstance
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
3.07
 resetGlobalInstance
93.33% covered (success)
93.33%
14 / 15
0.00% covered (danger)
0.00%
0 / 1
4.00
 salvage
75.00% covered (warning)
75.00%
6 / 8
0.00% covered (danger)
0.00%
0 / 1
4.25
 newInstance
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 disableStorageBackend
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 disableStorage
79.07% covered (warning)
79.07%
34 / 43
0.00% covered (danger)
0.00%
0 / 1
2.04
 isStorageDisabled
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 resetChildProcessServices
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 resetServiceForTesting
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
3.33
 failIfResetNotAllowed
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
6.17
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getActionFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getActorMigration
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getActorNormalization
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getActorStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getActorStoreFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getArchivedRevisionLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAuthManager
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAutoblockExemptionList
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBacklinkCacheFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBadFileLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBlobStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBlobStoreFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBlockActionInfo
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBlockErrorFormatter
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getBlockManager
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBlockPermissionCheckerFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBlockRestrictionStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBlockRestrictionStoreFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBlockUserFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBlockUtils
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBlockUtilsFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBootstrapConfig
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getBotPasswordStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCentralIdLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCentralIdLookupFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getChangeTagDefStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getChangeTagsStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getChronologyProtector
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCollationFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCommentFormatter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCommentParserFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCommentStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getConfigFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getConfigRepository
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getConfigSchema
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getConfiguredReadOnlyMode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getConnectionProvider
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getContentHandlerFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getContentLanguage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getContentLanguageCode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getContentModelChangeFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getContentModelStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getContentRenderer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getContentTransformer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCriticalSectionProvider
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDatabaseBlockStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDatabaseBlockStoreFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDatabaseFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDateFormatterFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDBLoadBalancer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDBLoadBalancerFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDBLoadBalancerFactoryConfigBuilder
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDefaultOutputPipeline
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDeletePageFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDomainEventDispatcher
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDomainEventSource
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEmailer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEmailUserFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEventRelayerGroup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getExtensionRegistry
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getExternalStoreAccess
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getExternalStoreFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFileBackendGroup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFormatterFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGenderCache
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGlobalIdGenerator
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGrantsInfo
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGrantsLocalization
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGroupPermissionsLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHideUserUtils
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHookContainer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHtmlCacheUpdater
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHtmlTransformFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHttpRequestFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getInterwikiLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIntroMessageBuilder
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getJobFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getJobQueueGroup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getJobQueueGroupFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getJobRunner
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getJsonCodec
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLanguageConverterFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLanguageFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLanguageFallback
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLanguageNameUtils
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLinkBatchFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLinkCache
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLinkRenderer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLinkRendererFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLinksMigration
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLinkTargetLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLintErrorChecker
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLocalisationCache
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLocalServerObjectCache
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLockManagerGroupFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLogFormatterFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMagicWordFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMainConfig
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMainObjectStash
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMainWANObjectCache
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMediaHandlerFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMergeHistoryFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMessageCache
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMessageFormatterFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMicroStash
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMimeAnalyzer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMovePageFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getNamespaceInfo
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getNameTableStoreFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getObjectCacheFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getObjectFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getOldRevisionImporter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPageEditStash
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPageProps
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPageRestHelperFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPageStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPageStoreFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPageUpdaterFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getParser
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getParserCache
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getParserCacheFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getParserFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getParserOutputAccess
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getParsoidDataAccess
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getParsoidOutputStash
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getParsoidPageConfigFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getParsoidParserFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getParsoidSiteConfig
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPasswordFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPasswordReset
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPerDbNameStatsdDataFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPermissionManager
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPingback
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPoolCounterFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPreferencesFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPreloadedContentBuilder
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getProxyLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRateLimiter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getReadOnlyMode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRedirectLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRedirectStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRepoGroup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getResourceLoader
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRestrictionStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRevertedTagUpdateManager
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRevisionFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRevisionLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRevisionRenderer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRevisionStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRevisionStoreFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRollbackPageFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRowCommentFormatter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 newSearchEngine
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSearchEngineConfig
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSearchEngineFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSearchResultThumbnailProvider
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getShellboxClientFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getShellCommandFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSignatureValidatorFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSiteLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSiteStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSkinFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSlotRoleRegistry
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSlotRoleStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSpamChecker
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSpecialPageFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStatsdDataFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStatsFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTalkPageNotificationManager
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTempFSFileFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTempUserConfig
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTempUserCreator
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTidy
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTitleFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTitleFormatter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTitleMatcher
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTitleParser
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTracer
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTrackingCategories
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUnblockUserFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUndeletePageFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUploadRevisionImporter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUrlUtils
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserCache
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserEditTracker
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserGroupManager
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserGroupManagerFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserIdentityLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserIdentityUtils
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserNamePrefixSearch
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserNameUtils
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserOptionsLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserOptionsManager
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserRegistrationLookup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWatchedItemQueryService
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWatchedItemStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWatchlistManager
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWikiExporterFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWikiImporterFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWikiPageFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWikiRevisionOldRevisionImporter
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getWikiRevisionOldRevisionImporterNoUpdates
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWikiRevisionUploadImporter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWRStatsFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21namespace MediaWiki;
22
23use ExternalStoreAccess;
24use ExternalStoreFactory;
25use JobQueueGroup;
26use JobRunner;
27use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
28use LocalisationCache;
29use LogFormatterFactory;
30use LogicException;
31use MediaHandlerFactory;
32use MediaWiki\Actions\ActionFactory;
33use MediaWiki\Auth\AuthManager;
34use MediaWiki\Block\AutoblockExemptionList;
35use MediaWiki\Block\BlockActionInfo;
36use MediaWiki\Block\BlockErrorFormatter;
37use MediaWiki\Block\BlockManager;
38use MediaWiki\Block\BlockPermissionCheckerFactory;
39use MediaWiki\Block\BlockRestrictionStore;
40use MediaWiki\Block\BlockRestrictionStoreFactory;
41use MediaWiki\Block\BlockUserFactory;
42use MediaWiki\Block\BlockUtils;
43use MediaWiki\Block\BlockUtilsFactory;
44use MediaWiki\Block\DatabaseBlockStore;
45use MediaWiki\Block\DatabaseBlockStoreFactory;
46use MediaWiki\Block\HideUserUtils;
47use MediaWiki\Block\UnblockUserFactory;
48use MediaWiki\Cache\BacklinkCacheFactory;
49use MediaWiki\Cache\GenderCache;
50use MediaWiki\Cache\HTMLCacheUpdater;
51use MediaWiki\Cache\LinkBatchFactory;
52use MediaWiki\Cache\LinkCache;
53use MediaWiki\Cache\UserCache;
54use MediaWiki\Category\TrackingCategories;
55use MediaWiki\ChangeTags\ChangeTagsStore;
56use MediaWiki\Collation\CollationFactory;
57use MediaWiki\CommentFormatter\CommentFormatter;
58use MediaWiki\CommentFormatter\CommentParserFactory;
59use MediaWiki\CommentFormatter\RowCommentFormatter;
60use MediaWiki\CommentStore\CommentStore;
61use MediaWiki\Config\Config;
62use MediaWiki\Config\ConfigFactory;
63use MediaWiki\Config\ConfigRepository;
64use MediaWiki\Config\GlobalVarConfig;
65use MediaWiki\Content\IContentHandlerFactory;
66use MediaWiki\Content\Renderer\ContentRenderer;
67use MediaWiki\Content\Transform\ContentTransformer;
68use MediaWiki\DomainEvent\DomainEventDispatcher;
69use MediaWiki\DomainEvent\DomainEventSource;
70use MediaWiki\Edit\ParsoidOutputStash;
71use MediaWiki\EditPage\IntroMessageBuilder;
72use MediaWiki\EditPage\PreloadedContentBuilder;
73use MediaWiki\EditPage\SpamChecker;
74use MediaWiki\Export\WikiExporterFactory;
75use MediaWiki\FileBackend\FileBackendGroup;
76use MediaWiki\FileBackend\FSFile\TempFSFileFactory;
77use MediaWiki\FileBackend\LockManager\LockManagerGroupFactory;
78use MediaWiki\HookContainer\HookContainer;
79use MediaWiki\HookContainer\HookRunner;
80use MediaWiki\Http\HttpRequestFactory;
81use MediaWiki\Installer\Pingback;
82use MediaWiki\Interwiki\InterwikiLookup;
83use MediaWiki\Interwiki\NullInterwikiLookup;
84use MediaWiki\JobQueue\JobFactory;
85use MediaWiki\JobQueue\JobQueueGroupFactory;
86use MediaWiki\Json\JsonCodec;
87use MediaWiki\Language\FormatterFactory;
88use MediaWiki\Language\Language;
89use MediaWiki\Language\LanguageCode;
90use MediaWiki\Languages\LanguageConverterFactory;
91use MediaWiki\Languages\LanguageFactory;
92use MediaWiki\Languages\LanguageFallback;
93use MediaWiki\Languages\LanguageNameUtils;
94use MediaWiki\Linker\LinkRenderer;
95use MediaWiki\Linker\LinkRendererFactory;
96use MediaWiki\Linker\LinksMigration;
97use MediaWiki\Linker\LinkTargetLookup;
98use MediaWiki\Mail\EmailUserFactory;
99use MediaWiki\Mail\IEmailer;
100use MediaWiki\OutputTransform\OutputTransformPipeline;
101use MediaWiki\Page\ContentModelChangeFactory;
102use MediaWiki\Page\DeletePageFactory;
103use MediaWiki\Page\File\BadFileLookup;
104use MediaWiki\Page\MergeHistoryFactory;
105use MediaWiki\Page\MovePageFactory;
106use MediaWiki\Page\PageProps;
107use MediaWiki\Page\PageStore;
108use MediaWiki\Page\PageStoreFactory;
109use MediaWiki\Page\ParserOutputAccess;
110use MediaWiki\Page\RedirectLookup;
111use MediaWiki\Page\RedirectStore;
112use MediaWiki\Page\RollbackPageFactory;
113use MediaWiki\Page\UndeletePageFactory;
114use MediaWiki\Page\WikiPageFactory;
115use MediaWiki\Parser\DateFormatterFactory;
116use MediaWiki\Parser\MagicWordFactory;
117use MediaWiki\Parser\Parser;
118use MediaWiki\Parser\ParserCache;
119use MediaWiki\Parser\ParserCacheFactory;
120use MediaWiki\Parser\ParserFactory;
121use MediaWiki\Parser\Parsoid\Config\PageConfigFactory;
122use MediaWiki\Parser\Parsoid\Config\SiteConfig;
123use MediaWiki\Parser\Parsoid\HtmlTransformFactory;
124use MediaWiki\Parser\Parsoid\LintErrorChecker;
125use MediaWiki\Parser\Parsoid\ParsoidParserFactory;
126use MediaWiki\Password\PasswordFactory;
127use MediaWiki\Permissions\GrantsInfo;
128use MediaWiki\Permissions\GrantsLocalization;
129use MediaWiki\Permissions\GroupPermissionsLookup;
130use MediaWiki\Permissions\PermissionManager;
131use MediaWiki\Permissions\RateLimiter;
132use MediaWiki\Permissions\RestrictionStore;
133use MediaWiki\PoolCounter\PoolCounterFactory;
134use MediaWiki\Preferences\PreferencesFactory;
135use MediaWiki\Preferences\SignatureValidatorFactory;
136use MediaWiki\Registration\ExtensionRegistry;
137use MediaWiki\Request\ProxyLookup;
138use MediaWiki\ResourceLoader\ResourceLoader;
139use MediaWiki\Rest\Handler\Helper\PageRestHelperFactory;
140use MediaWiki\Revision\ArchivedRevisionLookup;
141use MediaWiki\Revision\RevisionFactory;
142use MediaWiki\Revision\RevisionLookup;
143use MediaWiki\Revision\RevisionRenderer;
144use MediaWiki\Revision\RevisionStore;
145use MediaWiki\Revision\RevisionStoreFactory;
146use MediaWiki\Revision\SlotRoleRegistry;
147use MediaWiki\Search\SearchResultThumbnailProvider;
148use MediaWiki\Search\TitleMatcher;
149use MediaWiki\Settings\Config\ConfigSchema;
150use MediaWiki\Shell\CommandFactory;
151use MediaWiki\Shell\ShellboxClientFactory;
152use MediaWiki\Site\SiteLookup;
153use MediaWiki\Site\SiteStore;
154use MediaWiki\SpecialPage\SpecialPageFactory;
155use MediaWiki\Storage\BlobStore;
156use MediaWiki\Storage\BlobStoreFactory;
157use MediaWiki\Storage\NameTableStore;
158use MediaWiki\Storage\NameTableStoreFactory;
159use MediaWiki\Storage\PageEditStash;
160use MediaWiki\Storage\PageUpdaterFactory;
161use MediaWiki\Storage\RevertedTagUpdateManager;
162use MediaWiki\Tidy\TidyDriverBase;
163use MediaWiki\Title\NamespaceInfo;
164use MediaWiki\Title\TitleFactory;
165use MediaWiki\Title\TitleFormatter;
166use MediaWiki\Title\TitleParser;
167use MediaWiki\User\ActorMigration;
168use MediaWiki\User\ActorNormalization;
169use MediaWiki\User\ActorStore;
170use MediaWiki\User\ActorStoreFactory;
171use MediaWiki\User\BotPasswordStore;
172use MediaWiki\User\CentralId\CentralIdLookup;
173use MediaWiki\User\CentralId\CentralIdLookupFactory;
174use MediaWiki\User\Options\StaticUserOptionsLookup;
175use MediaWiki\User\Options\UserOptionsLookup;
176use MediaWiki\User\Options\UserOptionsManager;
177use MediaWiki\User\PasswordReset;
178use MediaWiki\User\Registration\UserRegistrationLookup;
179use MediaWiki\User\TalkPageNotificationManager;
180use MediaWiki\User\TempUser\RealTempUserConfig;
181use MediaWiki\User\TempUser\TempUserCreator;
182use MediaWiki\User\UserEditTracker;
183use MediaWiki\User\UserFactory;
184use MediaWiki\User\UserGroupManager;
185use MediaWiki\User\UserGroupManagerFactory;
186use MediaWiki\User\UserIdentityLookup;
187use MediaWiki\User\UserIdentityUtils;
188use MediaWiki\User\UserNamePrefixSearch;
189use MediaWiki\User\UserNameUtils;
190use MediaWiki\Utils\UrlUtils;
191use MediaWiki\Watchlist\WatchedItemQueryService;
192use MediaWiki\Watchlist\WatchedItemStoreInterface;
193use MediaWiki\Watchlist\WatchlistManager;
194use MessageCache;
195use MWLBFactory;
196use ObjectCacheFactory;
197use OldRevisionImporter;
198use RepoGroup;
199use SearchEngine;
200use SearchEngineConfig;
201use SearchEngineFactory;
202use SkinFactory;
203use UploadRevisionImporter;
204use WikiImporterFactory;
205use Wikimedia\EventRelayer\EventRelayerGroup;
206use Wikimedia\Message\IMessageFormatterFactory;
207use Wikimedia\Mime\MimeAnalyzer;
208use Wikimedia\NonSerializable\NonSerializableTrait;
209use Wikimedia\ObjectCache\BagOStuff;
210use Wikimedia\ObjectCache\WANObjectCache;
211use Wikimedia\ObjectFactory\ObjectFactory;
212use Wikimedia\Parsoid\Config\DataAccess;
213use Wikimedia\Rdbms\ChronologyProtector;
214use Wikimedia\Rdbms\ConfiguredReadOnlyMode;
215use Wikimedia\Rdbms\DatabaseFactory;
216use Wikimedia\Rdbms\IConnectionProvider;
217use Wikimedia\Rdbms\ILoadBalancer;
218use Wikimedia\Rdbms\LBFactory;
219use Wikimedia\Rdbms\LBFactorySingle;
220use Wikimedia\Rdbms\LoadBalancerDisabled;
221use Wikimedia\Rdbms\ReadOnlyMode;
222use Wikimedia\RequestTimeout\CriticalSectionProvider;
223use Wikimedia\Services\NoSuchServiceException;
224use Wikimedia\Services\SalvageableService;
225use Wikimedia\Services\ServiceContainer;
226use Wikimedia\Stats\IBufferingStatsdDataFactory;
227use Wikimedia\Stats\StatsFactory;
228use Wikimedia\Telemetry\TracerInterface;
229use Wikimedia\UUID\GlobalIdGenerator;
230use Wikimedia\WRStats\WRStatsFactory;
231
232/**
233 * Service locator for MediaWiki core services.
234 *
235 * Refer to includes/ServiceWiring.php for the default implementations.
236 *
237 * @see [Dependency Injection](@ref dependencyinjection) in docs/Injection.md
238 * for the principles of DI and how to use it MediaWiki core.
239 *
240 * @since 1.27
241 */
242class MediaWikiServices extends ServiceContainer {
243    use NonSerializableTrait;
244
245    /**
246     * @var bool
247     */
248    private static $globalInstanceAllowed = false;
249
250    /**
251     * @var self|null
252     */
253    private static $instance = null;
254
255    /**
256     * @see disableStorage()
257     * @var bool
258     */
259    private bool $storageDisabled = false;
260
261    /**
262     * Allows a global service container instance to exist.
263     *
264     * This should be called only after configuration settings have been read and extensions
265     * have been registered. Any change made to configuration after this method has been called
266     * may be ineffective or even harmful.
267     *
268     * @see getInstance()
269     *
270     * @since 1.36
271     */
272    public static function allowGlobalInstance() {
273        self::$globalInstanceAllowed = true;
274
275        if ( self::$instance ) {
276            // TODO: in 1.37, getInstance() should fail if $globalInstanceAllowed is false! (T153256)
277            // Until then, we have to reset service instances that have already been created.
278            // No need to warn here, getService() has already triggered a deprecation warning.
279            self::resetGlobalInstance( null, 'quick' );
280        }
281    }
282
283    /**
284     * @internal Should only be used in MediaWikiUnitTestCase
285     */
286    public static function disallowGlobalInstanceInUnitTests(): void {
287        if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
288            throw new LogicException( 'Can only be called in tests' );
289        }
290        self::$globalInstanceAllowed = false;
291    }
292
293    /**
294     * @internal Should only be used in MediaWikiUnitTestCase
295     */
296    public static function allowGlobalInstanceAfterUnitTests(): void {
297        if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
298            throw new LogicException( 'Can only be called in tests' );
299        }
300        self::$globalInstanceAllowed = true;
301    }
302
303    /**
304     * Returns true if an instance has already been initialized. This can be used to avoid accessing
305     * services if it's not safe, such as in unit tests or early setup.
306     */
307    public static function hasInstance(): bool {
308        return self::$instance !== null;
309    }
310
311    /**
312     * Returns the global default instance of the top level service locator.
313     *
314     * @note if called before allowGlobalInstance(), this method will fail.
315     *
316     * @since 1.27
317     *
318     * The default instance is initialized using the service instantiator functions
319     * defined in ServiceWiring.php.
320     *
321     * @note This should only be called by static functions! The instance returned here
322     * should not be passed around! Objects that need access to a service should have
323     * that service injected into the constructor, never a service locator!
324     */
325    public static function getInstance(): self {
326        if ( !self::$globalInstanceAllowed ) {
327            if ( defined( 'MW_PHPUNIT_TEST' ) ) {
328                // Fail hard in PHPUnit tests only
329                throw new LogicException( 'Premature access to service container' );
330            }
331            // TODO: getInstance() should always fail if $globalInstanceAllowed is false! (T153256)
332            wfDeprecatedMsg( 'Premature access to service container', '1.36' );
333        }
334
335        if ( self::$instance === null ) {
336            // NOTE: constructing GlobalVarConfig here is not particularly pretty,
337            // but some information from the global scope has to be injected here,
338            // even if it's just a file name or database credentials to load
339            // configuration from.
340            $bootstrapConfig = new GlobalVarConfig();
341            self::$instance = self::newInstance( $bootstrapConfig, 'load' );
342
343            // Provides a traditional hook point to allow extensions to configure services.
344            // NOTE: Ideally this would be in newInstance() but it causes an infinite run loop
345            $runner = new HookRunner( self::$instance->getHookContainer() );
346            $runner->onMediaWikiServices( self::$instance );
347        }
348        return self::$instance;
349    }
350
351    public function getService( $name ) {
352        // TODO: in 1.37, getInstance() should fail if $globalInstanceAllowed is false! (T153256)
353        if ( !self::$globalInstanceAllowed && $this === self::$instance ) {
354            wfDeprecatedMsg( "Premature access to service '$name'", '1.36', false, 3 );
355        }
356
357        return parent::getService( $name );
358    }
359
360    /**
361     * Replaces the global MediaWikiServices instance.
362     *
363     * @since 1.28
364     *
365     * @note This is for use in PHPUnit tests only!
366     *
367     * @param self $services The new MediaWikiServices object.
368     *
369     * @return self The old MediaWikiServices object, so it can be restored later.
370     */
371    public static function forceGlobalInstance( self $services ): self {
372        if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
373            throw new LogicException( __METHOD__ . ' must not be used outside unit tests.' );
374        }
375
376        $old = self::getInstance();
377        self::$instance = $services;
378
379        return $old;
380    }
381
382    /**
383     * Creates a new instance of MediaWikiServices and sets it as the global default
384     * instance. getInstance() will return a different MediaWikiServices object
385     * after every call to resetGlobalInstance().
386     *
387     * @since 1.28
388     *
389     * @warning This should not be used during normal operation. It is intended for use
390     * when the configuration has changed significantly since bootstrap time, e.g.
391     * during the installation process or during testing. The method must not be called after
392     * MW_SERVICE_BOOTSTRAP_COMPLETE has been defined in Setup.php, unless MW_PHPUNIT_TEST or
393     * MEDIAWIKI_INSTALL or RUN_MAINTENANCE_IF_MAIN is defined).
394     *
395     * @warning Calling resetGlobalInstance() may leave the application in an inconsistent
396     * state. Calling this is only safe under the ASSUMPTION that NO REFERENCE to
397     * any of the services managed by MediaWikiServices exist. If any service objects
398     * managed by the old MediaWikiServices instance remain in use, they may INTERFERE
399     * with the operation of the services managed by the new MediaWikiServices.
400     * Operating with a mix of services created by the old and the new
401     * MediaWikiServices instance may lead to INCONSISTENCIES and even DATA LOSS!
402     * Any class implementing LAZY LOADING is especially prone to this problem,
403     * since instances would typically retain a reference to a storage layer service.
404     *
405     * @see forceGlobalInstance()
406     * @see resetGlobalInstance()
407     * @see resetBetweenTest()
408     *
409     * @param Config|null $bootstrapConfig The Config object to be registered as the
410     *        'BootstrapConfig' service. This has to contain at least the information
411     *        needed to set up the 'ConfigFactory' service. If not given, the bootstrap
412     *        config of the old instance of MediaWikiServices will be re-used. If there
413     *        was no previous instance, a new GlobalVarConfig object will be used to
414     *        bootstrap the services.
415     * @param string $mode May be one of:
416     *   - quick: allow expensive resources to be re-used. See SalvageableService for details.
417     *   - reset: discard expensive resources but reuse service wiring (default)
418     *   - reload: discard expensive resources and reload the service wiring
419     */
420    public static function resetGlobalInstance( ?Config $bootstrapConfig = null, $mode = 'reset' ) {
421        if ( self::$instance === null ) {
422            // no global instance yet, nothing to reset
423            return;
424        }
425
426        self::failIfResetNotAllowed( __METHOD__ );
427
428        $oldInstance = self::$instance;
429        self::$instance = self::newInstance(
430            $bootstrapConfig ?? self::$instance->getBootstrapConfig(),
431            'load'
432        );
433
434        // Provides a traditional hook point to allow extensions to configure services.
435        $runner = new HookRunner( $oldInstance->getHookContainer() );
436        $runner->onMediaWikiServices( self::$instance );
437
438        if ( $mode !== 'reload' ) {
439            self::$instance->importWiring( $oldInstance, [ 'BootstrapConfig' ] );
440        }
441
442        if ( $mode === 'quick' ) {
443            self::$instance->salvage( $oldInstance );
444        } else {
445            $oldInstance->destroy();
446        }
447    }
448
449    /** @noinspection PhpDocSignatureInspection */
450
451    /**
452     * Salvages the state of any salvageable service instances in $other.
453     *
454     * @note $other will have been destroyed when salvage() returns.
455     */
456    private function salvage( self $other ) {
457        foreach ( $this->getServiceNames() as $name ) {
458            // The service could be new in the new instance and not registered in the
459            // other instance (e.g. an extension that was loaded after the instantiation of
460            // the other instance. Skip this service in this case. See T143974
461            try {
462                $oldService = $other->peekService( $name );
463            } catch ( NoSuchServiceException $e ) {
464                continue;
465            }
466
467            if ( $oldService instanceof SalvageableService ) {
468                /** @var SalvageableService $newService */
469                $newService = $this->getService( $name );
470                $newService->salvage( $oldService );
471            }
472        }
473
474        $other->destroy();
475    }
476
477    /**
478     * Creates a new MediaWikiServices instance and initializes it according to the
479     * given $bootstrapConfig. In particular, all wiring files defined in the
480     * ServiceWiringFiles setting are loaded, and the MediaWikiServices hook is called.
481     *
482     * @param Config $bootstrapConfig The Config object to be registered as the
483     *        'BootstrapConfig' service.
484     * @param string $loadWiring set this to 'load' to load the wiring files specified
485     *        in the 'ServiceWiringFiles' setting in $bootstrapConfig.
486     */
487    private static function newInstance( Config $bootstrapConfig, $loadWiring = '' ): self {
488        $instance = new self( $bootstrapConfig );
489
490        // Load the default wiring from the specified files.
491        if ( $loadWiring === 'load' ) {
492            $wiringFiles = $bootstrapConfig->get( MainConfigNames::ServiceWiringFiles );
493            $instance->loadWiringFiles( $wiringFiles );
494        }
495
496        return $instance;
497    }
498
499    /**
500     * Disables all storage layer services. After calling this, any attempt to access the
501     * storage layer will result in an error.
502     *
503     * @since 1.28
504     * @deprecated since 1.40, use disableStorage() instead.
505     *
506     * @warning This is intended for extreme situations, see the documentation of disableStorage() for details.
507     *
508     * @see resetGlobalInstance()
509     * @see resetChildProcessServices()
510     */
511    public static function disableStorageBackend() {
512        $services = self::getInstance();
513        $services->disableStorage();
514    }
515
516    /**
517     * Disables all storage layer services. After calling this, any attempt to access the
518     * storage layer will result in an error. Use resetGlobalInstance() with $mode=reload
519     * to restore normal operation.
520     *
521     * @since 1.40
522     *
523     * @warning This is intended for extreme situations only and should never be used
524     * while serving normal web requests. Legitimate use cases for this method include
525     * the installation process. Test fixtures may also use this, if the fixture relies
526     * on globalState.
527     *
528     * @see resetGlobalInstance()
529     * @see resetChildProcessServices()
530     */
531    public function disableStorage() {
532        if ( $this->storageDisabled ) {
533            return;
534        }
535
536        $this->redefineService(
537            'DBLoadBalancer',
538            static function ( self $services ) {
539                return new LoadBalancerDisabled();
540            }
541        );
542
543        $this->redefineService(
544            'DBLoadBalancerFactory',
545            static function ( self $services ) {
546                return LBFactorySingle::newDisabled();
547            }
548        );
549
550        $this->redefineService(
551            'InterwikiLookup',
552            static function ( self $services ) {
553                return new NullInterwikiLookup();
554            }
555        );
556
557        $this->redefineService(
558            'UserOptionsLookup',
559            static function ( self $services ) {
560                return new StaticUserOptionsLookup(
561                    [],
562                    $services->getMainConfig()->get( MainConfigNames::DefaultUserOptions )
563                );
564            }
565        );
566
567        $this->addServiceManipulator(
568            'LocalisationCache',
569            static function ( LocalisationCache $cache ) {
570                $cache->disableBackend();
571            }
572        );
573
574        $this->addServiceManipulator(
575            'MessageCache',
576            static function ( MessageCache $cache ) {
577                $cache->disable();
578            }
579        );
580
581        self::getInstance()->getObjectCacheFactory()->clear();
582
583        $this->storageDisabled = true;
584    }
585
586    /**
587     * Returns true if disableStorage() has been called on this MediaWikiServices instance.
588     */
589    public function isStorageDisabled(): bool {
590        return $this->storageDisabled;
591    }
592
593    /**
594     * Resets any services that may have become stale after a child processö
595     * returns from after pcntl_fork(). It's also safe, but generally unnecessary,
596     * to call this method from the parent process.
597     *
598     * @since 1.28
599     *
600     * @note This is intended for use in the context of process forking only!
601     *
602     * @see resetGlobalInstance()
603     * @see disableStorage()
604     */
605    public static function resetChildProcessServices() {
606        // NOTE: for now, just reset everything. Since we don't know the interdependencies
607        // between services, we can't do this more selectively at this time.
608        self::resetGlobalInstance();
609
610        // Child, reseed because there is no bug in PHP:
611        // https://bugs.php.net/bug.php?id=42465
612        mt_srand( getmypid() );
613    }
614
615    /**
616     * Resets the given service for testing purposes.
617     *
618     * @since 1.28
619     *
620     * @warning This is generally unsafe! Other services may still retain references
621     * to the stale service instance, leading to failures and inconsistencies. Subclasses
622     * may use this method to reset specific services under specific instances, but
623     * it should not be exposed to application logic.
624     *
625     * @note With proper dependency injection used throughout the codebase, this method
626     * should not be needed. It is provided to allow tests that pollute global service
627     * instances to clean up.
628     *
629     * @param string $name
630     * @param bool $destroy Whether the service instance should be destroyed if it exists.
631     *        When set to false, any existing service instance will effectively be detached
632     *        from the container.
633     */
634    public function resetServiceForTesting( $name, $destroy = true ) {
635        if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
636            throw new LogicException( 'resetServiceForTesting() must not be used outside unit tests.' );
637        }
638
639        $this->resetService( $name, $destroy );
640    }
641
642    /**
643     * Convenience method that throws an exception unless it is called during a phase in which
644     * resetting of global services is allowed. In general, services should not be reset
645     * individually, since that may introduce inconsistencies.
646     *
647     * @since 1.28
648     *
649     * This method will throw an exception if:
650     *
651     * - self::$resetInProgress is false (to allow all services to be reset together
652     *   via resetGlobalInstance)
653     * - and MEDIAWIKI_INSTALL is not defined (to allow services to be reset during installation)
654     * - and MW_PHPUNIT_TEST is not defined (to allow services to be reset during testing)
655     *
656     * This method is intended to be used to safeguard against accidentally resetting
657     * global service instances that are not yet managed by MediaWikiServices. It is
658     * defined here in the MediaWikiServices services class to have a central place
659     * for managing service bootstrapping and resetting.
660     *
661     * @param string $method the name of the caller method, as given by __METHOD__.
662     *
663     * @see resetGlobalInstance()
664     * @see forceGlobalInstance()
665     * @see disableStorage()
666     */
667    public static function failIfResetNotAllowed( $method ) {
668        if ( !defined( 'MW_PHPUNIT_TEST' )
669            && !defined( 'MW_PARSER_TEST' )
670            && !defined( 'MEDIAWIKI_INSTALL' )
671            && !defined( 'RUN_MAINTENANCE_IF_MAIN' )
672            && defined( 'MW_SERVICE_BOOTSTRAP_COMPLETE' )
673        ) {
674            throw new LogicException( $method . ' may only be called during bootstrapping and unit tests!' );
675        }
676    }
677
678    /**
679     * @param Config $config The Config object to be registered as the 'BootstrapConfig' service.
680     *        This has to contain at least the information needed to set up the 'ConfigFactory'
681     *        service.
682     */
683    public function __construct( Config $config ) {
684        parent::__construct();
685
686        // Register the given Config object as the bootstrap config service.
687        $this->defineService( 'BootstrapConfig', static function () use ( $config ) {
688            return $config;
689        } );
690    }
691
692    // CONVENIENCE GETTERS ////////////////////////////////////////////////////
693
694    /**
695     * @since 1.37
696     */
697    public function getActionFactory(): ActionFactory {
698        return $this->getService( 'ActionFactory' );
699    }
700
701    /**
702     * @since 1.31
703     */
704    public function getActorMigration(): ActorMigration {
705        return $this->getService( 'ActorMigration' );
706    }
707
708    /**
709     * @since 1.36
710     */
711    public function getActorNormalization(): ActorNormalization {
712        return $this->getService( 'ActorNormalization' );
713    }
714
715    /**
716     * @since 1.36
717     */
718    public function getActorStore(): ActorStore {
719        return $this->getService( 'ActorStore' );
720    }
721
722    /**
723     * @since 1.36
724     */
725    public function getActorStoreFactory(): ActorStoreFactory {
726        return $this->getService( 'ActorStoreFactory' );
727    }
728
729    /**
730     * @since 1.38
731     */
732    public function getArchivedRevisionLookup(): ArchivedRevisionLookup {
733        return $this->getService( 'ArchivedRevisionLookup' );
734    }
735
736    /**
737     * @since 1.35
738     */
739    public function getAuthManager(): AuthManager {
740        return $this->getService( 'AuthManager' );
741    }
742
743    /**
744     * @since 1.42
745     */
746    public function getAutoblockExemptionList(): AutoblockExemptionList {
747        return $this->getService( 'AutoblockExemptionList' );
748    }
749
750    /**
751     * @since 1.37
752     */
753    public function getBacklinkCacheFactory(): BacklinkCacheFactory {
754        return $this->getService( 'BacklinkCacheFactory' );
755    }
756
757    /**
758     * @since 1.34
759     */
760    public function getBadFileLookup(): BadFileLookup {
761        return $this->getService( 'BadFileLookup' );
762    }
763
764    /**
765     * @since 1.31
766     */
767    public function getBlobStore(): BlobStore {
768        return $this->getService( 'BlobStore' );
769    }
770
771    /**
772     * @since 1.31
773     */
774    public function getBlobStoreFactory(): BlobStoreFactory {
775        return $this->getService( 'BlobStoreFactory' );
776    }
777
778    /**
779     * @since 1.37
780     */
781    public function getBlockActionInfo(): BlockActionInfo {
782        return $this->getService( 'BlockActionInfo' );
783    }
784
785    /**
786     * @since 1.35
787     * @deprecated since 1.42, use getFormatterFactory()->getBlockErrorFormatter() instead.
788     */
789    public function getBlockErrorFormatter(): BlockErrorFormatter {
790        wfDeprecated( __METHOD__, '1.42' );
791        return $this->getService( 'BlockErrorFormatter' );
792    }
793
794    /**
795     * @since 1.34
796     */
797    public function getBlockManager(): BlockManager {
798        return $this->getService( 'BlockManager' );
799    }
800
801    /**
802     * @since 1.35
803     */
804    public function getBlockPermissionCheckerFactory(): BlockPermissionCheckerFactory {
805        return $this->getService( 'BlockPermissionCheckerFactory' );
806    }
807
808    /**
809     * @since 1.33
810     */
811    public function getBlockRestrictionStore(): BlockRestrictionStore {
812        return $this->getService( 'BlockRestrictionStore' );
813    }
814
815    /**
816     * @since 1.38
817     */
818    public function getBlockRestrictionStoreFactory(): BlockRestrictionStoreFactory {
819        return $this->getService( 'BlockRestrictionStoreFactory' );
820    }
821
822    /**
823     * @since 1.36
824     */
825    public function getBlockUserFactory(): BlockUserFactory {
826        return $this->getService( 'BlockUserFactory' );
827    }
828
829    /**
830     * @since 1.36
831     */
832    public function getBlockUtils(): BlockUtils {
833        return $this->getService( 'BlockUtils' );
834    }
835
836    /**
837     * @since 1.42
838     */
839    public function getBlockUtilsFactory(): BlockUtilsFactory {
840        return $this->getService( 'BlockUtilsFactory' );
841    }
842
843    /**
844     * Returns the Config object containing the bootstrap configuration.
845     * Bootstrap configuration would typically include database credentials
846     * and other information that may be needed before the ConfigFactory
847     * service can be instantiated.
848     *
849     * @note This should only be used during bootstrapping, in particular
850     * when creating the MainConfig service. Application logic should
851     * use getMainConfig() to get a Config instances.
852     *
853     * @since 1.27
854     */
855    public function getBootstrapConfig(): Config {
856        return $this->getService( 'BootstrapConfig' );
857    }
858
859    /**
860     * @since 1.37
861     */
862    public function getBotPasswordStore(): BotPasswordStore {
863        return $this->getService( 'BotPasswordStore' );
864    }
865
866    /**
867     * @since 1.37
868     */
869    public function getCentralIdLookup(): CentralIdLookup {
870        return $this->getService( 'CentralIdLookup' );
871    }
872
873    /**
874     * @since 1.37
875     */
876    public function getCentralIdLookupFactory(): CentralIdLookupFactory {
877        return $this->getService( 'CentralIdLookupFactory' );
878    }
879
880    /**
881     * @since 1.32
882     */
883    public function getChangeTagDefStore(): NameTableStore {
884        return $this->getService( 'ChangeTagDefStore' );
885    }
886
887    /**
888     * @since 1.41
889     */
890    public function getChangeTagsStore(): ChangeTagsStore {
891        return $this->getService( 'ChangeTagsStore' );
892    }
893
894    /**
895     * @since 1.41
896     */
897    public function getChronologyProtector(): ChronologyProtector {
898        return $this->getService( 'ChronologyProtector' );
899    }
900
901    /**
902     * @since 1.37
903     */
904    public function getCollationFactory(): CollationFactory {
905        return $this->getService( 'CollationFactory' );
906    }
907
908    /**
909     * @since 1.38
910     */
911    public function getCommentFormatter(): CommentFormatter {
912        return $this->getService( 'CommentFormatter' );
913    }
914
915    /**
916     * @since 1.41
917     */
918    public function getCommentParserFactory(): CommentParserFactory {
919        return $this->getService( 'CommentParserFactory' );
920    }
921
922    /**
923     * @since 1.31
924     */
925    public function getCommentStore(): CommentStore {
926        return $this->getService( 'CommentStore' );
927    }
928
929    /**
930     * @since 1.27
931     */
932    public function getConfigFactory(): ConfigFactory {
933        return $this->getService( 'ConfigFactory' );
934    }
935
936    /**
937     * @deprecated since 1.42. Unused.
938     * @since 1.32
939     */
940    public function getConfigRepository(): ConfigRepository {
941        wfDeprecated( __METHOD__, '1.42' );
942        return $this->getService( 'ConfigRepository' );
943    }
944
945    /**
946     * @since 1.39
947     */
948    public function getConfigSchema(): ConfigSchema {
949        return $this->getService( 'ConfigSchema' );
950    }
951
952    /**
953     * @since 1.29
954     * @deprecated since 1.41 use ::getReadOnlyMode() instead
955     */
956    public function getConfiguredReadOnlyMode(): ConfiguredReadOnlyMode {
957        return $this->getService( 'ConfiguredReadOnlyMode' );
958    }
959
960    /**
961     * @since 1.42
962     */
963    public function getConnectionProvider(): IConnectionProvider {
964        return $this->getService( 'ConnectionProvider' );
965    }
966
967    /**
968     * @since 1.35
969     */
970    public function getContentHandlerFactory(): IContentHandlerFactory {
971        return $this->getService( 'ContentHandlerFactory' );
972    }
973
974    /**
975     * @since 1.32
976     */
977    public function getContentLanguage(): Language {
978        return $this->getService( 'ContentLanguage' );
979    }
980
981    /**
982     * @since 1.43
983     */
984    public function getContentLanguageCode(): LanguageCode {
985        return $this->getService( 'ContentLanguageCode' );
986    }
987
988    /**
989     * @since 1.35
990     */
991    public function getContentModelChangeFactory(): ContentModelChangeFactory {
992        return $this->getService( 'ContentModelChangeFactory' );
993    }
994
995    /**
996     * @since 1.31
997     */
998    public function getContentModelStore(): NameTableStore {
999        return $this->getService( 'ContentModelStore' );
1000    }
1001
1002    /**
1003     * @since 1.38
1004     */
1005    public function getContentRenderer(): ContentRenderer {
1006        return $this->getService( 'ContentRenderer' );
1007    }
1008
1009    /**
1010     * @since 1.37
1011     */
1012    public function getContentTransformer(): ContentTransformer {
1013        return $this->getService( 'ContentTransformer' );
1014    }
1015
1016    /**
1017     * @since 1.36
1018     */
1019    public function getCriticalSectionProvider(): CriticalSectionProvider {
1020        return $this->getService( 'CriticalSectionProvider' );
1021    }
1022
1023    /**
1024     * @since 1.36
1025     */
1026    public function getDatabaseBlockStore(): DatabaseBlockStore {
1027        return $this->getService( 'DatabaseBlockStore' );
1028    }
1029
1030    /**
1031     * @since 1.40
1032     */
1033    public function getDatabaseBlockStoreFactory(): DatabaseBlockStoreFactory {
1034        return $this->getService( 'DatabaseBlockStoreFactory' );
1035    }
1036
1037    /**
1038     * @since 1.39
1039     */
1040    public function getDatabaseFactory(): DatabaseFactory {
1041        return $this->getService( 'DatabaseFactory' );
1042    }
1043
1044    /**
1045     * @since 1.33
1046     */
1047    public function getDateFormatterFactory(): DateFormatterFactory {
1048        return $this->getService( 'DateFormatterFactory' );
1049    }
1050
1051    /**
1052     * @since 1.28
1053     * @return ILoadBalancer The main DB load balancer for the local wiki.
1054     */
1055    public function getDBLoadBalancer(): ILoadBalancer {
1056        return $this->getService( 'DBLoadBalancer' );
1057    }
1058
1059    /**
1060     * @since 1.28
1061     * @note When possible, use {@link getConnectionProvider()} instead.
1062     */
1063    public function getDBLoadBalancerFactory(): LBFactory {
1064        return $this->getService( 'DBLoadBalancerFactory' );
1065    }
1066
1067    /**
1068     * @since 1.39
1069     */
1070    public function getDBLoadBalancerFactoryConfigBuilder(): MWLBFactory {
1071        return $this->getService( 'DBLoadBalancerFactoryConfigBuilder' );
1072    }
1073
1074    /**
1075     * @return OutputTransformPipeline
1076     * @internal
1077     */
1078    public function getDefaultOutputPipeline(): OutputTransformPipeline {
1079        return $this->getService( 'DefaultOutputPipeline' );
1080    }
1081
1082    /**
1083     * @since 1.37
1084     */
1085    public function getDeletePageFactory(): DeletePageFactory {
1086        return $this->getService( 'DeletePageFactory' );
1087    }
1088
1089    /**
1090     * @since 1.44
1091     * @unstable until 1.45
1092     */
1093    public function getDomainEventDispatcher(): DomainEventDispatcher {
1094        return $this->getService( 'DomainEventDispatcher' );
1095    }
1096
1097    /**
1098     * @since 1.44
1099     * @unstable until 1.45
1100     */
1101    public function getDomainEventSource(): DomainEventSource {
1102        return $this->getService( 'DomainEventSource' );
1103    }
1104
1105    /**
1106     * @since 1.35
1107     */
1108    public function getEmailer(): IEmailer {
1109        return $this->getService( 'Emailer' );
1110    }
1111
1112    /**
1113     * @since 1.41
1114     */
1115    public function getEmailUserFactory(): EmailUserFactory {
1116        return $this->getService( 'EmailUserFactory' );
1117    }
1118
1119    /**
1120     * @since 1.27
1121     */
1122    public function getEventRelayerGroup(): EventRelayerGroup {
1123        return $this->getService( 'EventRelayerGroup' );
1124    }
1125
1126    /**
1127     * @since 1.42
1128     */
1129    public function getExtensionRegistry(): ExtensionRegistry {
1130        return $this->getService( 'ExtensionRegistry' );
1131    }
1132
1133    /**
1134     * @since 1.34
1135     */
1136    public function getExternalStoreAccess(): ExternalStoreAccess {
1137        return $this->getService( 'ExternalStoreAccess' );
1138    }
1139
1140    /**
1141     * @since 1.31
1142     */
1143    public function getExternalStoreFactory(): ExternalStoreFactory {
1144        return $this->getService( 'ExternalStoreFactory' );
1145    }
1146
1147    /**
1148     * @since 1.35
1149     */
1150    public function getFileBackendGroup(): FileBackendGroup {
1151        return $this->getService( 'FileBackendGroup' );
1152    }
1153
1154    /**
1155     * @since 1.41
1156     */
1157    public function getFormatterFactory(): FormatterFactory {
1158        return $this->getService( 'FormatterFactory' );
1159    }
1160
1161    /**
1162     * @since 1.28
1163     */
1164    public function getGenderCache(): GenderCache {
1165        return $this->getService( 'GenderCache' );
1166    }
1167
1168    /**
1169     * @since 1.35
1170     */
1171    public function getGlobalIdGenerator(): GlobalIdGenerator {
1172        return $this->getService( 'GlobalIdGenerator' );
1173    }
1174
1175    /**
1176     * @since 1.38
1177     */
1178    public function getGrantsInfo(): GrantsInfo {
1179        return $this->getService( 'GrantsInfo' );
1180    }
1181
1182    /**
1183     * @since 1.38
1184     */
1185    public function getGrantsLocalization(): GrantsLocalization {
1186        return $this->getService( 'GrantsLocalization' );
1187    }
1188
1189    /**
1190     * @since 1.36
1191     */
1192    public function getGroupPermissionsLookup(): GroupPermissionsLookup {
1193        return $this->getService( 'GroupPermissionsLookup' );
1194    }
1195
1196    /**
1197     * @since 1.42
1198     * @return HideUserUtils
1199     */
1200    public function getHideUserUtils(): HideUserUtils {
1201        return $this->getService( 'HideUserUtils' );
1202    }
1203
1204    /**
1205     * @since 1.35
1206     */
1207    public function getHookContainer(): HookContainer {
1208        return $this->getService( 'HookContainer' );
1209    }
1210
1211    /**
1212     * @since 1.35
1213     */
1214    public function getHtmlCacheUpdater(): HTMLCacheUpdater {
1215        return $this->getService( 'HtmlCacheUpdater' );
1216    }
1217
1218    /**
1219     * @since 1.39
1220     */
1221    public function getHtmlTransformFactory(): HtmlTransformFactory {
1222        return $this->getService( 'HtmlTransformFactory' );
1223    }
1224
1225    /**
1226     * @since 1.31
1227     */
1228    public function getHttpRequestFactory(): HttpRequestFactory {
1229        return $this->getService( 'HttpRequestFactory' );
1230    }
1231
1232    /**
1233     * @since 1.28
1234     */
1235    public function getInterwikiLookup(): InterwikiLookup {
1236        return $this->getService( 'InterwikiLookup' );
1237    }
1238
1239    /**
1240     * @since 1.41
1241     */
1242    public function getIntroMessageBuilder(): IntroMessageBuilder {
1243        return $this->getService( 'IntroMessageBuilder' );
1244    }
1245
1246    /**
1247     * @since 1.40
1248     */
1249    public function getJobFactory(): JobFactory {
1250        return $this->getService( 'JobFactory' );
1251    }
1252
1253    /**
1254     * @since 1.37
1255     */
1256    public function getJobQueueGroup(): JobQueueGroup {
1257        return $this->getService( 'JobQueueGroup' );
1258    }
1259
1260    /**
1261     * @since 1.37
1262     */
1263    public function getJobQueueGroupFactory(): JobQueueGroupFactory {
1264        return $this->getService( 'JobQueueGroupFactory' );
1265    }
1266
1267    /**
1268     * @since 1.35
1269     */
1270    public function getJobRunner(): JobRunner {
1271        return $this->getService( 'JobRunner' );
1272    }
1273
1274    /**
1275     * @since 1.36
1276     */
1277    public function getJsonCodec(): JsonCodec {
1278        return $this->getService( 'JsonCodec' );
1279    }
1280
1281    /**
1282     * @since 1.35
1283     */
1284    public function getLanguageConverterFactory(): LanguageConverterFactory {
1285        return $this->getService( 'LanguageConverterFactory' );
1286    }
1287
1288    /**
1289     * @since 1.35
1290     */
1291    public function getLanguageFactory(): LanguageFactory {
1292        return $this->getService( 'LanguageFactory' );
1293    }
1294
1295    /**
1296     * @since 1.35
1297     */
1298    public function getLanguageFallback(): LanguageFallback {
1299        return $this->getService( 'LanguageFallback' );
1300    }
1301
1302    /**
1303     * @since 1.34
1304     */
1305    public function getLanguageNameUtils(): LanguageNameUtils {
1306        return $this->getService( 'LanguageNameUtils' );
1307    }
1308
1309    /**
1310     * @since 1.35
1311     */
1312    public function getLinkBatchFactory(): LinkBatchFactory {
1313        return $this->getService( 'LinkBatchFactory' );
1314    }
1315
1316    /**
1317     * @since 1.28
1318     */
1319    public function getLinkCache(): LinkCache {
1320        return $this->getService( 'LinkCache' );
1321    }
1322
1323    /**
1324     * LinkRenderer instance that can be used
1325     * if no custom options are needed
1326     *
1327     * @since 1.28
1328     */
1329    public function getLinkRenderer(): LinkRenderer {
1330        return $this->getService( 'LinkRenderer' );
1331    }
1332
1333    /**
1334     * @since 1.28
1335     */
1336    public function getLinkRendererFactory(): LinkRendererFactory {
1337        return $this->getService( 'LinkRendererFactory' );
1338    }
1339
1340    /**
1341     * @since 1.39
1342     */
1343    public function getLinksMigration(): LinksMigration {
1344        return $this->getService( 'LinksMigration' );
1345    }
1346
1347    /**
1348     * @since 1.38
1349     */
1350    public function getLinkTargetLookup(): LinkTargetLookup {
1351        return $this->getService( 'LinkTargetLookup' );
1352    }
1353
1354    /**
1355     * @since 1.43
1356     */
1357    public function getLintErrorChecker(): LintErrorChecker {
1358        return $this->getService( 'LintErrorChecker' );
1359    }
1360
1361    /**
1362     * @since 1.34
1363     */
1364    public function getLocalisationCache(): LocalisationCache {
1365        return $this->getService( 'LocalisationCache' );
1366    }
1367
1368    /**
1369     * Returns the main server-local cache, yielding EmptyBagOStuff if there is none
1370     *
1371     * In web request mode, the cache should at least be shared among web workers.
1372     * In CLI mode, the cache should at least be shared among processes run by the same user.
1373     *
1374     * @since 1.28
1375     */
1376    public function getLocalServerObjectCache(): BagOStuff {
1377        return $this->getService( 'LocalServerObjectCache' );
1378    }
1379
1380    /**
1381     * @since 1.34
1382     */
1383    public function getLockManagerGroupFactory(): LockManagerGroupFactory {
1384        return $this->getService( 'LockManagerGroupFactory' );
1385    }
1386
1387    /**
1388     * @since 1.42
1389     */
1390    public function getLogFormatterFactory(): LogFormatterFactory {
1391        return $this->getService( 'LogFormatterFactory' );
1392    }
1393
1394    /**
1395     * @since 1.32
1396     */
1397    public function getMagicWordFactory(): MagicWordFactory {
1398        return $this->getService( 'MagicWordFactory' );
1399    }
1400
1401    /**
1402     * Returns the Config object that provides configuration for MediaWiki core.
1403     * This may or may not be the same object that is returned by getBootstrapConfig().
1404     *
1405     * @since 1.27
1406     */
1407    public function getMainConfig(): Config {
1408        return $this->getService( 'MainConfig' );
1409    }
1410
1411    /**
1412     * Returns the main object stash, yielding EmptyBagOStuff if there is none
1413     *
1414     * The stash should be shared among all datacenters
1415     *
1416     * @since 1.28
1417     */
1418    public function getMainObjectStash(): BagOStuff {
1419        return $this->getService( 'MainObjectStash' );
1420    }
1421
1422    /**
1423     * Returns the main WAN cache, yielding EmptyBagOStuff if there is none
1424     *
1425     * The cache should relay any purge operations to all datacenters
1426     *
1427     * @since 1.28
1428     */
1429    public function getMainWANObjectCache(): WANObjectCache {
1430        return $this->getService( 'MainWANObjectCache' );
1431    }
1432
1433    /**
1434     * @since 1.28
1435     */
1436    public function getMediaHandlerFactory(): MediaHandlerFactory {
1437        return $this->getService( 'MediaHandlerFactory' );
1438    }
1439
1440    /**
1441     * @since 1.35
1442     */
1443    public function getMergeHistoryFactory(): MergeHistoryFactory {
1444        return $this->getService( 'MergeHistoryFactory' );
1445    }
1446
1447    /**
1448     * @since 1.34
1449     */
1450    public function getMessageCache(): MessageCache {
1451        return $this->getService( 'MessageCache' );
1452    }
1453
1454    /**
1455     * @since 1.34
1456     */
1457    public function getMessageFormatterFactory(): IMessageFormatterFactory {
1458        return $this->getService( 'MessageFormatterFactory' );
1459    }
1460
1461    /**
1462     * @since 1.42
1463     * @unstable
1464     * @return BagOStuff
1465     */
1466    public function getMicroStash(): BagOStuff {
1467        return $this->getService( 'MicroStash' );
1468    }
1469
1470    /**
1471     * @since 1.28
1472     */
1473    public function getMimeAnalyzer(): MimeAnalyzer {
1474        return $this->getService( 'MimeAnalyzer' );
1475    }
1476
1477    /**
1478     * @since 1.34
1479     */
1480    public function getMovePageFactory(): MovePageFactory {
1481        return $this->getService( 'MovePageFactory' );
1482    }
1483
1484    /**
1485     * @since 1.34
1486     */
1487    public function getNamespaceInfo(): NamespaceInfo {
1488        return $this->getService( 'NamespaceInfo' );
1489    }
1490
1491    /**
1492     * @since 1.32
1493     */
1494    public function getNameTableStoreFactory(): NameTableStoreFactory {
1495        return $this->getService( 'NameTableStoreFactory' );
1496    }
1497
1498    /**
1499     * @since 1.42
1500     * @return ObjectCacheFactory
1501     */
1502    public function getObjectCacheFactory(): ObjectCacheFactory {
1503        return $this->getService( 'ObjectCacheFactory' );
1504    }
1505
1506    /**
1507     * ObjectFactory is intended for instantiating "handlers" from declarative definitions,
1508     * such as Action API modules, special pages, or REST API handlers.
1509     *
1510     * @since 1.34
1511     */
1512    public function getObjectFactory(): ObjectFactory {
1513        return $this->getService( 'ObjectFactory' );
1514    }
1515
1516    /**
1517     * @since 1.32
1518     */
1519    public function getOldRevisionImporter(): OldRevisionImporter {
1520        return $this->getService( 'OldRevisionImporter' );
1521    }
1522
1523    /**
1524     * @since 1.34
1525     */
1526    public function getPageEditStash(): PageEditStash {
1527        return $this->getService( 'PageEditStash' );
1528    }
1529
1530    /**
1531     * @since 1.36
1532     */
1533    public function getPageProps(): PageProps {
1534        return $this->getService( 'PageProps' );
1535    }
1536
1537    /**
1538     * @since 1.40
1539     */
1540    public function getPageRestHelperFactory(): PageRestHelperFactory {
1541        return $this->getService( 'PageRestHelperFactory' );
1542    }
1543
1544    /**
1545     * @since 1.36
1546     */
1547    public function getPageStore(): PageStore {
1548        return $this->getService( 'PageStore' );
1549    }
1550
1551    /**
1552     * @since 1.36
1553     */
1554    public function getPageStoreFactory(): PageStoreFactory {
1555        return $this->getService( 'PageStoreFactory' );
1556    }
1557
1558    /**
1559     * @since 1.37
1560     */
1561    public function getPageUpdaterFactory(): PageUpdaterFactory {
1562        return $this->getService( 'PageUpdaterFactory' );
1563    }
1564
1565    /**
1566     * Get the main Parser instance. This is unsafe when the caller is not in
1567     * a top-level context, because re-entering the parser will throw an
1568     * exception.
1569     *
1570     * @note Do not use this service for dependency injection or in service wiring.
1571     * It is convenience function to get the global instance in global code.
1572     * For dependency injection or service wiring code use the parser factory via the
1573     * 'ParserFactory' service and call one of the factory functions, preferably
1574     * {@link ParserFactory::create}.
1575     *
1576     * @since 1.29
1577     */
1578    public function getParser(): Parser {
1579        return $this->getService( 'Parser' );
1580    }
1581
1582    /**
1583     * @since 1.30
1584     */
1585    public function getParserCache(): ParserCache {
1586        return $this->getService( 'ParserCache' );
1587    }
1588
1589    /**
1590     * @since 1.36
1591     */
1592    public function getParserCacheFactory(): ParserCacheFactory {
1593        return $this->getService( 'ParserCacheFactory' );
1594    }
1595
1596    /**
1597     * @since 1.32
1598     */
1599    public function getParserFactory(): ParserFactory {
1600        return $this->getService( 'ParserFactory' );
1601    }
1602
1603    /**
1604     * @since 1.36
1605     */
1606    public function getParserOutputAccess(): ParserOutputAccess {
1607        return $this->getService( 'ParserOutputAccess' );
1608    }
1609
1610    /**
1611     * @since 1.39
1612     * @internal
1613     */
1614    public function getParsoidDataAccess(): DataAccess {
1615        return $this->getService( 'ParsoidDataAccess' );
1616    }
1617
1618    /**
1619     * @since 1.39
1620     * @unstable since 1.39, should be stable before release of 1.39
1621     */
1622    public function getParsoidOutputStash(): ParsoidOutputStash {
1623        return $this->getService( 'ParsoidOutputStash' );
1624    }
1625
1626    /**
1627     * @since 1.39
1628     * @internal
1629     */
1630    public function getParsoidPageConfigFactory(): PageConfigFactory {
1631        return $this->getService( 'ParsoidPageConfigFactory' );
1632    }
1633
1634    /**
1635     * @since 1.41
1636     * @internal
1637     */
1638    public function getParsoidParserFactory(): ParsoidParserFactory {
1639        return $this->getService( 'ParsoidParserFactory' );
1640    }
1641
1642    /**
1643     * @since 1.39
1644     * @internal
1645     */
1646    public function getParsoidSiteConfig(): SiteConfig {
1647        return $this->getService( 'ParsoidSiteConfig' );
1648    }
1649
1650    /**
1651     * @since 1.32
1652     */
1653    public function getPasswordFactory(): PasswordFactory {
1654        return $this->getService( 'PasswordFactory' );
1655    }
1656
1657    /**
1658     * @since 1.34
1659     */
1660    public function getPasswordReset(): PasswordReset {
1661        return $this->getService( 'PasswordReset' );
1662    }
1663
1664    /**
1665     * @since 1.32
1666     */
1667    public function getPerDbNameStatsdDataFactory(): StatsdDataFactoryInterface {
1668        return $this->getService( 'PerDbNameStatsdDataFactory' );
1669    }
1670
1671    /**
1672     * @since 1.33
1673     */
1674    public function getPermissionManager(): PermissionManager {
1675        return $this->getService( 'PermissionManager' );
1676    }
1677
1678    /**
1679     * @since 1.41
1680     * @internal
1681     */
1682    public function getPingback(): Pingback {
1683        return $this->getService( 'Pingback' );
1684    }
1685
1686    /**
1687     * @since 1.40
1688     */
1689    public function getPoolCounterFactory(): PoolCounterFactory {
1690        return $this->getService( 'PoolCounterFactory' );
1691    }
1692
1693    /**
1694     * @since 1.31
1695     */
1696    public function getPreferencesFactory(): PreferencesFactory {
1697        return $this->getService( 'PreferencesFactory' );
1698    }
1699
1700    /**
1701     * @since 1.41
1702     */
1703    public function getPreloadedContentBuilder(): PreloadedContentBuilder {
1704        return $this->getService( 'PreloadedContentBuilder' );
1705    }
1706
1707    /**
1708     * @since 1.28
1709     */
1710    public function getProxyLookup(): ProxyLookup {
1711        return $this->getService( 'ProxyLookup' );
1712    }
1713
1714    /**
1715     * @since 1.39
1716     */
1717    public function getRateLimiter(): RateLimiter {
1718        return $this->getService( 'RateLimiter' );
1719    }
1720
1721    /**
1722     * @since 1.29
1723     */
1724    public function getReadOnlyMode(): ReadOnlyMode {
1725        return $this->getService( 'ReadOnlyMode' );
1726    }
1727
1728    /**
1729     * @since 1.38
1730     */
1731    public function getRedirectLookup(): RedirectLookup {
1732        return $this->getService( 'RedirectLookup' );
1733    }
1734
1735    /**
1736     * @since 1.38
1737     */
1738    public function getRedirectStore(): RedirectStore {
1739        return $this->getService( 'RedirectStore' );
1740    }
1741
1742    /**
1743     * @since 1.34
1744     */
1745    public function getRepoGroup(): RepoGroup {
1746        return $this->getService( 'RepoGroup' );
1747    }
1748
1749    /**
1750     * @since 1.33
1751     */
1752    public function getResourceLoader(): ResourceLoader {
1753        return $this->getService( 'ResourceLoader' );
1754    }
1755
1756    /**
1757     * @since 1.37
1758     */
1759    public function getRestrictionStore(): RestrictionStore {
1760        return $this->getService( 'RestrictionStore' );
1761    }
1762
1763    /**
1764     * @since 1.36
1765     */
1766    public function getRevertedTagUpdateManager(): RevertedTagUpdateManager {
1767        return $this->getService( 'RevertedTagUpdateManager' );
1768    }
1769
1770    /**
1771     * @since 1.31
1772     */
1773    public function getRevisionFactory(): RevisionFactory {
1774        return $this->getService( 'RevisionFactory' );
1775    }
1776
1777    /**
1778     * @since 1.31
1779     */
1780    public function getRevisionLookup(): RevisionLookup {
1781        return $this->getService( 'RevisionLookup' );
1782    }
1783
1784    /**
1785     * @since 1.32
1786     */
1787    public function getRevisionRenderer(): RevisionRenderer {
1788        return $this->getService( 'RevisionRenderer' );
1789    }
1790
1791    /**
1792     * @since 1.31
1793     */
1794    public function getRevisionStore(): RevisionStore {
1795        return $this->getService( 'RevisionStore' );
1796    }
1797
1798    /**
1799     * @since 1.32
1800     */
1801    public function getRevisionStoreFactory(): RevisionStoreFactory {
1802        return $this->getService( 'RevisionStoreFactory' );
1803    }
1804
1805    /**
1806     * @since 1.37
1807     */
1808    public function getRollbackPageFactory(): RollbackPageFactory {
1809        return $this->getService( 'RollbackPageFactory' );
1810    }
1811
1812    /**
1813     * @since 1.38
1814     */
1815    public function getRowCommentFormatter(): RowCommentFormatter {
1816        return $this->getService( 'RowCommentFormatter' );
1817    }
1818
1819    /**
1820     * @since 1.27
1821     */
1822    public function newSearchEngine(): SearchEngine {
1823        // New engine object every time, since they keep state
1824        return $this->getService( 'SearchEngineFactory' )->create();
1825    }
1826
1827    /**
1828     * @since 1.27
1829     */
1830    public function getSearchEngineConfig(): SearchEngineConfig {
1831        return $this->getService( 'SearchEngineConfig' );
1832    }
1833
1834    /**
1835     * @since 1.27
1836     */
1837    public function getSearchEngineFactory(): SearchEngineFactory {
1838        return $this->getService( 'SearchEngineFactory' );
1839    }
1840
1841    /**
1842     * @since 1.40
1843     */
1844    public function getSearchResultThumbnailProvider(): SearchResultThumbnailProvider {
1845        return $this->getService( 'SearchResultThumbnailProvider' );
1846    }
1847
1848    /**
1849     * @since 1.36
1850     */
1851    public function getShellboxClientFactory(): ShellboxClientFactory {
1852        return $this->getService( 'ShellboxClientFactory' );
1853    }
1854
1855    /**
1856     * @since 1.30
1857     */
1858    public function getShellCommandFactory(): CommandFactory {
1859        return $this->getService( 'ShellCommandFactory' );
1860    }
1861
1862    /**
1863     * @since 1.38
1864     */
1865    public function getSignatureValidatorFactory(): SignatureValidatorFactory {
1866        return $this->getService( 'SignatureValidatorFactory' );
1867    }
1868
1869    /**
1870     * @since 1.27
1871     */
1872    public function getSiteLookup(): SiteLookup {
1873        return $this->getService( 'SiteLookup' );
1874    }
1875
1876    /**
1877     * @since 1.27
1878     */
1879    public function getSiteStore(): SiteStore {
1880        return $this->getService( 'SiteStore' );
1881    }
1882
1883    /**
1884     * @since 1.27
1885     */
1886    public function getSkinFactory(): SkinFactory {
1887        return $this->getService( 'SkinFactory' );
1888    }
1889
1890    /**
1891     * @since 1.33
1892     */
1893    public function getSlotRoleRegistry(): SlotRoleRegistry {
1894        return $this->getService( 'SlotRoleRegistry' );
1895    }
1896
1897    /**
1898     * @since 1.31
1899     */
1900    public function getSlotRoleStore(): NameTableStore {
1901        return $this->getService( 'SlotRoleStore' );
1902    }
1903
1904    /**
1905     * @since 1.35
1906     */
1907    public function getSpamChecker(): SpamChecker {
1908        return $this->getService( 'SpamChecker' );
1909    }
1910
1911    /**
1912     * @since 1.32
1913     */
1914    public function getSpecialPageFactory(): SpecialPageFactory {
1915        return $this->getService( 'SpecialPageFactory' );
1916    }
1917
1918    /**
1919     * @since 1.27
1920     */
1921    public function getStatsdDataFactory(): IBufferingStatsdDataFactory {
1922        return $this->getService( 'StatsdDataFactory' );
1923    }
1924
1925    /**
1926     * @since 1.41
1927     */
1928    public function getStatsFactory(): StatsFactory {
1929        return $this->getService( 'StatsFactory' );
1930    }
1931
1932    /**
1933     * @since 1.35
1934     */
1935    public function getTalkPageNotificationManager(): TalkPageNotificationManager {
1936        return $this->getService( 'TalkPageNotificationManager' );
1937    }
1938
1939    /**
1940     * @since 1.34
1941     */
1942    public function getTempFSFileFactory(): TempFSFileFactory {
1943        return $this->getService( 'TempFSFileFactory' );
1944    }
1945
1946    /**
1947     * @since 1.39
1948     */
1949    public function getTempUserConfig(): RealTempUserConfig {
1950        return $this->getService( 'TempUserConfig' );
1951    }
1952
1953    /**
1954     * @since 1.39
1955     */
1956    public function getTempUserCreator(): TempUserCreator {
1957        return $this->getService( 'TempUserCreator' );
1958    }
1959
1960    /**
1961     * @since 1.36
1962     */
1963    public function getTidy(): TidyDriverBase {
1964        return $this->getService( 'Tidy' );
1965    }
1966
1967    /**
1968     * @since 1.35
1969     */
1970    public function getTitleFactory(): TitleFactory {
1971        return $this->getService( 'TitleFactory' );
1972    }
1973
1974    /**
1975     * @since 1.28
1976     */
1977    public function getTitleFormatter(): TitleFormatter {
1978        return $this->getService( 'TitleFormatter' );
1979    }
1980
1981    /**
1982     * @since 1.40
1983     */
1984    public function getTitleMatcher(): TitleMatcher {
1985        return $this->getService( 'TitleMatcher' );
1986    }
1987
1988    /**
1989     * @since 1.28
1990     */
1991    public function getTitleParser(): TitleParser {
1992        return $this->getService( 'TitleParser' );
1993    }
1994
1995    public function getTracer(): TracerInterface {
1996        return $this->getService( 'Tracer' );
1997    }
1998
1999    /**
2000     * @since 1.38
2001     */
2002    public function getTrackingCategories(): TrackingCategories {
2003        return $this->getService( 'TrackingCategories' );
2004    }
2005
2006    /**
2007     * @since 1.36
2008     */
2009    public function getUnblockUserFactory(): UnblockUserFactory {
2010        return $this->getService( 'UnblockUserFactory' );
2011    }
2012
2013    /**
2014     * @since 1.38
2015     */
2016    public function getUndeletePageFactory(): UndeletePageFactory {
2017        return $this->getService( 'UndeletePageFactory' );
2018    }
2019
2020    /**
2021     * @since 1.32
2022     */
2023    public function getUploadRevisionImporter(): UploadRevisionImporter {
2024        return $this->getService( 'UploadRevisionImporter' );
2025    }
2026
2027    /**
2028     * @since 1.39
2029     */
2030    public function getUrlUtils(): UrlUtils {
2031        return $this->getService( 'UrlUtils' );
2032    }
2033
2034    /**
2035     * @since 1.36
2036     * @deprecated since 1.43, use ActorStore
2037     */
2038    public function getUserCache(): UserCache {
2039        return $this->getService( 'UserCache' );
2040    }
2041
2042    /**
2043     * @since 1.35
2044     */
2045    public function getUserEditTracker(): UserEditTracker {
2046        return $this->getService( 'UserEditTracker' );
2047    }
2048
2049    /**
2050     * @since 1.35
2051     */
2052    public function getUserFactory(): UserFactory {
2053        return $this->getService( 'UserFactory' );
2054    }
2055
2056    /**
2057     * @since 1.35
2058     */
2059    public function getUserGroupManager(): UserGroupManager {
2060        return $this->getService( 'UserGroupManager' );
2061    }
2062
2063    /**
2064     * @since 1.35
2065     */
2066    public function getUserGroupManagerFactory(): UserGroupManagerFactory {
2067        return $this->getService( 'UserGroupManagerFactory' );
2068    }
2069
2070    /**
2071     * @since 1.36
2072     */
2073    public function getUserIdentityLookup(): UserIdentityLookup {
2074        return $this->getService( 'UserIdentityLookup' );
2075    }
2076
2077    /**
2078     * @since 1.41
2079     */
2080    public function getUserIdentityUtils(): UserIdentityUtils {
2081        return $this->getService( 'UserIdentityUtils' );
2082    }
2083
2084    /**
2085     * @since 1.36
2086     */
2087    public function getUserNamePrefixSearch(): UserNamePrefixSearch {
2088        return $this->getService( 'UserNamePrefixSearch' );
2089    }
2090
2091    /**
2092     * @since 1.35
2093     */
2094    public function getUserNameUtils(): UserNameUtils {
2095        return $this->getService( 'UserNameUtils' );
2096    }
2097
2098    /**
2099     * @since 1.35
2100     */
2101    public function getUserOptionsLookup(): UserOptionsLookup {
2102        return $this->getService( 'UserOptionsLookup' );
2103    }
2104
2105    /**
2106     * @since 1.35
2107     */
2108    public function getUserOptionsManager(): UserOptionsManager {
2109        return $this->getService( 'UserOptionsManager' );
2110    }
2111
2112    /**
2113     * @since 1.41
2114     */
2115    public function getUserRegistrationLookup(): UserRegistrationLookup {
2116        return $this->getService( 'UserRegistrationLookup' );
2117    }
2118
2119    /**
2120     * @since 1.28
2121     */
2122    public function getWatchedItemQueryService(): WatchedItemQueryService {
2123        return $this->getService( 'WatchedItemQueryService' );
2124    }
2125
2126    /**
2127     * @since 1.28
2128     */
2129    public function getWatchedItemStore(): WatchedItemStoreInterface {
2130        return $this->getService( 'WatchedItemStore' );
2131    }
2132
2133    /**
2134     * @since 1.36
2135     */
2136    public function getWatchlistManager(): WatchlistManager {
2137        return $this->getService( 'WatchlistManager' );
2138    }
2139
2140    /**
2141     * @since 1.38
2142     */
2143    public function getWikiExporterFactory(): WikiExporterFactory {
2144        return $this->getService( 'WikiExporterFactory' );
2145    }
2146
2147    /**
2148     * @since 1.37
2149     */
2150    public function getWikiImporterFactory(): WikiImporterFactory {
2151        return $this->getService( 'WikiImporterFactory' );
2152    }
2153
2154    /**
2155     * @since 1.36
2156     */
2157    public function getWikiPageFactory(): WikiPageFactory {
2158        return $this->getService( 'WikiPageFactory' );
2159    }
2160
2161    /**
2162     * @since 1.31
2163     */
2164    public function getWikiRevisionOldRevisionImporter(): OldRevisionImporter {
2165        return $this->getService( 'OldRevisionImporter' );
2166    }
2167
2168    /**
2169     * @since 1.31
2170     */
2171    public function getWikiRevisionOldRevisionImporterNoUpdates(): OldRevisionImporter {
2172        return $this->getService( 'WikiRevisionOldRevisionImporterNoUpdates' );
2173    }
2174
2175    /**
2176     * @since 1.31
2177     */
2178    public function getWikiRevisionUploadImporter(): UploadRevisionImporter {
2179        return $this->getService( 'UploadRevisionImporter' );
2180    }
2181
2182    /**
2183     * @since 1.39
2184     */
2185    public function getWRStatsFactory(): WRStatsFactory {
2186        return $this->getService( 'WRStatsFactory' );
2187    }
2188
2189}