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