ParsoidParser: Record ParserOptions watcher on ParserOutput object
[mediawiki.git] / includes / ServiceWiring.php
blob799b01445397ea2fb78a588d12bd4c1836a6b1ca
1 <?php
2 /**
3 * Service implementations for %MediaWiki core.
5 * This file returns the array loaded by the MediaWikiServices class
6 * for use through `MediaWiki\MediaWikiServices::getInstance()`
8 * @see [Dependency Injection](@ref dependencyinjection) in docs/Injection.md
9 * for the principles of DI and how to use it MediaWiki core.
11 * Reminder:
13 * - ServiceWiring is NOT a cache for arbitrary singletons.
15 * - Services MUST NOT vary their behaviour on global state, especially not
16 * WebRequest, RequestContext (T218555), or other details of the current
17 * request or CLI process (e.g. "current" user or title). Doing so may
18 * cause a chain reaction and cause serious data corruption.
20 * Refer to [DI Principles](@ref di-principles) in docs/Injection.md for
21 * how and why we avoid this, as well as for limited exemptions to these
22 * principles.
24 * -------
26 * This program is free software; you can redistribute it and/or modify
27 * it under the terms of the GNU General Public License as published by
28 * the Free Software Foundation; either version 2 of the License, or
29 * (at your option) any later version.
31 * This program is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 * GNU General Public License for more details.
36 * You should have received a copy of the GNU General Public License along
37 * with this program; if not, write to the Free Software Foundation, Inc.,
38 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
39 * http://www.gnu.org/copyleft/gpl.html
41 * @file
44 use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
45 use MediaWiki\Actions\ActionFactory;
46 use MediaWiki\Auth\AuthManager;
47 use MediaWiki\Auth\Throttler;
48 use MediaWiki\Block\BlockActionInfo;
49 use MediaWiki\Block\BlockErrorFormatter;
50 use MediaWiki\Block\BlockManager;
51 use MediaWiki\Block\BlockPermissionCheckerFactory;
52 use MediaWiki\Block\BlockRestrictionStore;
53 use MediaWiki\Block\BlockRestrictionStoreFactory;
54 use MediaWiki\Block\BlockUserFactory;
55 use MediaWiki\Block\BlockUtils;
56 use MediaWiki\Block\DatabaseBlock;
57 use MediaWiki\Block\DatabaseBlockStore;
58 use MediaWiki\Block\DatabaseBlockStoreFactory;
59 use MediaWiki\Block\UnblockUserFactory;
60 use MediaWiki\Block\UserBlockCommandFactory;
61 use MediaWiki\Cache\BacklinkCacheFactory;
62 use MediaWiki\Cache\LinkBatchFactory;
63 use MediaWiki\Category\TrackingCategories;
64 use MediaWiki\ChangeTags\ChangeTagsStore;
65 use MediaWiki\Collation\CollationFactory;
66 use MediaWiki\CommentFormatter\CommentFormatter;
67 use MediaWiki\CommentFormatter\CommentParserFactory;
68 use MediaWiki\CommentFormatter\RowCommentFormatter;
69 use MediaWiki\CommentStore\CommentStore;
70 use MediaWiki\Config\ConfigRepository;
71 use MediaWiki\Config\ServiceOptions;
72 use MediaWiki\Content\ContentHandlerFactory;
73 use MediaWiki\Content\IContentHandlerFactory;
74 use MediaWiki\Content\Renderer\ContentRenderer;
75 use MediaWiki\Content\Transform\ContentTransformer;
76 use MediaWiki\DAO\WikiAwareEntity;
77 use MediaWiki\Deferred\DeferredUpdatesManager;
78 use MediaWiki\Edit\ParsoidOutputStash;
79 use MediaWiki\Edit\SimpleParsoidOutputStash;
80 use MediaWiki\EditPage\Constraint\EditConstraintFactory;
81 use MediaWiki\EditPage\IntroMessageBuilder;
82 use MediaWiki\EditPage\PreloadedContentBuilder;
83 use MediaWiki\EditPage\SpamChecker;
84 use MediaWiki\Export\WikiExporterFactory;
85 use MediaWiki\FileBackend\FSFile\TempFSFileFactory;
86 use MediaWiki\FileBackend\LockManager\LockManagerGroupFactory;
87 use MediaWiki\HookContainer\FauxGlobalHookArray;
88 use MediaWiki\HookContainer\HookContainer;
89 use MediaWiki\HookContainer\HookRunner;
90 use MediaWiki\HookContainer\StaticHookRegistry;
91 use MediaWiki\Http\HttpRequestFactory;
92 use MediaWiki\Installer\Pingback;
93 use MediaWiki\Interwiki\ClassicInterwikiLookup;
94 use MediaWiki\Interwiki\InterwikiLookup;
95 use MediaWiki\JobQueue\JobFactory;
96 use MediaWiki\JobQueue\JobQueueGroupFactory;
97 use MediaWiki\Json\JsonCodec;
98 use MediaWiki\Languages\LanguageConverterFactory;
99 use MediaWiki\Languages\LanguageFactory;
100 use MediaWiki\Languages\LanguageFallback;
101 use MediaWiki\Languages\LanguageNameUtils;
102 use MediaWiki\Linker\LinkRenderer;
103 use MediaWiki\Linker\LinkRendererFactory;
104 use MediaWiki\Linker\LinksMigration;
105 use MediaWiki\Linker\LinkTargetLookup;
106 use MediaWiki\Linker\LinkTargetStore;
107 use MediaWiki\Logger\LoggerFactory;
108 use MediaWiki\Mail\Emailer;
109 use MediaWiki\Mail\EmailUser;
110 use MediaWiki\Mail\EmailUserFactory;
111 use MediaWiki\Mail\IEmailer;
112 use MediaWiki\MainConfigNames;
113 use MediaWiki\MediaWikiServices;
114 use MediaWiki\Message\MessageFormatterFactory;
115 use MediaWiki\Page\ContentModelChangeFactory;
116 use MediaWiki\Page\DeletePageFactory;
117 use MediaWiki\Page\File\BadFileLookup;
118 use MediaWiki\Page\MergeHistoryFactory;
119 use MediaWiki\Page\MovePageFactory;
120 use MediaWiki\Page\PageCommandFactory;
121 use MediaWiki\Page\PageProps;
122 use MediaWiki\Page\PageStore;
123 use MediaWiki\Page\PageStoreFactory;
124 use MediaWiki\Page\ParserOutputAccess;
125 use MediaWiki\Page\RedirectLookup;
126 use MediaWiki\Page\RedirectStore;
127 use MediaWiki\Page\RollbackPageFactory;
128 use MediaWiki\Page\UndeletePageFactory;
129 use MediaWiki\Page\WikiPageFactory;
130 use MediaWiki\Parser\MagicWordFactory;
131 use MediaWiki\Parser\ParserCacheFactory;
132 use MediaWiki\Parser\ParserObserver;
133 use MediaWiki\Parser\Parsoid\Config\DataAccess as MWDataAccess;
134 use MediaWiki\Parser\Parsoid\Config\PageConfigFactory as MWPageConfigFactory;
135 use MediaWiki\Parser\Parsoid\Config\SiteConfig as MWSiteConfig;
136 use MediaWiki\Parser\Parsoid\HtmlTransformFactory;
137 use MediaWiki\Parser\Parsoid\ParsoidOutputAccess;
138 use MediaWiki\Parser\Parsoid\ParsoidParserFactory;
139 use MediaWiki\Permissions\GrantsInfo;
140 use MediaWiki\Permissions\GrantsLocalization;
141 use MediaWiki\Permissions\GroupPermissionsLookup;
142 use MediaWiki\Permissions\PermissionManager;
143 use MediaWiki\Permissions\RateLimiter;
144 use MediaWiki\Permissions\RestrictionStore;
145 use MediaWiki\PoolCounter\PoolCounterFactory;
146 use MediaWiki\Preferences\DefaultPreferencesFactory;
147 use MediaWiki\Preferences\PreferencesFactory;
148 use MediaWiki\Preferences\SignatureValidator;
149 use MediaWiki\Preferences\SignatureValidatorFactory;
150 use MediaWiki\ResourceLoader\MessageBlobStore;
151 use MediaWiki\ResourceLoader\ResourceLoader;
152 use MediaWiki\Rest\Handler\Helper\PageRestHelperFactory;
153 use MediaWiki\Revision\ArchivedRevisionLookup;
154 use MediaWiki\Revision\ContributionsLookup;
155 use MediaWiki\Revision\MainSlotRoleHandler;
156 use MediaWiki\Revision\RevisionFactory;
157 use MediaWiki\Revision\RevisionLookup;
158 use MediaWiki\Revision\RevisionRenderer;
159 use MediaWiki\Revision\RevisionStore;
160 use MediaWiki\Revision\RevisionStoreFactory;
161 use MediaWiki\Revision\SlotRecord;
162 use MediaWiki\Revision\SlotRoleRegistry;
163 use MediaWiki\Search\SearchResultThumbnailProvider;
164 use MediaWiki\Search\TitleMatcher;
165 use MediaWiki\Settings\Config\ConfigSchema;
166 use MediaWiki\Settings\SettingsBuilder;
167 use MediaWiki\Shell\CommandFactory;
168 use MediaWiki\Shell\ShellboxClientFactory;
169 use MediaWiki\SpecialPage\SpecialPageFactory;
170 use MediaWiki\Storage\BlobStore;
171 use MediaWiki\Storage\BlobStoreFactory;
172 use MediaWiki\Storage\EditResultCache;
173 use MediaWiki\Storage\NameTableStore;
174 use MediaWiki\Storage\NameTableStoreFactory;
175 use MediaWiki\Storage\PageEditStash;
176 use MediaWiki\Storage\PageUpdaterFactory;
177 use MediaWiki\Storage\RevertedTagUpdateManager;
178 use MediaWiki\Storage\SqlBlobStore;
179 use MediaWiki\Tidy\RemexDriver;
180 use MediaWiki\Tidy\TidyDriverBase;
181 use MediaWiki\Title\TitleFactory;
182 use MediaWiki\User\ActorMigration;
183 use MediaWiki\User\ActorNormalization;
184 use MediaWiki\User\ActorStore;
185 use MediaWiki\User\ActorStoreFactory;
186 use MediaWiki\User\BotPasswordStore;
187 use MediaWiki\User\CentralId\CentralIdLookupFactory;
188 use MediaWiki\User\DefaultOptionsLookup;
189 use MediaWiki\User\TalkPageNotificationManager;
190 use MediaWiki\User\TempUser\RealTempUserConfig;
191 use MediaWiki\User\TempUser\TempUserCreator;
192 use MediaWiki\User\UserEditTracker;
193 use MediaWiki\User\UserFactory;
194 use MediaWiki\User\UserGroupManager;
195 use MediaWiki\User\UserGroupManagerFactory;
196 use MediaWiki\User\UserIdentity;
197 use MediaWiki\User\UserIdentityLookup;
198 use MediaWiki\User\UserNamePrefixSearch;
199 use MediaWiki\User\UserNameUtils;
200 use MediaWiki\User\UserOptionsLookup;
201 use MediaWiki\User\UserOptionsManager;
202 use MediaWiki\Utils\UrlUtils;
203 use MediaWiki\Watchlist\WatchlistManager;
204 use MediaWiki\WikiMap\WikiMap;
205 use Wikimedia\DependencyStore\KeyValueDependencyStore;
206 use Wikimedia\DependencyStore\SqlModuleDependencyStore;
207 use Wikimedia\EventRelayer\EventRelayerGroup;
208 use Wikimedia\Message\IMessageFormatterFactory;
209 use Wikimedia\ObjectFactory\ObjectFactory;
210 use Wikimedia\Parsoid\Config\Api\DataAccess as ApiDataAccess;
211 use Wikimedia\Parsoid\Config\Api\SiteConfig as ApiSiteConfig;
212 use Wikimedia\Parsoid\Config\DataAccess;
213 use Wikimedia\Parsoid\Config\SiteConfig;
214 use Wikimedia\Parsoid\Parsoid;
215 use Wikimedia\Rdbms\ConfiguredReadOnlyMode;
216 use Wikimedia\Rdbms\DatabaseFactory;
217 use Wikimedia\Rdbms\ReadOnlyMode;
218 use Wikimedia\RequestTimeout\CriticalSectionProvider;
219 use Wikimedia\RequestTimeout\RequestTimeout;
220 use Wikimedia\Stats\StatsCache;
221 use Wikimedia\Stats\StatsFactory;
222 use Wikimedia\UUID\GlobalIdGenerator;
223 use Wikimedia\WRStats\BagOStuffStatsStore;
224 use Wikimedia\WRStats\WRStatsFactory;
226 /** @phpcs-require-sorted-array */
227 return [
228 'ActionFactory' => static function ( MediaWikiServices $services ): ActionFactory {
229 return new ActionFactory(
230 $services->getMainConfig()->get( MainConfigNames::Actions ),
231 LoggerFactory::getInstance( 'ActionFactory' ),
232 $services->getObjectFactory(),
233 $services->getHookContainer()
237 'ActorMigration' => static function ( MediaWikiServices $services ): ActorMigration {
238 return new ActorMigration(
239 SCHEMA_COMPAT_NEW,
240 $services->getActorStoreFactory()
244 'ActorNormalization' => static function ( MediaWikiServices $services ): ActorNormalization {
245 return $services->getActorStoreFactory()->getActorNormalization();
248 'ActorStore' => static function ( MediaWikiServices $services ): ActorStore {
249 return $services->getActorStoreFactory()->getActorStore();
252 'ActorStoreFactory' => static function ( MediaWikiServices $services ): ActorStoreFactory {
253 return new ActorStoreFactory(
254 new ServiceOptions( ActorStoreFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
255 $services->getDBLoadBalancerFactory(),
256 $services->getUserNameUtils(),
257 LoggerFactory::getInstance( 'ActorStore' )
261 'ArchivedRevisionLookup' => static function ( MediaWikiServices $services ): ArchivedRevisionLookup {
262 return new ArchivedRevisionLookup(
263 $services->getDBLoadBalancerFactory(),
264 $services->getRevisionStore()
268 'AuthManager' => static function ( MediaWikiServices $services ): AuthManager {
269 $authManager = new AuthManager(
270 RequestContext::getMain()->getRequest(),
271 $services->getMainConfig(),
272 $services->getObjectFactory(),
273 $services->getHookContainer(),
274 $services->getReadOnlyMode(),
275 $services->getUserNameUtils(),
276 $services->getBlockManager(),
277 $services->getWatchlistManager(),
278 $services->getDBLoadBalancer(),
279 $services->getContentLanguage(),
280 $services->getLanguageConverterFactory(),
281 $services->getBotPasswordStore(),
282 $services->getUserFactory(),
283 $services->getUserIdentityLookup(),
284 $services->getUserOptionsManager()
286 $authManager->setLogger( LoggerFactory::getInstance( 'authentication' ) );
287 return $authManager;
290 'BacklinkCacheFactory' => static function ( MediaWikiServices $services ): BacklinkCacheFactory {
291 return new BacklinkCacheFactory(
292 $services->getMainWANObjectCache(),
293 $services->getHookContainer(),
294 $services->getDBLoadBalancerFactory()
298 'BadFileLookup' => static function ( MediaWikiServices $services ): BadFileLookup {
299 return new BadFileLookup(
300 static function () {
301 return wfMessage( 'bad_image_list' )->inContentLanguage()->plain();
303 $services->getLocalServerObjectCache(),
304 $services->getRepoGroup(),
305 $services->getTitleParser(),
306 $services->getHookContainer()
310 'BlobStore' => static function ( MediaWikiServices $services ): BlobStore {
311 return $services->getService( '_SqlBlobStore' );
314 'BlobStoreFactory' => static function ( MediaWikiServices $services ): BlobStoreFactory {
315 return new BlobStoreFactory(
316 $services->getDBLoadBalancerFactory(),
317 $services->getExternalStoreAccess(),
318 $services->getMainWANObjectCache(),
319 new ServiceOptions( BlobStoreFactory::CONSTRUCTOR_OPTIONS,
320 $services->getMainConfig() )
324 'BlockActionInfo' => static function ( MediaWikiServices $services ): BlockActionInfo {
325 return new BlockActionInfo( $services->getHookContainer() );
328 'BlockErrorFormatter' => static function ( MediaWikiServices $services ): BlockErrorFormatter {
329 return new BlockErrorFormatter(
330 $services->getTitleFormatter(),
331 $services->getHookContainer(),
332 $services->getUserNameUtils()
336 'BlockManager' => static function ( MediaWikiServices $services ): BlockManager {
337 return new BlockManager(
338 new ServiceOptions(
339 BlockManager::CONSTRUCTOR_OPTIONS,
340 $services->getMainConfig()
342 $services->getPermissionManager(),
343 $services->getUserFactory(),
344 LoggerFactory::getInstance( 'BlockManager' ),
345 $services->getHookContainer()
349 'BlockPermissionCheckerFactory' => static function (
350 MediaWikiServices $services
351 ): BlockPermissionCheckerFactory {
352 return new BlockPermissionCheckerFactory(
353 new ServiceOptions(
354 BlockPermissionCheckerFactory::CONSTRUCTOR_OPTIONS,
355 $services->getMainConfig()
357 $services->getBlockUtils()
361 'BlockRestrictionStore' => static function ( MediaWikiServices $services ): BlockRestrictionStore {
362 return $services->getBlockRestrictionStoreFactory()->getBlockRestrictionStore( WikiAwareEntity::LOCAL );
365 'BlockRestrictionStoreFactory' => static function ( MediaWikiServices $services ): BlockRestrictionStoreFactory {
366 return new BlockRestrictionStoreFactory(
367 $services->getDBLoadBalancerFactory()
371 'BlockUserFactory' => static function ( MediaWikiServices $services ): BlockUserFactory {
372 return $services->getService( '_UserBlockCommandFactory' );
375 'BlockUtils' => static function ( MediaWikiServices $services ): BlockUtils {
376 return new BlockUtils(
377 new ServiceOptions(
378 BlockUtils::CONSTRUCTOR_OPTIONS,
379 $services->getMainConfig()
381 $services->getUserIdentityLookup(),
382 $services->getUserNameUtils()
386 'BotPasswordStore' => static function ( MediaWikiServices $services ): BotPasswordStore {
387 return new BotPasswordStore(
388 new ServiceOptions(
389 BotPasswordStore::CONSTRUCTOR_OPTIONS,
390 $services->getMainConfig()
392 $services->getCentralIdLookup(),
393 $services->getDBLoadBalancerFactory()
397 'CentralIdLookup' => static function ( MediaWikiServices $services ): CentralIdLookup {
398 return $services->getCentralIdLookupFactory()->getLookup();
401 'CentralIdLookupFactory' => static function ( MediaWikiServices $services ): CentralIdLookupFactory {
402 return new CentralIdLookupFactory(
403 new ServiceOptions( CentralIdLookupFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
404 $services->getObjectFactory(),
405 $services->getUserIdentityLookup()
409 'ChangeTagDefStore' => static function ( MediaWikiServices $services ): NameTableStore {
410 return $services->getNameTableStoreFactory()->getChangeTagDef();
413 'ChangeTagsStore' => static function ( MediaWikiServices $services ): ChangeTagsStore {
414 return new ChangeTagsStore(
415 $services->getDBLoadBalancerFactory(),
416 $services->getChangeTagDefStore(),
417 $services->getMainWANObjectCache(),
418 $services->getHookContainer(),
419 LoggerFactory::getInstance( 'ChangeTags' ),
420 $services->getUserFactory(),
421 new ServiceOptions(
422 ChangeTagsStore::CONSTRUCTOR_OPTIONS,
423 $services->getMainConfig()
428 'CollationFactory' => static function ( MediaWikiServices $services ): CollationFactory {
429 return new CollationFactory(
430 new ServiceOptions(
431 CollationFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
432 $services->getObjectFactory(),
433 $services->getHookContainer()
437 'CommentFormatter' => static function ( MediaWikiServices $services ): CommentFormatter {
438 return new CommentFormatter(
439 $services->getCommentParserFactory()
443 'CommentParserFactory' => static function ( MediaWikiServices $services ): CommentParserFactory {
444 return new CommentParserFactory(
445 $services->getLinkRendererFactory()->create( [ 'renderForComment' => true ] ),
446 $services->getLinkBatchFactory(),
447 $services->getLinkCache(),
448 $services->getRepoGroup(),
449 RequestContext::getMain()->getLanguage(),
450 $services->getContentLanguage(),
451 $services->getTitleParser(),
452 $services->getNamespaceInfo(),
453 $services->getHookContainer()
457 'CommentStore' => static function ( MediaWikiServices $services ): CommentStore {
458 return new CommentStore(
459 $services->getContentLanguage(),
460 MIGRATION_NEW
464 'ConfigFactory' => static function ( MediaWikiServices $services ): ConfigFactory {
465 // Use the bootstrap config to initialize the ConfigFactory.
466 $registry = $services->getBootstrapConfig()->get( MainConfigNames::ConfigRegistry );
467 $factory = new ConfigFactory();
469 foreach ( $registry as $name => $callback ) {
470 $factory->register( $name, $callback );
472 return $factory;
475 'ConfigRepository' => static function ( MediaWikiServices $services ): ConfigRepository {
476 return new ConfigRepository( $services->getConfigFactory() );
479 'ConfigSchema' => static function ( MediaWikiServices $services ): ConfigSchema {
480 /** @var SettingsBuilder $settings */
481 $settings = $services->get( '_SettingsBuilder' );
482 return $settings->getConfigSchema();
485 'ConfiguredReadOnlyMode' => static function ( MediaWikiServices $services ): ConfiguredReadOnlyMode {
486 $config = $services->getMainConfig();
487 return new ConfiguredReadOnlyMode(
488 $config->get( MainConfigNames::ReadOnly ),
489 $config->get( MainConfigNames::ReadOnlyFile )
493 'ContentHandlerFactory' => static function ( MediaWikiServices $services ): IContentHandlerFactory {
494 $contentHandlerConfig = $services->getMainConfig()->get( MainConfigNames::ContentHandlers );
496 return new ContentHandlerFactory(
497 $contentHandlerConfig,
498 $services->getObjectFactory(),
499 $services->getHookContainer(),
500 LoggerFactory::getInstance( 'ContentHandler' )
504 'ContentLanguage' => static function ( MediaWikiServices $services ): Language {
505 return $services->getLanguageFactory()->getLanguage(
506 $services->getMainConfig()->get( MainConfigNames::LanguageCode ) );
509 'ContentModelChangeFactory' => static function ( MediaWikiServices $services ): ContentModelChangeFactory {
510 return $services->getService( '_PageCommandFactory' );
513 'ContentModelStore' => static function ( MediaWikiServices $services ): NameTableStore {
514 return $services->getNameTableStoreFactory()->getContentModels();
517 'ContentRenderer' => static function ( MediaWikiServices $services ): ContentRenderer {
518 return new ContentRenderer( $services->getContentHandlerFactory() );
521 'ContentTransformer' => static function ( MediaWikiServices $services ): ContentTransformer {
522 return new ContentTransformer( $services->getContentHandlerFactory() );
525 'ContributionsLookup' => static function ( MediaWikiServices $services ): ContributionsLookup {
526 return new ContributionsLookup(
527 $services->getRevisionStore(),
528 $services->getLinkRendererFactory(),
529 $services->getLinkBatchFactory(),
530 $services->getHookContainer(),
531 $services->getDBLoadBalancerFactory(),
532 $services->getActorMigration(),
533 $services->getNamespaceInfo(),
534 $services->getCommentFormatter()
538 'CriticalSectionProvider' => static function ( MediaWikiServices $services ): CriticalSectionProvider {
539 $config = $services->getMainConfig();
540 $limit = $GLOBALS[ 'wgCommandLineMode' ] ? INF : $config->get( MainConfigNames::CriticalSectionTimeLimit );
541 return RequestTimeout::singleton()->createCriticalSectionProvider( $limit );
544 'CryptHKDF' => static function ( MediaWikiServices $services ): CryptHKDF {
545 $config = $services->getMainConfig();
547 $secret = $config->get( MainConfigNames::HKDFSecret ) ?: $config->get( MainConfigNames::SecretKey );
548 if ( !$secret ) {
549 throw new RuntimeException( "Cannot use MWCryptHKDF without a secret." );
552 // In HKDF, the context can be known to the attacker, but this will
553 // keep simultaneous runs from producing the same output.
554 $context = [ microtime(), getmypid(), gethostname() ];
556 // Setup salt cache. Use APC, or fallback to the main cache if it isn't setup
557 $cache = $services->getLocalServerObjectCache();
558 if ( $cache instanceof EmptyBagOStuff ) {
559 $cache = ObjectCache::getLocalClusterInstance();
562 return new CryptHKDF( $secret, $config->get( MainConfigNames::HKDFAlgorithm ), $cache, $context );
565 'DatabaseBlockStore' => static function ( MediaWikiServices $services ): DatabaseBlockStore {
566 return $services->getDatabaseBlockStoreFactory()->getDatabaseBlockStore( DatabaseBlock::LOCAL );
569 'DatabaseBlockStoreFactory' => static function ( MediaWikiServices $services ): DatabaseBlockStoreFactory {
570 return new DatabaseBlockStoreFactory(
571 new ServiceOptions(
572 DatabaseBlockStoreFactory::CONSTRUCTOR_OPTIONS,
573 $services->getMainConfig()
575 LoggerFactory::getInstance( 'DatabaseBlockStore' ),
576 $services->getActorStoreFactory(),
577 $services->getBlockRestrictionStoreFactory(),
578 $services->getCommentStore(),
579 $services->getHookContainer(),
580 $services->getDBLoadBalancerFactory(),
581 $services->getConfiguredReadOnlyMode(),
582 $services->getUserFactory()
586 'DatabaseFactory' => static function ( MediaWikiServices $services ): DatabaseFactory {
587 return new DatabaseFactory();
590 'DateFormatterFactory' => static function ( MediaWikiServices $services ): DateFormatterFactory {
591 return new DateFormatterFactory();
594 'DBLoadBalancer' => static function ( MediaWikiServices $services ): Wikimedia\Rdbms\ILoadBalancer {
595 // just return the default LB from the DBLoadBalancerFactory service
596 return $services->getDBLoadBalancerFactory()->getMainLB();
599 'DBLoadBalancerFactory' =>
600 static function ( MediaWikiServices $services ): Wikimedia\Rdbms\LBFactory {
601 $mainConfig = $services->getMainConfig();
602 $lbFactoryConfigBuilder = $services->getDBLoadBalancerFactoryConfigBuilder();
604 $lbConf = $lbFactoryConfigBuilder->applyDefaultConfig(
605 $mainConfig->get( MainConfigNames::LBFactoryConf )
608 $class = $lbFactoryConfigBuilder->getLBFactoryClass( $lbConf );
609 $instance = new $class( $lbConf );
611 $lbFactoryConfigBuilder->setDomainAliases( $instance );
613 // NOTE: This accesses ProxyLookup from the MediaWikiServices singleton
614 // for non-essential non-nonimal purposes (via WebRequest::getIP).
615 // This state is fine (and meant) to be consistent for a given PHP process,
616 // even if applied to the service container for a different wiki.
617 $lbFactoryConfigBuilder->applyGlobalState(
618 $instance,
619 $mainConfig,
620 $services->getStatsdDataFactory()
623 return $instance;
626 'DBLoadBalancerFactoryConfigBuilder' => static function ( MediaWikiServices $services ): MWLBFactory {
627 $mainConfig = $services->getMainConfig();
628 $cpStashType = $mainConfig->get( MainConfigNames::ChronologyProtectorStash );
629 $cacheId = $mainConfig->get( MainConfigNames::MainCacheType );
630 $isMainCacheBad = ObjectCache::isDatabaseId( $cacheId );
631 if ( is_string( $cpStashType ) ) {
632 $cpStash = ObjectCache::getInstance( $cpStashType );
633 } elseif ( $isMainCacheBad ) {
634 $cpStash = new EmptyBagOStuff();
635 } else {
636 $cpStash = ObjectCache::getLocalClusterInstance();
639 if ( $isMainCacheBad ) {
640 $wanCache = WANObjectCache::newEmpty();
641 } else {
642 $wanCache = $services->getMainWANObjectCache();
645 $srvCache = $services->getLocalServerObjectCache();
646 if ( $srvCache instanceof EmptyBagOStuff ) {
647 // Use process cache if no APCU or other local-server cache (e.g. on CLI)
648 $srvCache = new HashBagOStuff( [ 'maxKeys' => 100 ] );
650 return new MWLBFactory(
651 new ServiceOptions( MWLBFactory::APPLY_DEFAULT_CONFIG_OPTIONS, $services->getMainConfig() ),
652 $services->getConfiguredReadOnlyMode(),
653 $cpStash,
654 $srvCache,
655 $wanCache,
656 $services->getCriticalSectionProvider(),
657 $services->getStatsdDataFactory()
661 'DeferredUpdatesManager' => static function ( MediaWikiServices $services ): DeferredUpdatesManager {
662 return new DeferredUpdatesManager(
663 new ServiceOptions(
664 DeferredUpdatesManager::CONSTRUCTOR_OPTIONS,
665 $services->getMainConfig()
667 LoggerFactory::getInstance( 'DeferredUpdates' ),
668 $services->getDBLoadBalancerFactory(),
669 $services->getStatsdDataFactory(),
670 $services->getJobQueueGroupFactory()
674 'DeletePageFactory' => static function ( MediaWikiServices $services ): DeletePageFactory {
675 return $services->getService( '_PageCommandFactory' );
678 'Emailer' => static function ( MediaWikiServices $services ): IEmailer {
679 return new Emailer();
682 'EmailUserFactory' => static function ( MediaWikiServices $services ): EmailUserFactory {
683 return new EmailUserFactory(
684 new ServiceOptions( EmailUser::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
685 $services->getHookContainer(),
686 $services->getUserOptionsLookup(),
687 $services->getCentralIdLookup(),
688 $services->getUserFactory(),
689 $services->getEmailer(),
690 $services->getMessageFormatterFactory(),
691 $services->getMessageFormatterFactory()->getTextFormatter( $services->getContentLanguage()->getCode() )
695 'EventRelayerGroup' => static function ( MediaWikiServices $services ): EventRelayerGroup {
696 return new EventRelayerGroup( $services->getMainConfig()->get( MainConfigNames::EventRelayerConfig ) );
699 'ExternalStoreAccess' => static function ( MediaWikiServices $services ): ExternalStoreAccess {
700 return new ExternalStoreAccess(
701 $services->getExternalStoreFactory(),
702 LoggerFactory::getInstance( 'ExternalStore' )
706 'ExternalStoreFactory' => static function ( MediaWikiServices $services ): ExternalStoreFactory {
707 $config = $services->getMainConfig();
708 $writeStores = $config->get( MainConfigNames::DefaultExternalStore );
710 return new ExternalStoreFactory(
711 $config->get( MainConfigNames::ExternalStores ),
712 ( $writeStores !== false ) ? (array)$writeStores : [],
713 $services->getDBLoadBalancer()->getLocalDomainID(),
714 LoggerFactory::getInstance( 'ExternalStore' )
718 'FileBackendGroup' => static function ( MediaWikiServices $services ): FileBackendGroup {
719 $mainConfig = $services->getMainConfig();
721 $ld = WikiMap::getCurrentWikiDbDomain();
722 $fallbackWikiId = WikiMap::getWikiIdFromDbDomain( $ld );
723 // If the local wiki ID and local domain ID do not match, probably due to a non-default
724 // schema, issue a warning. A non-default schema indicates that it might be used to
725 // disambiguate different wikis.
726 $legacyDomainId = strlen( $ld->getTablePrefix() )
727 ? "{$ld->getDatabase()}-{$ld->getTablePrefix()}"
728 : $ld->getDatabase();
729 if ( $ld->getSchema() !== null && $legacyDomainId !== $fallbackWikiId ) {
730 wfWarn(
731 "Legacy default 'domainId' is '$legacyDomainId' but wiki ID is '$fallbackWikiId'."
735 $cache = $services->getLocalServerObjectCache();
736 if ( $cache instanceof EmptyBagOStuff ) {
737 $cache = new HashBagOStuff();
740 return new FileBackendGroup(
741 new ServiceOptions( FileBackendGroup::CONSTRUCTOR_OPTIONS, $mainConfig,
742 [ 'fallbackWikiId' => $fallbackWikiId ] ),
743 $services->getConfiguredReadOnlyMode(),
744 $cache,
745 $services->getMainWANObjectCache(),
746 $services->getMimeAnalyzer(),
747 $services->getLockManagerGroupFactory(),
748 $services->getTempFSFileFactory(),
749 $services->getObjectFactory()
753 'GenderCache' => static function ( MediaWikiServices $services ): GenderCache {
754 $nsInfo = $services->getNamespaceInfo();
755 // Database layer may be disabled, so processing without database connection
756 $dbLoadBalancer = $services->isServiceDisabled( 'DBLoadBalancer' )
757 ? null
758 : $services->getDBLoadBalancer();
759 return new GenderCache( $nsInfo, $dbLoadBalancer, $services->get( '_DefaultOptionsLookup' ) );
762 'GlobalIdGenerator' => static function ( MediaWikiServices $services ): GlobalIdGenerator {
763 $mainConfig = $services->getMainConfig();
765 return new GlobalIdGenerator(
766 $mainConfig->get( MainConfigNames::TmpDirectory ),
767 static function ( $command ) {
768 return wfShellExec( $command );
773 'GrantsInfo' => static function ( MediaWikiServices $services ): GrantsInfo {
774 return new GrantsInfo(
775 new ServiceOptions(
776 GrantsInfo::CONSTRUCTOR_OPTIONS,
777 $services->getMainConfig()
782 'GrantsLocalization' => static function ( MediaWikiServices $services ): GrantsLocalization {
783 return new GrantsLocalization(
784 $services->getGrantsInfo(),
785 $services->getLinkRenderer(),
786 $services->getLanguageFactory(),
787 $services->getContentLanguage()
791 'GroupPermissionsLookup' => static function ( MediaWikiServices $services ): GroupPermissionsLookup {
792 return new GroupPermissionsLookup(
793 new ServiceOptions( GroupPermissionsLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig() )
797 'HookContainer' => static function ( MediaWikiServices $services ): HookContainer {
798 // NOTE: This is called while $services is being initialized, in order to call the
799 // MediaWikiServices hook.
801 $configHooks = $services->getBootstrapConfig()->get( MainConfigNames::Hooks );
803 // If we are instantiating this service after $wgHooks was replaced by a fake,
804 // get the original array out of the object. This should only happen in the installer,
805 // when it calls resetMediaWikiServices().
806 if ( $configHooks instanceof FauxGlobalHookArray ) {
807 $configHooks = $configHooks->getOriginalArray();
810 $extRegistry = ExtensionRegistry::getInstance();
811 $extHooks = $extRegistry->getAttribute( 'Hooks' );
812 $extDeprecatedHooks = $extRegistry->getAttribute( 'DeprecatedHooks' );
814 $hookRegistry = new StaticHookRegistry( $configHooks, $extHooks, $extDeprecatedHooks );
815 $hookContainer = new HookContainer(
816 $hookRegistry,
817 $services->getObjectFactory()
820 return $hookContainer;
823 'HtmlCacheUpdater' => static function ( MediaWikiServices $services ): HtmlCacheUpdater {
824 $config = $services->getMainConfig();
826 return new HtmlCacheUpdater(
827 $services->getHookContainer(),
828 $services->getTitleFactory(),
829 $config->get( MainConfigNames::CdnReboundPurgeDelay ),
830 $config->get( MainConfigNames::UseFileCache ),
831 $config->get( MainConfigNames::CdnMaxAge )
835 'HtmlTransformFactory' => static function ( MediaWikiServices $services ): HtmlTransformFactory {
836 return new HtmlTransformFactory(
837 $services->getService( '_Parsoid' ),
838 $services->getMainConfig()->get( MainConfigNames::ParsoidSettings ),
839 $services->getParsoidPageConfigFactory(),
840 $services->getContentHandlerFactory(),
841 $services->getParsoidSiteConfig(),
842 $services->getTitleFactory(),
843 $services->getLanguageConverterFactory(),
844 $services->getLanguageFactory()
848 'HttpRequestFactory' =>
849 static function ( MediaWikiServices $services ): HttpRequestFactory {
850 return new HttpRequestFactory(
851 new ServiceOptions(
852 HttpRequestFactory::CONSTRUCTOR_OPTIONS,
853 $services->getMainConfig()
855 LoggerFactory::getInstance( 'http' )
859 'InterwikiLookup' => static function ( MediaWikiServices $services ): InterwikiLookup {
860 return new ClassicInterwikiLookup(
861 new ServiceOptions(
862 ClassicInterwikiLookup::CONSTRUCTOR_OPTIONS,
863 $services->getMainConfig(),
864 [ 'wikiId' => WikiMap::getCurrentWikiId() ]
866 $services->getContentLanguage(),
867 $services->getMainWANObjectCache(),
868 $services->getHookContainer(),
869 $services->getDBLoadBalancer()
873 'IntroMessageBuilder' => static function ( MediaWikiServices $services ): IntroMessageBuilder {
874 return new IntroMessageBuilder(
875 $services->getMainConfig(),
876 $services->getLinkRenderer(),
877 $services->getPermissionManager(),
878 $services->getUserNameUtils(),
879 $services->getTempUserCreator(),
880 $services->getUserFactory(),
881 $services->getRestrictionStore(),
882 $services->getReadOnlyMode(),
883 $services->getSpecialPageFactory(),
884 $services->getRepoGroup(),
885 $services->getNamespaceInfo(),
886 $services->getSkinFactory()
890 'JobFactory' => static function ( MediaWikiServices $services ): JobFactory {
891 return new JobFactory(
892 $services->getObjectFactory(),
893 $services->getMainConfig()->get( MainConfigNames::JobClasses )
897 'JobQueueGroup' => static function ( MediaWikiServices $services ): JobQueueGroup {
898 return $services->getJobQueueGroupFactory()->makeJobQueueGroup();
901 'JobQueueGroupFactory' => static function ( MediaWikiServices $services ): JobQueueGroupFactory {
902 return new JobQueueGroupFactory(
903 new ServiceOptions( JobQueueGroupFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
904 $services->getConfiguredReadOnlyMode(),
905 $services->getStatsdDataFactory(),
906 $services->getMainWANObjectCache(),
907 $services->getGlobalIdGenerator()
911 'JobRunner' => static function ( MediaWikiServices $services ): JobRunner {
912 return new JobRunner(
913 new ServiceOptions( JobRunner::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
914 $services->getDBLoadBalancerFactory(),
915 $services->getJobQueueGroup(),
916 $services->getReadOnlyMode(),
917 $services->getLinkCache(),
918 $services->getStatsdDataFactory(),
919 LoggerFactory::getInstance( 'runJobs' )
923 'JsonCodec' => static function ( MediaWikiServices $services ): JsonCodec {
924 return new JsonCodec();
927 'LanguageConverterFactory' => static function ( MediaWikiServices $services ): LanguageConverterFactory {
928 $usePigLatinVariant = $services->getMainConfig()->get( MainConfigNames::UsePigLatinVariant );
929 $isConversionDisabled = $services->getMainConfig()->get( MainConfigNames::DisableLangConversion );
930 $isTitleConversionDisabled = $services->getMainConfig()->get( MainConfigNames::DisableTitleConversion );
931 return new LanguageConverterFactory(
932 $services->getObjectFactory(),
933 $usePigLatinVariant,
934 $isConversionDisabled,
935 $isTitleConversionDisabled,
936 static function () use ( $services ) {
937 return $services->getContentLanguage();
942 'LanguageFactory' => static function ( MediaWikiServices $services ): LanguageFactory {
943 return new LanguageFactory(
944 new ServiceOptions( LanguageFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
945 $services->getNamespaceInfo(),
946 $services->getLocalisationCache(),
947 $services->getLanguageNameUtils(),
948 $services->getLanguageFallback(),
949 $services->getLanguageConverterFactory(),
950 $services->getHookContainer(),
951 $services->getMainConfig()
955 'LanguageFallback' => static function ( MediaWikiServices $services ): LanguageFallback {
956 return new LanguageFallback(
957 $services->getMainConfig()->get( MainConfigNames::LanguageCode ),
958 $services->getLocalisationCache(),
959 $services->getLanguageNameUtils()
963 'LanguageNameUtils' => static function ( MediaWikiServices $services ): LanguageNameUtils {
964 return new LanguageNameUtils(
965 new ServiceOptions(
966 LanguageNameUtils::CONSTRUCTOR_OPTIONS,
967 $services->getMainConfig()
969 $services->getHookContainer()
973 'LinkBatchFactory' => static function ( MediaWikiServices $services ): LinkBatchFactory {
974 return new LinkBatchFactory(
975 $services->getLinkCache(),
976 $services->getTitleFormatter(),
977 $services->getContentLanguage(),
978 $services->getGenderCache(),
979 $services->getDBLoadBalancerFactory(),
980 $services->getLinksMigration(),
981 LoggerFactory::getInstance( 'LinkBatch' )
985 'LinkCache' => static function ( MediaWikiServices $services ): LinkCache {
986 // Database layer may be disabled, so processing without database connection
987 $dbLoadBalancer = $services->isServiceDisabled( 'DBLoadBalancer' )
988 ? null
989 : $services->getDBLoadBalancer();
990 $linkCache = new LinkCache(
991 $services->getTitleFormatter(),
992 $services->getMainWANObjectCache(),
993 $services->getNamespaceInfo(),
994 $dbLoadBalancer
996 $linkCache->setLogger( LoggerFactory::getInstance( 'LinkCache' ) );
997 return $linkCache;
1000 'LinkRenderer' => static function ( MediaWikiServices $services ): LinkRenderer {
1001 return $services->getLinkRendererFactory()->create();
1004 'LinkRendererFactory' => static function ( MediaWikiServices $services ): LinkRendererFactory {
1005 return new LinkRendererFactory(
1006 $services->getTitleFormatter(),
1007 $services->getLinkCache(),
1008 $services->getSpecialPageFactory(),
1009 $services->getHookContainer()
1013 'LinksMigration' => static function ( MediaWikiServices $services ): LinksMigration {
1014 return new LinksMigration(
1015 $services->getMainConfig(),
1016 $services->getLinkTargetLookup()
1020 'LinkTargetLookup' => static function ( MediaWikiServices $services ): LinkTargetLookup {
1021 return new LinkTargetStore(
1022 $services->getDBLoadBalancer(),
1023 $services->getLocalServerObjectCache(),
1024 $services->getMainWANObjectCache()
1028 'LocalisationCache' => static function ( MediaWikiServices $services ): LocalisationCache {
1029 $conf = $services->getMainConfig()->get( MainConfigNames::LocalisationCacheConf );
1031 $logger = LoggerFactory::getInstance( 'localisation' );
1033 $store = LocalisationCache::getStoreFromConf(
1034 $conf, $services->getMainConfig()->get( MainConfigNames::CacheDirectory ) );
1035 $logger->debug( 'LocalisationCache using store ' . get_class( $store ) );
1037 return new $conf['class'](
1038 new ServiceOptions(
1039 LocalisationCache::CONSTRUCTOR_OPTIONS,
1040 // Two of the options are stored in $wgLocalisationCacheConf
1041 $conf,
1042 // In case someone set that config variable and didn't reset all keys, set defaults.
1044 'forceRecache' => false,
1045 'manualRecache' => false,
1047 // Some other options come from config itself
1048 $services->getMainConfig()
1050 $store,
1051 $logger,
1052 [ static function () use ( $services ) {
1053 // NOTE: Make sure we use the same cache object that is assigned in the
1054 // constructor of the MessageBlobStore class used by ResourceLoader.
1055 // T231866: Avoid circular dependency via ResourceLoader.
1056 MessageBlobStore::clearGlobalCacheEntry( $services->getMainWANObjectCache() );
1057 } ],
1058 $services->getLanguageNameUtils(),
1059 $services->getHookContainer()
1063 'LocalServerObjectCache' => static function ( MediaWikiServices $services ): BagOStuff {
1064 return ObjectCache::makeLocalServerCache();
1067 'LockManagerGroupFactory' => static function ( MediaWikiServices $services ): LockManagerGroupFactory {
1068 return new LockManagerGroupFactory(
1069 WikiMap::getCurrentWikiDbDomain()->getId(),
1070 $services->getMainConfig()->get( MainConfigNames::LockManagers )
1074 'MagicWordFactory' => static function ( MediaWikiServices $services ): MagicWordFactory {
1075 return new MagicWordFactory(
1076 $services->getContentLanguage(),
1077 $services->getHookContainer()
1081 'MainConfig' => static function ( MediaWikiServices $services ): Config {
1082 // Use the 'main' config from the ConfigFactory service.
1083 return $services->getConfigFactory()->makeConfig( 'main' );
1086 'MainObjectStash' => static function ( MediaWikiServices $services ): BagOStuff {
1087 $mainConfig = $services->getMainConfig();
1089 $id = $mainConfig->get( MainConfigNames::MainStash );
1090 $params = $mainConfig->get( MainConfigNames::ObjectCaches )[$id] ?? null;
1091 if ( !$params ) {
1092 throw new ConfigException(
1093 "\$wgObjectCaches must have \"$id\" set (via \$wgMainStash)"
1097 $store = ObjectCache::newFromParams( $params, $services );
1098 $store->getLogger()->debug( 'MainObjectStash using store {class}', [
1099 'class' => get_class( $store )
1100 ] );
1102 return $store;
1105 'MainWANObjectCache' => static function ( MediaWikiServices $services ): WANObjectCache {
1106 $mainConfig = $services->getMainConfig();
1108 $store = $services->get( '_LocalClusterCache' );
1109 $logger = $store->getLogger();
1110 $logger->debug( 'MainWANObjectCache using store {class}', [
1111 'class' => get_class( $store )
1112 ] );
1114 $wanParams = $mainConfig->get( MainConfigNames::WANObjectCache ) + [
1115 'cache' => $store,
1116 'logger' => $logger,
1117 'secret' => $mainConfig->get( MainConfigNames::SecretKey ),
1119 if ( !$GLOBALS[ 'wgCommandLineMode' ] ) {
1120 // Send the statsd data post-send on HTTP requests; avoid in CLI mode (T181385)
1121 $wanParams['stats'] = $services->getStatsdDataFactory();
1122 // Let pre-emptive refreshes happen post-send on HTTP requests
1123 $wanParams['asyncHandler'] = [ DeferredUpdates::class, 'addCallableUpdate' ];
1125 return new WANObjectCache( $wanParams );
1128 'MediaHandlerFactory' => static function ( MediaWikiServices $services ): MediaHandlerFactory {
1129 return new MediaHandlerFactory(
1130 LoggerFactory::getInstance( 'MediaHandlerFactory' ),
1131 $services->getMainConfig()->get( MainConfigNames::MediaHandlers )
1135 'MergeHistoryFactory' => static function ( MediaWikiServices $services ): MergeHistoryFactory {
1136 return $services->getService( '_PageCommandFactory' );
1139 'MessageCache' => static function ( MediaWikiServices $services ): MessageCache {
1140 $mainConfig = $services->getMainConfig();
1141 $clusterCache = ObjectCache::getInstance( $mainConfig->get( MainConfigNames::MessageCacheType ) );
1142 $srvCache = $mainConfig->get( MainConfigNames::UseLocalMessageCache )
1143 ? $services->getLocalServerObjectCache()
1144 : new EmptyBagOStuff();
1146 $logger = LoggerFactory::getInstance( 'MessageCache' );
1147 $logger->debug( 'MessageCache using store {class}', [
1148 'class' => get_class( $clusterCache )
1149 ] );
1151 $options = new ServiceOptions( MessageCache::CONSTRUCTOR_OPTIONS, $mainConfig );
1153 return new MessageCache(
1154 $services->getMainWANObjectCache(),
1155 $clusterCache,
1156 $srvCache,
1157 $services->getContentLanguage(),
1158 $services->getLanguageConverterFactory(),
1159 $logger,
1160 $options,
1161 $services->getLanguageFactory(),
1162 $services->getLocalisationCache(),
1163 $services->getLanguageNameUtils(),
1164 $services->getLanguageFallback(),
1165 $services->getHookContainer()
1169 'MessageFormatterFactory' => static function ( MediaWikiServices $services ): IMessageFormatterFactory {
1170 return new MessageFormatterFactory();
1173 'MimeAnalyzer' => static function ( MediaWikiServices $services ): MimeAnalyzer {
1174 $logger = LoggerFactory::getInstance( 'Mime' );
1175 $mainConfig = $services->getMainConfig();
1176 $hookRunner = new HookRunner( $services->getHookContainer() );
1177 $params = [
1178 'typeFile' => $mainConfig->get( MainConfigNames::MimeTypeFile ),
1179 'infoFile' => $mainConfig->get( MainConfigNames::MimeInfoFile ),
1180 'xmlTypes' => $mainConfig->get( MainConfigNames::XMLMimeTypes ),
1181 'guessCallback' =>
1182 static function ( $mimeAnalyzer, &$head, &$tail, $file, &$mime )
1183 use ( $logger, $hookRunner ) {
1184 // Also test DjVu
1185 $deja = new DjVuImage( $file );
1186 if ( $deja->isValid() ) {
1187 $logger->info( "Detected $file as image/vnd.djvu\n" );
1188 $mime = 'image/vnd.djvu';
1190 return;
1192 // Some strings by reference for performance - assuming well-behaved hooks
1193 $hookRunner->onMimeMagicGuessFromContent(
1194 $mimeAnalyzer, $head, $tail, $file, $mime );
1196 'extCallback' => static function ( $mimeAnalyzer, $ext, &$mime ) use ( $hookRunner ) {
1197 // Media handling extensions can improve the MIME detected
1198 $hookRunner->onMimeMagicImproveFromExtension( $mimeAnalyzer, $ext, $mime );
1200 'initCallback' => static function ( $mimeAnalyzer ) use ( $hookRunner ) {
1201 // Allow media handling extensions adding MIME-types and MIME-info
1202 $hookRunner->onMimeMagicInit( $mimeAnalyzer );
1204 'logger' => $logger
1207 if ( $params['infoFile'] === 'includes/mime.info' ) {
1208 $params['infoFile'] = MimeAnalyzer::USE_INTERNAL;
1211 if ( $params['typeFile'] === 'includes/mime.types' ) {
1212 $params['typeFile'] = MimeAnalyzer::USE_INTERNAL;
1215 $detectorCmd = $mainConfig->get( MainConfigNames::MimeDetectorCommand );
1216 if ( $detectorCmd ) {
1217 $factory = $services->getShellCommandFactory();
1218 $params['detectCallback'] = static function ( $file ) use ( $detectorCmd, $factory ) {
1219 $result = $factory->create()
1220 // $wgMimeDetectorCommand can contain commands with parameters
1221 ->unsafeParams( $detectorCmd )
1222 ->params( $file )
1223 ->execute();
1224 return $result->getStdout();
1228 return new MimeAnalyzer( $params );
1231 'MovePageFactory' => static function ( MediaWikiServices $services ): MovePageFactory {
1232 return $services->getService( '_PageCommandFactory' );
1235 'NamespaceInfo' => static function ( MediaWikiServices $services ): NamespaceInfo {
1236 return new NamespaceInfo(
1237 new ServiceOptions( NamespaceInfo::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1238 $services->getHookContainer()
1242 'NameTableStoreFactory' => static function ( MediaWikiServices $services ): NameTableStoreFactory {
1243 return new NameTableStoreFactory(
1244 $services->getDBLoadBalancerFactory(),
1245 $services->getMainWANObjectCache(),
1246 LoggerFactory::getInstance( 'NameTableSqlStore' )
1250 'ObjectFactory' => static function ( MediaWikiServices $services ): ObjectFactory {
1251 return new ObjectFactory( $services );
1254 'OldRevisionImporter' => static function ( MediaWikiServices $services ): OldRevisionImporter {
1255 return new ImportableOldRevisionImporter(
1256 true,
1257 LoggerFactory::getInstance( 'OldRevisionImporter' ),
1258 $services->getDBLoadBalancer(),
1259 $services->getRevisionStore(),
1260 $services->getSlotRoleRegistry(),
1261 $services->getWikiPageFactory(),
1262 $services->getPageUpdaterFactory(),
1263 $services->getUserFactory()
1267 'PageEditStash' => static function ( MediaWikiServices $services ): PageEditStash {
1268 return new PageEditStash(
1269 ObjectCache::getLocalClusterInstance(),
1270 $services->getDBLoadBalancer(),
1271 LoggerFactory::getInstance( 'StashEdit' ),
1272 $services->getStatsdDataFactory(),
1273 $services->getUserEditTracker(),
1274 $services->getUserFactory(),
1275 $services->getWikiPageFactory(),
1276 $services->getHookContainer(),
1277 defined( 'MEDIAWIKI_JOB_RUNNER' ) || $GLOBALS[ 'wgCommandLineMode' ]
1278 ? PageEditStash::INITIATOR_JOB_OR_CLI
1279 : PageEditStash::INITIATOR_USER
1283 'PageProps' => static function ( MediaWikiServices $services ): PageProps {
1284 return new PageProps(
1285 $services->getLinkBatchFactory(),
1286 $services->getDBLoadBalancer()
1290 'PageRestHelperFactory' => static function ( MediaWikiServices $services ): PageRestHelperFactory {
1291 return new PageRestHelperFactory(
1292 new ServiceOptions( PageRestHelperFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1293 $services->getRevisionLookup(),
1294 $services->getTitleFormatter(),
1295 $services->getPageStore(),
1296 $services->getParsoidOutputStash(),
1297 $services->getStatsdDataFactory(),
1298 $services->getParsoidOutputAccess(),
1299 $services->getHtmlTransformFactory(),
1300 $services->getContentHandlerFactory(),
1301 $services->getLanguageFactory(),
1302 $services->getRedirectStore()
1306 'PageStore' => static function ( MediaWikiServices $services ): PageStore {
1307 return $services->getPageStoreFactory()->getPageStore();
1310 'PageStoreFactory' => static function ( MediaWikiServices $services ): PageStoreFactory {
1311 $options = new ServiceOptions(
1312 PageStoreFactory::CONSTRUCTOR_OPTIONS,
1313 $services->getMainConfig()
1316 return new PageStoreFactory(
1317 $options,
1318 $services->getDBLoadBalancerFactory(),
1319 $services->getNamespaceInfo(),
1320 $services->getTitleParser(),
1321 $services->getLinkCache(),
1322 $services->getStatsdDataFactory()
1326 'PageUpdaterFactory' => static function (
1327 MediaWikiServices $services
1328 ): PageUpdaterFactory {
1329 $editResultCache = new EditResultCache(
1330 $services->getMainObjectStash(),
1331 $services->getDBLoadBalancer(),
1332 new ServiceOptions(
1333 EditResultCache::CONSTRUCTOR_OPTIONS,
1334 $services->getMainConfig()
1338 return new PageUpdaterFactory(
1339 $services->getRevisionStore(),
1340 $services->getRevisionRenderer(),
1341 $services->getSlotRoleRegistry(),
1342 $services->getParserCache(),
1343 $services->getParsoidOutputAccess(),
1344 $services->getJobQueueGroup(),
1345 $services->getMessageCache(),
1346 $services->getContentLanguage(),
1347 $services->getDBLoadBalancerFactory(),
1348 $services->getContentHandlerFactory(),
1349 $services->getHookContainer(),
1350 $editResultCache,
1351 $services->getUserNameUtils(),
1352 LoggerFactory::getInstance( 'SavePage' ),
1353 new ServiceOptions(
1354 PageUpdaterFactory::CONSTRUCTOR_OPTIONS,
1355 $services->getMainConfig()
1357 $services->getUserEditTracker(),
1358 $services->getUserGroupManager(),
1359 $services->getTitleFormatter(),
1360 $services->getContentTransformer(),
1361 $services->getPageEditStash(),
1362 $services->getTalkPageNotificationManager(),
1363 $services->getMainWANObjectCache(),
1364 $services->getPermissionManager(),
1365 $services->getWikiPageFactory(),
1366 $services->getChangeTagsStore()->getSoftwareTags()
1370 'Parser' => static function ( MediaWikiServices $services ): Parser {
1371 return $services->getParserFactory()->getMainInstance();
1374 'ParserCache' => static function ( MediaWikiServices $services ): ParserCache {
1375 return $services->getParserCacheFactory()
1376 ->getParserCache( ParserCacheFactory::DEFAULT_NAME );
1379 'ParserCacheFactory' => static function ( MediaWikiServices $services ): ParserCacheFactory {
1380 $config = $services->getMainConfig();
1381 $cache = ObjectCache::getInstance( $config->get( MainConfigNames::ParserCacheType ) );
1382 $wanCache = $services->getMainWANObjectCache();
1384 $options = new ServiceOptions( ParserCacheFactory::CONSTRUCTOR_OPTIONS, $config );
1386 return new ParserCacheFactory(
1387 $cache,
1388 $wanCache,
1389 $services->getHookContainer(),
1390 $services->getJsonCodec(),
1391 $services->getStatsdDataFactory(),
1392 LoggerFactory::getInstance( 'ParserCache' ),
1393 $options,
1394 $services->getTitleFactory(),
1395 $services->getWikiPageFactory()
1399 'ParserFactory' => static function ( MediaWikiServices $services ): ParserFactory {
1400 $options = new ServiceOptions( Parser::CONSTRUCTOR_OPTIONS,
1401 $services->getMainConfig()
1404 return new ParserFactory(
1405 $options,
1406 $services->getMagicWordFactory(),
1407 $services->getContentLanguage(),
1408 $services->getUrlUtils(),
1409 $services->getSpecialPageFactory(),
1410 $services->getLinkRendererFactory(),
1411 $services->getNamespaceInfo(),
1412 LoggerFactory::getInstance( 'Parser' ),
1413 $services->getBadFileLookup(),
1414 $services->getLanguageConverterFactory(),
1415 $services->getHookContainer(),
1416 $services->getTidy(),
1417 $services->getMainWANObjectCache(),
1418 $services->getUserOptionsLookup(),
1419 $services->getUserFactory(),
1420 $services->getTitleFormatter(),
1421 $services->getHttpRequestFactory(),
1422 $services->getTrackingCategories(),
1423 $services->getSignatureValidatorFactory(),
1424 $services->getUserNameUtils()
1428 'ParserOutputAccess' => static function ( MediaWikiServices $services ): ParserOutputAccess {
1429 return new ParserOutputAccess(
1430 $services->getParserCacheFactory(),
1431 $services->getRevisionLookup(),
1432 $services->getRevisionRenderer(),
1433 $services->getStatsdDataFactory(),
1434 $services->getDBLoadBalancerFactory(),
1435 LoggerFactory::getProvider(),
1436 $services->getWikiPageFactory(),
1437 $services->getTitleFormatter()
1441 'ParsoidDataAccess' => static function ( MediaWikiServices $services ): DataAccess {
1442 $mainConfig = $services->getMainConfig();
1443 $parsoidSettings = $mainConfig->get( MainConfigNames::ParsoidSettings );
1444 if ( !empty( $parsoidSettings['debugApi'] ) ) {
1445 return ApiDataAccess::fromSettings( $parsoidSettings );
1447 return new MWDataAccess(
1448 new ServiceOptions( MWDataAccess::CONSTRUCTOR_OPTIONS, $mainConfig ),
1449 $services->getRepoGroup(),
1450 $services->getBadFileLookup(),
1451 $services->getHookContainer(),
1452 $services->getContentTransformer(),
1453 $services->getReadOnlyMode(),
1454 $services->getParserFactory(), // *legacy* parser factory
1455 $services->getLinkBatchFactory()
1459 'ParsoidOutputAccess' => static function ( MediaWikiServices $services ): ParsoidOutputAccess {
1460 return new ParsoidOutputAccess(
1461 new ServiceOptions(
1462 ParsoidOutputAccess::CONSTRUCTOR_OPTIONS,
1463 $services->getMainConfig(),
1464 [ 'ParsoidWikiID' => WikiMap::getCurrentWikiId() ]
1466 $services->getParserCacheFactory(),
1467 $services->getPageStore(),
1468 $services->getRevisionLookup(),
1469 $services->getGlobalIdGenerator(),
1470 $services->getStatsdDataFactory(),
1471 $services->getService( '_Parsoid' ),
1472 $services->getParsoidSiteConfig(),
1473 $services->getParsoidPageConfigFactory(),
1474 $services->getContentHandlerFactory()
1478 'ParsoidOutputStash' => static function ( MediaWikiServices $services ): ParsoidOutputStash {
1479 // TODO: Determine storage requirements and config options for stashing parsoid
1480 // output for VE edits (T309016).
1481 $config = $services->getMainConfig()->get( MainConfigNames::ParsoidCacheConfig );
1482 $backend = $config['StashType']
1483 ? ObjectCache::getInstance( $config['StashType'] )
1484 : $services->getMainObjectStash();
1486 return new SimpleParsoidOutputStash(
1487 $services->getContentHandlerFactory(),
1488 $backend,
1489 $config['StashDuration']
1493 'ParsoidPageConfigFactory' => static function ( MediaWikiServices $services ): MWPageConfigFactory {
1494 return new MWPageConfigFactory(
1495 $services->getRevisionStore(),
1496 $services->getSlotRoleRegistry(),
1497 $services->getLanguageFactory()
1501 'ParsoidParserFactory' => static function ( MediaWikiServices $services ): ParsoidParserFactory {
1502 return new ParsoidParserFactory(
1503 $services->getParsoidSiteConfig(),
1504 $services->getParsoidDataAccess(),
1505 $services->getParsoidPageConfigFactory(),
1506 $services->getLanguageConverterFactory(),
1507 $services->getParserFactory()
1511 'ParsoidSiteConfig' => static function ( MediaWikiServices $services ): SiteConfig {
1512 $mainConfig = $services->getMainConfig();
1513 $parsoidSettings = $mainConfig->get( MainConfigNames::ParsoidSettings );
1514 if ( !empty( $parsoidSettings['debugApi'] ) ) {
1515 return ApiSiteConfig::fromSettings( $parsoidSettings );
1517 return new MWSiteConfig(
1518 new ServiceOptions( MWSiteConfig::CONSTRUCTOR_OPTIONS, $mainConfig ),
1519 $parsoidSettings,
1520 $services->getObjectFactory(),
1521 $services->getContentLanguage(),
1522 $services->getStatsdDataFactory(),
1523 $services->getMagicWordFactory(),
1524 $services->getNamespaceInfo(),
1525 $services->getSpecialPageFactory(),
1526 $services->getInterwikiLookup(),
1527 $services->getUserOptionsLookup(),
1528 $services->getLanguageFactory(),
1529 $services->getLanguageConverterFactory(),
1530 $services->getLanguageNameUtils(),
1531 $services->getUrlUtils(),
1532 // These arguments are temporary and will be removed once
1533 // better solutions are found.
1534 $services->getParser(), // T268776
1535 $mainConfig // T268777
1539 'PasswordFactory' => static function ( MediaWikiServices $services ): PasswordFactory {
1540 $config = $services->getMainConfig();
1541 return new PasswordFactory(
1542 $config->get( MainConfigNames::PasswordConfig ),
1543 $config->get( MainConfigNames::PasswordDefault )
1547 'PasswordReset' => static function ( MediaWikiServices $services ): PasswordReset {
1548 $options = new ServiceOptions( PasswordReset::CONSTRUCTOR_OPTIONS, $services->getMainConfig() );
1549 return new PasswordReset(
1550 $options,
1551 LoggerFactory::getInstance( 'authentication' ),
1552 $services->getAuthManager(),
1553 $services->getHookContainer(),
1554 $services->getDBLoadBalancerFactory(),
1555 $services->getUserFactory(),
1556 $services->getUserNameUtils(),
1557 $services->getUserOptionsLookup()
1561 'PerDbNameStatsdDataFactory' =>
1562 static function ( MediaWikiServices $services ): StatsdDataFactoryInterface {
1563 $config = $services->getMainConfig();
1564 $wiki = $config->get( MainConfigNames::DBname );
1565 return new PrefixingStatsdDataFactoryProxy(
1566 $services->getStatsdDataFactory(),
1567 $wiki
1571 'PermissionManager' => static function ( MediaWikiServices $services ): PermissionManager {
1572 return new PermissionManager(
1573 new ServiceOptions(
1574 PermissionManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
1576 $services->getSpecialPageFactory(),
1577 $services->getNamespaceInfo(),
1578 $services->getGroupPermissionsLookup(),
1579 $services->getUserGroupManager(),
1580 $services->getBlockErrorFormatter(),
1581 $services->getHookContainer(),
1582 $services->getUserCache(),
1583 $services->getRedirectLookup(),
1584 $services->getRestrictionStore(),
1585 $services->getTitleFormatter(),
1586 $services->getTempUserConfig(),
1587 $services->getUserFactory(),
1588 $services->getActionFactory()
1592 'Pingback' => static function ( MediaWikiServices $services ): PingBack {
1593 return new Pingback(
1594 $services->getMainConfig(),
1595 $services->getDBLoadBalancerFactory(),
1596 ObjectCache::getLocalClusterInstance(),
1597 $services->getHttpRequestFactory(),
1598 LoggerFactory::getInstance( 'Pingback' )
1602 'PoolCounterFactory' => static function ( MediaWikiServices $services ): PoolCounterFactory {
1603 $mainConfig = $services->getMainConfig();
1604 return new PoolCounterFactory(
1605 $mainConfig->get( MainConfigNames::PoolCounterConf ),
1606 $mainConfig->get( MainConfigNames::PoolCountClientConf )
1610 'PreferencesFactory' => static function ( MediaWikiServices $services ): PreferencesFactory {
1611 $factory = new DefaultPreferencesFactory(
1612 new ServiceOptions(
1613 DefaultPreferencesFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1614 $services->getContentLanguage(),
1615 $services->getAuthManager(),
1616 $services->getLinkRendererFactory()->create(),
1617 $services->getNamespaceInfo(),
1618 $services->getPermissionManager(),
1619 $services->getLanguageConverterFactory()->getLanguageConverter(),
1620 $services->getLanguageNameUtils(),
1621 $services->getHookContainer(),
1622 $services->getUserOptionsManager(),
1623 $services->getLanguageConverterFactory(),
1624 $services->getParser(),
1625 $services->getSkinFactory(),
1626 $services->getUserGroupManager(),
1627 $services->getSignatureValidatorFactory(),
1628 $services->getMainConfig()
1630 $factory->setLogger( LoggerFactory::getInstance( 'preferences' ) );
1632 return $factory;
1635 'PreloadedContentBuilder' => static function ( MediaWikiServices $services ): PreloadedContentBuilder {
1636 return new PreloadedContentBuilder(
1637 $services->getContentHandlerFactory(),
1638 $services->getWikiPageFactory(),
1639 $services->getRedirectLookup(),
1640 $services->getSpecialPageFactory(),
1641 $services->getContentTransformer(),
1642 $services->getHookContainer(),
1646 'ProxyLookup' => static function ( MediaWikiServices $services ): ProxyLookup {
1647 $mainConfig = $services->getMainConfig();
1648 return new ProxyLookup(
1649 $mainConfig->get( MainConfigNames::CdnServers ),
1650 $mainConfig->get( MainConfigNames::CdnServersNoPurge ),
1651 $services->getHookContainer()
1655 'RateLimiter' => static function ( MediaWikiServices $services ): RateLimiter {
1656 $rateLimiter = new RateLimiter(
1657 new ServiceOptions( RateLimiter::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1658 $services->getWRStatsFactory(),
1659 $services->getCentralIdLookupFactory()->getNonLocalLookup(),
1660 $services->getUserFactory(),
1661 $services->getUserGroupManager(),
1662 $services->getHookContainer()
1665 $rateLimiter->setStats( $services->getStatsdDataFactory() );
1667 return $rateLimiter;
1670 'ReadOnlyMode' => static function ( MediaWikiServices $services ): ReadOnlyMode {
1671 return new ReadOnlyMode(
1672 $services->getConfiguredReadOnlyMode(),
1673 $services->getDBLoadBalancer()
1677 'RedirectLookup' => static function ( MediaWikiServices $services ): RedirectLookup {
1678 return $services->getRedirectStore();
1681 'RedirectStore' => static function ( MediaWikiServices $services ): RedirectStore {
1682 return new RedirectStore( $services->getWikiPageFactory() );
1685 'RepoGroup' => static function ( MediaWikiServices $services ): RepoGroup {
1686 $config = $services->getMainConfig();
1687 return new RepoGroup(
1688 $config->get( MainConfigNames::LocalFileRepo ),
1689 $config->get( MainConfigNames::ForeignFileRepos ),
1690 $services->getMainWANObjectCache(),
1691 $services->getMimeAnalyzer()
1695 'ResourceLoader' => static function ( MediaWikiServices $services ): ResourceLoader {
1696 $config = $services->getMainConfig();
1698 $maxage = $config->get( MainConfigNames::ResourceLoaderMaxage );
1699 $rl = new ResourceLoader(
1700 $config,
1701 LoggerFactory::getInstance( 'resourceloader' ),
1702 $config->get( MainConfigNames::ResourceLoaderUseObjectCacheForDeps )
1703 ? new KeyValueDependencyStore( $services->getMainObjectStash() )
1704 : new SqlModuleDependencyStore( $services->getDBLoadBalancer() ),
1706 'loadScript' => $config->get( MainConfigNames::LoadScript ),
1707 'maxageVersioned' => $maxage['versioned'] ?? null,
1708 'maxageUnversioned' => $maxage['unversioned'] ?? null,
1709 'useFileCache' => $config->get( MainConfigNames::UseFileCache ),
1713 $extRegistry = ExtensionRegistry::getInstance();
1714 // Attribute has precedence over config
1715 $modules = $extRegistry->getAttribute( 'ResourceModules' )
1716 + $config->get( MainConfigNames::ResourceModules );
1717 $moduleSkinStyles = $extRegistry->getAttribute( 'ResourceModuleSkinStyles' )
1718 + $config->get( MainConfigNames::ResourceModuleSkinStyles );
1720 $rl->setModuleSkinStyles( $moduleSkinStyles );
1721 $rl->addSource( $config->get( MainConfigNames::ResourceLoaderSources ) );
1723 // Core modules, then extension/skin modules
1724 $baseDir = $config->get( MainConfigNames::BaseDirectory );
1725 $rl->register( include "$baseDir/resources/Resources.php" );
1726 $rl->register( $modules );
1727 $hookRunner = new \MediaWiki\ResourceLoader\HookRunner( $services->getHookContainer() );
1728 $hookRunner->onResourceLoaderRegisterModules( $rl );
1730 $msgPosterAttrib = $extRegistry->getAttribute( 'MessagePosterModule' );
1731 $rl->register( 'mediawiki.messagePoster', [
1732 'localBasePath' => $baseDir,
1733 'debugRaw' => false,
1734 'scripts' => array_merge(
1736 "resources/src/mediawiki.messagePoster/factory.js",
1737 "resources/src/mediawiki.messagePoster/MessagePoster.js",
1738 "resources/src/mediawiki.messagePoster/WikitextMessagePoster.js",
1740 $msgPosterAttrib['scripts'] ?? []
1742 'dependencies' => array_merge(
1744 'oojs',
1745 'mediawiki.api',
1746 'mediawiki.ForeignApi',
1748 $msgPosterAttrib['dependencies'] ?? []
1750 'targets' => [ 'desktop', 'mobile' ],
1751 ] );
1753 if ( $config->get( MainConfigNames::EnableJavaScriptTest ) === true ) {
1754 $rl->registerTestModules();
1757 return $rl;
1760 'RestrictionStore' => static function ( MediaWikiServices $services ): RestrictionStore {
1761 return new RestrictionStore(
1762 new ServiceOptions(
1763 RestrictionStore::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
1765 $services->getMainWANObjectCache(),
1766 $services->getDBLoadBalancer(),
1767 $services->getLinkCache(),
1768 $services->getLinksMigration(),
1769 $services->getCommentStore(),
1770 $services->getHookContainer(),
1771 $services->getPageStore()
1775 'RevertedTagUpdateManager' => static function ( MediaWikiServices $services ): RevertedTagUpdateManager {
1776 $editResultCache = new EditResultCache(
1777 $services->getMainObjectStash(),
1778 $services->getDBLoadBalancer(),
1779 new ServiceOptions(
1780 EditResultCache::CONSTRUCTOR_OPTIONS,
1781 $services->getMainConfig()
1785 return new RevertedTagUpdateManager(
1786 $editResultCache,
1787 $services->getJobQueueGroup()
1791 'RevisionFactory' => static function ( MediaWikiServices $services ): RevisionFactory {
1792 return $services->getRevisionStore();
1795 'RevisionLookup' => static function ( MediaWikiServices $services ): RevisionLookup {
1796 return $services->getRevisionStore();
1799 'RevisionRenderer' => static function ( MediaWikiServices $services ): RevisionRenderer {
1800 $renderer = new RevisionRenderer(
1801 $services->getDBLoadBalancer(),
1802 $services->getSlotRoleRegistry(),
1803 $services->getContentRenderer()
1806 $renderer->setLogger( LoggerFactory::getInstance( 'SaveParse' ) );
1807 return $renderer;
1810 'RevisionStore' => static function ( MediaWikiServices $services ): RevisionStore {
1811 return $services->getRevisionStoreFactory()->getRevisionStore();
1814 'RevisionStoreFactory' => static function ( MediaWikiServices $services ): RevisionStoreFactory {
1815 return new RevisionStoreFactory(
1816 $services->getDBLoadBalancerFactory(),
1817 $services->getBlobStoreFactory(),
1818 $services->getNameTableStoreFactory(),
1819 $services->getSlotRoleRegistry(),
1820 $services->getMainWANObjectCache(),
1821 $services->getLocalServerObjectCache(),
1822 $services->getCommentStore(),
1823 $services->getActorMigration(),
1824 $services->getActorStoreFactory(),
1825 LoggerFactory::getInstance( 'RevisionStore' ),
1826 $services->getContentHandlerFactory(),
1827 $services->getPageStoreFactory(),
1828 $services->getTitleFactory(),
1829 $services->getHookContainer()
1833 'RollbackPageFactory' => static function ( MediaWikiServices $services ): RollbackPageFactory {
1834 return $services->get( '_PageCommandFactory' );
1837 'RowCommentFormatter' => static function ( MediaWikiServices $services ): RowCommentFormatter {
1838 return new RowCommentFormatter(
1839 $services->getCommentParserFactory(),
1840 $services->getCommentStore()
1844 'SearchEngineConfig' => static function ( MediaWikiServices $services ): SearchEngineConfig {
1845 // @todo This should not take a Config object, but it's not so easy to remove because it
1846 // exposes it in a getter, which is actually used.
1847 return new SearchEngineConfig(
1848 $services->getMainConfig(),
1849 $services->getContentLanguage(),
1850 $services->getHookContainer(),
1851 ExtensionRegistry::getInstance()->getAttribute( 'SearchMappings' ),
1852 $services->getUserOptionsLookup()
1856 'SearchEngineFactory' => static function ( MediaWikiServices $services ): SearchEngineFactory {
1857 return new SearchEngineFactory(
1858 $services->getSearchEngineConfig(),
1859 $services->getHookContainer(),
1860 $services->getDBLoadBalancer()
1864 'SearchResultThumbnailProvider' => static function ( MediaWikiServices $services ): SearchResultThumbnailProvider {
1865 return new SearchResultThumbnailProvider(
1866 $services->getRepoGroup(),
1867 $services->getHookContainer()
1871 'ShellboxClientFactory' => static function ( MediaWikiServices $services ): ShellboxClientFactory {
1872 $urls = $services->getMainConfig()->get( MainConfigNames::ShellboxUrls );
1874 return new ShellboxClientFactory(
1875 $services->getHttpRequestFactory(),
1876 $urls,
1877 $services->getMainConfig()->get( MainConfigNames::ShellboxSecretKey )
1881 'ShellCommandFactory' => static function ( MediaWikiServices $services ): CommandFactory {
1882 $config = $services->getMainConfig();
1884 $limits = [
1885 'time' => $config->get( MainConfigNames::MaxShellTime ),
1886 'walltime' => $config->get( MainConfigNames::MaxShellWallClockTime ),
1887 'memory' => $config->get( MainConfigNames::MaxShellMemory ),
1888 'filesize' => $config->get( MainConfigNames::MaxShellFileSize ),
1890 $cgroup = $config->get( MainConfigNames::ShellCgroup );
1891 $restrictionMethod = $config->get( MainConfigNames::ShellRestrictionMethod );
1893 $factory = new CommandFactory( $services->getShellboxClientFactory(),
1894 $limits, $cgroup, $restrictionMethod );
1895 $factory->setLogger( LoggerFactory::getInstance( 'exec' ) );
1896 $factory->logStderr();
1898 return $factory;
1901 'SignatureValidatorFactory' => static function ( MediaWikiServices $services ): SignatureValidatorFactory {
1902 return new SignatureValidatorFactory(
1903 new ServiceOptions(
1904 SignatureValidator::CONSTRUCTOR_OPTIONS,
1905 $services->getMainConfig()
1907 // Use a closure for ParserFactory to avoid a circular dependency
1908 static function () use ( $services ) {
1909 return $services->getParserFactory();
1911 $services->getSpecialPageFactory(),
1912 $services->getTitleFactory()
1916 'SiteLookup' => static function ( MediaWikiServices $services ): SiteLookup {
1917 // Use SiteStore as the SiteLookup as well. This was originally separated
1918 // to allow for a cacheable read-only interface, but this was never used.
1919 // SiteStore has caching (see below).
1920 return $services->getSiteStore();
1923 'SiteStore' => static function ( MediaWikiServices $services ): SiteStore {
1924 $rawSiteStore = new DBSiteStore( $services->getDBLoadBalancer() );
1926 $cache = $services->getLocalServerObjectCache();
1927 if ( $cache instanceof EmptyBagOStuff ) {
1928 $cache = ObjectCache::getLocalClusterInstance();
1931 return new CachingSiteStore( $rawSiteStore, $cache );
1934 /** @suppress PhanTypeInvalidCallableArrayKey */
1935 'SkinFactory' => static function ( MediaWikiServices $services ): SkinFactory {
1936 $factory = new SkinFactory(
1937 $services->getObjectFactory(),
1938 (array)$services->getMainConfig()->get( MainConfigNames::SkipSkins )
1941 $names = $services->getMainConfig()->get( MainConfigNames::ValidSkinNames );
1943 foreach ( $names as $name => $skin ) {
1944 if ( is_array( $skin ) ) {
1945 $spec = $skin;
1946 $displayName = $skin['displayname'] ?? $name;
1947 $skippable = $skin['skippable'] ?? null;
1948 } else {
1949 $displayName = $skin;
1950 $skippable = null;
1951 $spec = [
1952 'name' => $name,
1953 'class' => "Skin$skin"
1956 $factory->register( $name, $displayName, $spec, $skippable );
1959 // Register a hidden "fallback" skin
1960 $factory->register( 'fallback', 'Fallback', [
1961 'class' => SkinFallback::class,
1962 'args' => [
1964 'name' => 'fallback',
1965 'styles' => [ 'mediawiki.skinning.interface' ],
1966 'templateDirectory' => __DIR__ . '/skins/templates/fallback',
1969 ], true );
1970 // Register a hidden skin for api output
1971 $factory->register( 'apioutput', 'ApiOutput', [
1972 'class' => SkinApi::class,
1973 'args' => [
1975 'name' => 'apioutput',
1976 'styles' => [ 'mediawiki.skinning.interface' ],
1977 'templateDirectory' => __DIR__ . '/skins/templates/apioutput',
1980 ], true );
1982 return $factory;
1985 'SlotRoleRegistry' => static function ( MediaWikiServices $services ): SlotRoleRegistry {
1986 $registry = new SlotRoleRegistry(
1987 $services->getSlotRoleStore()
1990 $config = $services->getMainConfig();
1991 $contentHandlerFactory = $services->getContentHandlerFactory();
1992 $hookContainer = $services->getHookContainer();
1993 $titleFactory = $services->getTitleFactory();
1994 $registry->defineRole(
1995 SlotRecord::MAIN,
1996 static function () use ( $config, $contentHandlerFactory, $hookContainer, $titleFactory ) {
1997 return new MainSlotRoleHandler(
1998 $config->get( MainConfigNames::NamespaceContentModels ),
1999 $contentHandlerFactory,
2000 $hookContainer,
2001 $titleFactory
2006 return $registry;
2009 'SlotRoleStore' => static function ( MediaWikiServices $services ): NameTableStore {
2010 return $services->getNameTableStoreFactory()->getSlotRoles();
2013 'SpamChecker' => static function ( MediaWikiServices $services ): SpamChecker {
2014 return new SpamChecker(
2015 (array)$services->getMainConfig()->get( MainConfigNames::SpamRegex ),
2016 (array)$services->getMainConfig()->get( MainConfigNames::SummarySpamRegex )
2020 'SpecialPageFactory' => static function ( MediaWikiServices $services ): SpecialPageFactory {
2021 return new SpecialPageFactory(
2022 new ServiceOptions(
2023 SpecialPageFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
2024 $services->getContentLanguage(),
2025 $services->getObjectFactory(),
2026 $services->getTitleFactory(),
2027 $services->getHookContainer()
2031 'StatsCache' => static function ( MediaWikiServices $services ): StatsCache {
2032 return new StatsCache();
2035 'StatsdDataFactory' => static function ( MediaWikiServices $services ): IBufferingStatsdDataFactory {
2036 return new BufferingStatsdDataFactory(
2037 rtrim( $services->getMainConfig()->get( MainConfigNames::StatsdMetricPrefix ), '.' )
2041 'StatsFactory' => static function ( MediaWikiServices $services ): StatsFactory {
2042 $config = $services->getMainConfig();
2043 $format = \Wikimedia\Stats\OutputFormats::getFormatFromString(
2044 $config->get( MainConfigNames::StatsFormat ) ?? 'null'
2046 $cache = $services->getService( 'StatsCache' );
2047 $emitter = \Wikimedia\Stats\OutputFormats::getNewEmitter(
2048 $config->get( MainConfigNames::StatsPrefix ) ?? 'MediaWiki',
2049 $cache,
2050 \Wikimedia\Stats\OutputFormats::getNewFormatter( $format ),
2051 $config->get( MainConfigNames::StatsTarget )
2053 $factory = new StatsFactory( 'core', $cache, $emitter, LoggerFactory::getInstance( 'Stats' ) );
2054 return $factory->withStatsdDataFactory( $services->getStatsdDataFactory() );
2057 'TalkPageNotificationManager' => static function (
2058 MediaWikiServices $services
2059 ): TalkPageNotificationManager {
2060 return new TalkPageNotificationManager(
2061 new ServiceOptions(
2062 TalkPageNotificationManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
2064 $services->getDBLoadBalancerFactory(),
2065 $services->getReadOnlyMode(),
2066 $services->getRevisionLookup(),
2067 $services->getHookContainer(),
2068 $services->getUserFactory()
2072 'TempFSFileFactory' => static function ( MediaWikiServices $services ): TempFSFileFactory {
2073 return new TempFSFileFactory( $services->getMainConfig()->get( MainConfigNames::TmpDirectory ) );
2076 'TempUserConfig' => static function ( MediaWikiServices $services ): RealTempUserConfig {
2077 return new RealTempUserConfig(
2078 $services->getMainConfig()->get( MainConfigNames::AutoCreateTempUser )
2082 'TempUserCreator' => static function ( MediaWikiServices $services ): TempUserCreator {
2083 $accountCreationThrottle = $services->getMainConfig()->get( MainConfigNames::AccountCreationThrottle );
2084 // T306878: Handle old $wgAccountCreationThrottle format (number of attempts per 24 hours)
2085 if ( !is_array( $accountCreationThrottle ) ) {
2086 $accountCreationThrottle = [ [
2087 'count' => $accountCreationThrottle,
2088 'seconds' => 86400,
2089 ] ];
2092 return new TempUserCreator(
2093 $services->getTempUserConfig(),
2094 $services->getObjectFactory(),
2095 $services->getUserFactory(),
2096 $services->getAuthManager(),
2097 // This is supposed to match ThrottlePreAuthenticationProvider
2098 new Throttler(
2099 $accountCreationThrottle,
2101 'type' => 'acctcreate',
2102 'cache' => $services->getLocalServerObjectCache()
2108 'Tidy' => static function ( MediaWikiServices $services ): TidyDriverBase {
2109 return new RemexDriver(
2110 new ServiceOptions(
2111 RemexDriver::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
2116 'TitleFactory' => static function ( MediaWikiServices $services ): TitleFactory {
2117 return new TitleFactory();
2120 'TitleFormatter' => static function ( MediaWikiServices $services ): TitleFormatter {
2121 return $services->getService( '_MediaWikiTitleCodec' );
2124 'TitleMatcher' => static function ( MediaWikiServices $services ): TitleMatcher {
2125 return new TitleMatcher(
2126 new ServiceOptions(
2127 TitleMatcher::CONSTRUCTOR_OPTIONS,
2128 $services->getMainConfig()
2130 $services->getContentLanguage(),
2131 $services->getLanguageConverterFactory(),
2132 $services->getHookContainer(),
2133 $services->getWikiPageFactory(),
2134 $services->getUserNameUtils(),
2135 $services->getRepoGroup()
2139 'TitleParser' => static function ( MediaWikiServices $services ): TitleParser {
2140 return $services->getService( '_MediaWikiTitleCodec' );
2143 'TrackingCategories' => static function ( MediaWikiServices $services ): TrackingCategories {
2144 return new TrackingCategories(
2145 new ServiceOptions(
2146 TrackingCategories::CONSTRUCTOR_OPTIONS,
2147 $services->getMainConfig()
2149 $services->getNamespaceInfo(),
2150 $services->getTitleParser(),
2151 LoggerFactory::getInstance( 'TrackingCategories' )
2155 'UnblockUserFactory' => static function ( MediaWikiServices $services ): UnblockUserFactory {
2156 return $services->getService( '_UserBlockCommandFactory' );
2159 'UndeletePageFactory' => static function ( MediaWikiServices $services ): UndeletePageFactory {
2160 return $services->getService( '_PageCommandFactory' );
2163 'UploadRevisionImporter' => static function ( MediaWikiServices $services ): UploadRevisionImporter {
2164 return new ImportableUploadRevisionImporter(
2165 $services->getMainConfig()->get( MainConfigNames::EnableUploads ),
2166 LoggerFactory::getInstance( 'UploadRevisionImporter' )
2170 'UrlUtils' => static function ( MediaWikiServices $services ): UrlUtils {
2171 $config = $services->getMainConfig();
2172 return new UrlUtils( [
2173 UrlUtils::SERVER => $config->get( MainConfigNames::Server ),
2174 UrlUtils::CANONICAL_SERVER => $config->get( MainConfigNames::CanonicalServer ),
2175 UrlUtils::INTERNAL_SERVER => $config->get( MainConfigNames::InternalServer ),
2176 UrlUtils::FALLBACK_PROTOCOL => RequestContext::getMain()->getRequest()->getProtocol(),
2177 UrlUtils::HTTPS_PORT => $config->get( MainConfigNames::HttpsPort ),
2178 UrlUtils::VALID_PROTOCOLS => $config->get( MainConfigNames::UrlProtocols ),
2179 ] );
2182 'UserCache' => static function ( MediaWikiServices $services ): UserCache {
2183 return new UserCache(
2184 LoggerFactory::getInstance( 'UserCache' ),
2185 $services->getDBLoadBalancer(),
2186 $services->getLinkBatchFactory()
2190 'UserEditTracker' => static function ( MediaWikiServices $services ): UserEditTracker {
2191 return new UserEditTracker(
2192 $services->getActorMigration(),
2193 $services->getDBLoadBalancerFactory(),
2194 $services->getJobQueueGroup()
2198 'UserFactory' => static function ( MediaWikiServices $services ): UserFactory {
2199 return new UserFactory(
2200 new ServiceOptions(
2201 UserFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
2203 $services->getDBLoadBalancerFactory(),
2204 $services->getUserNameUtils()
2208 'UserGroupManager' => static function ( MediaWikiServices $services ): UserGroupManager {
2209 return $services->getUserGroupManagerFactory()->getUserGroupManager();
2212 'UserGroupManagerFactory' => static function ( MediaWikiServices $services ): UserGroupManagerFactory {
2213 return new UserGroupManagerFactory(
2214 new ServiceOptions(
2215 UserGroupManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
2217 $services->getConfiguredReadOnlyMode(),
2218 $services->getDBLoadBalancerFactory(),
2219 $services->getHookContainer(),
2220 $services->getUserEditTracker(),
2221 $services->getGroupPermissionsLookup(),
2222 $services->getJobQueueGroupFactory(),
2223 LoggerFactory::getInstance( 'UserGroupManager' ),
2224 $services->getTempUserConfig(),
2225 [ static function ( UserIdentity $user ) use ( $services ) {
2226 $services->getPermissionManager()->invalidateUsersRightsCache( $user );
2227 $services->getUserFactory()->newFromUserIdentity( $user )->invalidateCache();
2232 'UserIdentityLookup' => static function ( MediaWikiServices $services ): UserIdentityLookup {
2233 return $services->getActorStoreFactory()->getUserIdentityLookup();
2236 'UserNamePrefixSearch' => static function ( MediaWikiServices $services ): UserNamePrefixSearch {
2237 return new UserNamePrefixSearch(
2238 $services->getDBLoadBalancerFactory(),
2239 $services->getUserNameUtils()
2243 'UserNameUtils' => static function ( MediaWikiServices $services ): UserNameUtils {
2244 $messageFormatterFactory = new MessageFormatterFactory( Message::FORMAT_PLAIN );
2245 return new UserNameUtils(
2246 new ServiceOptions(
2247 UserNameUtils::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
2249 $services->getContentLanguage(),
2250 LoggerFactory::getInstance( 'UserNameUtils' ),
2251 $services->getTitleParser(),
2252 $messageFormatterFactory->getTextFormatter(
2253 $services->getContentLanguage()->getCode()
2255 $services->getHookContainer(),
2256 $services->getTempUserConfig()
2260 'UserOptionsLookup' => static function ( MediaWikiServices $services ): UserOptionsLookup {
2261 return $services->getUserOptionsManager();
2264 'UserOptionsManager' => static function ( MediaWikiServices $services ): UserOptionsManager {
2265 return new UserOptionsManager(
2266 new ServiceOptions( UserOptionsManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
2267 $services->get( '_DefaultOptionsLookup' ),
2268 $services->getLanguageConverterFactory(),
2269 $services->getDBLoadBalancerFactory(),
2270 LoggerFactory::getInstance( 'UserOptionsManager' ),
2271 $services->getHookContainer(),
2272 $services->getUserFactory(),
2273 $services->getUserNameUtils()
2277 'VirtualRESTServiceClient' =>
2278 static function ( MediaWikiServices $services ): VirtualRESTServiceClient {
2279 $config = $services->getMainConfig()->get( MainConfigNames::VirtualRestConfig );
2281 $vrsClient = new VirtualRESTServiceClient(
2282 $services->getHttpRequestFactory()->createMultiClient() );
2283 foreach ( $config['paths'] as $prefix => $serviceConfig ) {
2284 $class = $serviceConfig['class'];
2285 // Merge in the global defaults
2286 $constructArg = $serviceConfig['options'] ?? [];
2287 $constructArg += $config['global'];
2288 // Make the VRS service available at the mount point
2289 $vrsClient->mount( $prefix, [ 'class' => $class, 'config' => $constructArg ] );
2292 return $vrsClient;
2295 'WatchedItemQueryService' =>
2296 static function ( MediaWikiServices $services ): WatchedItemQueryService {
2297 return new WatchedItemQueryService(
2298 $services->getDBLoadBalancer(),
2299 $services->getCommentStore(),
2300 $services->getWatchedItemStore(),
2301 $services->getHookContainer(),
2302 $services->getUserOptionsLookup(),
2303 $services->getMainConfig()->get( MainConfigNames::WatchlistExpiry ),
2304 $services->getMainConfig()->get( MainConfigNames::MaxExecutionTimeForExpensiveQueries )
2308 'WatchedItemStore' => static function ( MediaWikiServices $services ): WatchedItemStore {
2309 $store = new WatchedItemStore(
2310 new ServiceOptions( WatchedItemStore::CONSTRUCTOR_OPTIONS,
2311 $services->getMainConfig() ),
2312 $services->getDBLoadBalancerFactory(),
2313 $services->getJobQueueGroup(),
2314 $services->getMainObjectStash(),
2315 new HashBagOStuff( [ 'maxKeys' => 100 ] ),
2316 $services->getReadOnlyMode(),
2317 $services->getNamespaceInfo(),
2318 $services->getRevisionLookup(),
2319 $services->getLinkBatchFactory()
2321 $store->setStatsdDataFactory( $services->getStatsdDataFactory() );
2323 if ( $services->getMainConfig()->get( MainConfigNames::ReadOnlyWatchedItemStore ) ) {
2324 $store = new NoWriteWatchedItemStore( $store );
2327 return $store;
2330 'WatchlistManager' => static function ( MediaWikiServices $services ): WatchlistManager {
2331 return new WatchlistManager(
2333 WatchlistManager::OPTION_ENOTIF =>
2334 RecentChange::isEnotifEnabled( $services->getMainConfig() ),
2336 $services->getHookContainer(),
2337 $services->getReadOnlyMode(),
2338 $services->getRevisionLookup(),
2339 $services->getTalkPageNotificationManager(),
2340 $services->getWatchedItemStore(),
2341 $services->getUserFactory(),
2342 $services->getNamespaceInfo(),
2343 $services->getWikiPageFactory()
2347 'WikiExporterFactory' => static function ( MediaWikiServices $services ): WikiExporterFactory {
2348 return new WikiExporterFactory(
2349 $services->getHookContainer(),
2350 $services->getRevisionStore(),
2351 $services->getTitleParser(),
2352 $services->getCommentStore()
2356 'WikiImporterFactory' => static function ( MediaWikiServices $services ): WikiImporterFactory {
2357 return new WikiImporterFactory(
2358 $services->getMainConfig(),
2359 $services->getHookContainer(),
2360 $services->getContentLanguage(),
2361 $services->getNamespaceInfo(),
2362 $services->getTitleFactory(),
2363 $services->getWikiPageFactory(),
2364 $services->getWikiRevisionUploadImporter(),
2365 $services->getPermissionManager(),
2366 $services->getContentHandlerFactory(),
2367 $services->getSlotRoleRegistry()
2371 'WikiPageFactory' => static function ( MediaWikiServices $services ): WikiPageFactory {
2372 return new WikiPageFactory(
2373 $services->getTitleFactory(),
2374 new HookRunner( $services->getHookContainer() ),
2375 $services->getDBLoadBalancer()
2379 'WikiRevisionOldRevisionImporterNoUpdates' =>
2380 static function ( MediaWikiServices $services ): ImportableOldRevisionImporter {
2381 return new ImportableOldRevisionImporter(
2382 false,
2383 LoggerFactory::getInstance( 'OldRevisionImporter' ),
2384 $services->getDBLoadBalancer(),
2385 $services->getRevisionStore(),
2386 $services->getSlotRoleRegistry(),
2387 $services->getWikiPageFactory(),
2388 $services->getPageUpdaterFactory(),
2389 $services->getUserFactory()
2393 'WRStatsFactory' => static function ( MediaWikiServices $services ): WRStatsFactory {
2394 return new WRStatsFactory(
2395 new BagOStuffStatsStore(
2396 ObjectCache::getInstance( $services->getMainConfig()->get( MainConfigNames::StatsCacheType ) )
2401 '_DefaultOptionsLookup' => static function ( MediaWikiServices $services ): DefaultOptionsLookup {
2402 return new DefaultOptionsLookup(
2403 new ServiceOptions( DefaultOptionsLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
2404 $services->getContentLanguage(),
2405 $services->getHookContainer(),
2406 $services->getNamespaceInfo()
2410 '_EditConstraintFactory' => static function ( MediaWikiServices $services ): EditConstraintFactory {
2411 // This service is internal and currently only exists because a significant number
2412 // of dependencies will be needed by different constraints. It is not part of
2413 // the public interface and has no corresponding method in MediaWikiServices
2414 return new EditConstraintFactory(
2415 // Multiple
2416 new ServiceOptions(
2417 EditConstraintFactory::CONSTRUCTOR_OPTIONS,
2418 $services->getMainConfig()
2420 LoggerFactory::getProvider(),
2422 // UserBlockConstraint
2423 $services->getPermissionManager(),
2425 // EditFilterMergedContentHookConstraint
2426 $services->getHookContainer(),
2428 // ReadOnlyConstraint
2429 $services->getReadOnlyMode(),
2431 // SpamRegexConstraint
2432 $services->getSpamChecker()
2436 '_LocalClusterCache' => static function ( MediaWikiServices $services ): BagOStuff {
2437 $mainConfig = $services->getMainConfig();
2438 $id = $mainConfig->get( MainConfigNames::MainCacheType );
2439 $params = $mainConfig->get( MainConfigNames::ObjectCaches )[$id] ?? null;
2440 if ( !$params ) {
2441 throw new ConfigException(
2442 "\$wgObjectCaches must have \"$id\" set (via \$wgMainCacheType)"
2445 return ObjectCache::newFromParams( $params, $services );
2448 '_MediaWikiTitleCodec' => static function ( MediaWikiServices $services ): MediaWikiTitleCodec {
2449 return new MediaWikiTitleCodec(
2450 $services->getContentLanguage(),
2451 $services->getGenderCache(),
2452 $services->getMainConfig()->get( MainConfigNames::LocalInterwikis ),
2453 $services->getInterwikiLookup(),
2454 $services->getNamespaceInfo()
2458 '_PageCommandFactory' => static function ( MediaWikiServices $services ): PageCommandFactory {
2459 return new PageCommandFactory(
2460 $services->getMainConfig(),
2461 $services->getDBLoadBalancerFactory(),
2462 $services->getNamespaceInfo(),
2463 $services->getWatchedItemStore(),
2464 $services->getRepoGroup(),
2465 $services->getReadOnlyMode(),
2466 $services->getContentHandlerFactory(),
2467 $services->getRevisionStore(),
2468 $services->getSpamChecker(),
2469 $services->getTitleFormatter(),
2470 $services->getHookContainer(),
2471 $services->getWikiPageFactory(),
2472 $services->getUserFactory(),
2473 $services->getActorMigration(),
2474 $services->getActorNormalization(),
2475 $services->getTitleFactory(),
2476 $services->getUserEditTracker(),
2477 $services->getCollationFactory(),
2478 $services->getJobQueueGroup(),
2479 $services->getCommentStore(),
2480 $services->getMainObjectStash(),
2481 WikiMap::getCurrentWikiDbDomain()->getId(),
2482 WebRequest::getRequestId(),
2483 $services->getBacklinkCacheFactory(),
2484 LoggerFactory::getInstance( 'UndeletePage' ),
2485 $services->getPageUpdaterFactory(),
2486 $services->getMessageFormatterFactory()->getTextFormatter(
2487 $services->getContentLanguage()->getCode()
2489 $services->getArchivedRevisionLookup(),
2490 $services->getRestrictionStore(),
2491 $services->getDeferredUpdatesManager()
2495 '_ParserObserver' => static function ( MediaWikiServices $services ): ParserObserver {
2496 return new ParserObserver( LoggerFactory::getInstance( 'DuplicateParse' ) );
2499 '_Parsoid' => static function ( MediaWikiServices $services ): Parsoid {
2500 return new Parsoid(
2501 $services->getParsoidSiteConfig(),
2502 $services->getParsoidDataAccess()
2506 '_SettingsBuilder' => static function ( MediaWikiServices $services ): SettingsBuilder {
2507 return SettingsBuilder::getInstance();
2510 '_SqlBlobStore' => static function ( MediaWikiServices $services ): SqlBlobStore {
2511 return $services->getBlobStoreFactory()->newSqlBlobStore();
2514 '_UserBlockCommandFactory' => static function ( MediaWikiServices $services ): UserBlockCommandFactory {
2515 return new UserBlockCommandFactory(
2516 new ServiceOptions( UserBlockCommandFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
2517 $services->getHookContainer(),
2518 $services->getBlockPermissionCheckerFactory(),
2519 $services->getBlockUtils(),
2520 $services->getDatabaseBlockStore(),
2521 $services->getBlockRestrictionStore(),
2522 $services->getUserFactory(),
2523 $services->getUserEditTracker(),
2524 LoggerFactory::getInstance( 'BlockManager' ),
2525 $services->getTitleFactory(),
2526 $services->getBlockActionInfo()
2530 ///////////////////////////////////////////////////////////////////////////
2531 // NOTE: When adding a service here, don't forget to add a getter function
2532 // in the MediaWikiServices class. The convenience getter should just call
2533 // $this->getService( 'FooBarService' ).
2534 ///////////////////////////////////////////////////////////////////////////