Start 1.41.1
[mediawiki.git] / includes / ServiceWiring.php
blob9f64b7f8b7d5308478f2ffcc05931750a20e6983
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\Config;
71 use MediaWiki\Config\ConfigException;
72 use MediaWiki\Config\ConfigFactory;
73 use MediaWiki\Config\ConfigRepository;
74 use MediaWiki\Config\ServiceOptions;
75 use MediaWiki\Content\ContentHandlerFactory;
76 use MediaWiki\Content\IContentHandlerFactory;
77 use MediaWiki\Content\Renderer\ContentRenderer;
78 use MediaWiki\Content\Transform\ContentTransformer;
79 use MediaWiki\DAO\WikiAwareEntity;
80 use MediaWiki\Edit\ParsoidOutputStash;
81 use MediaWiki\Edit\SimpleParsoidOutputStash;
82 use MediaWiki\EditPage\Constraint\EditConstraintFactory;
83 use MediaWiki\EditPage\IntroMessageBuilder;
84 use MediaWiki\EditPage\PreloadedContentBuilder;
85 use MediaWiki\EditPage\SpamChecker;
86 use MediaWiki\Export\WikiExporterFactory;
87 use MediaWiki\FileBackend\FSFile\TempFSFileFactory;
88 use MediaWiki\FileBackend\LockManager\LockManagerGroupFactory;
89 use MediaWiki\HookContainer\FauxGlobalHookArray;
90 use MediaWiki\HookContainer\HookContainer;
91 use MediaWiki\HookContainer\HookRunner;
92 use MediaWiki\HookContainer\StaticHookRegistry;
93 use MediaWiki\Http\HttpRequestFactory;
94 use MediaWiki\Http\Telemetry;
95 use MediaWiki\Installer\Pingback;
96 use MediaWiki\Interwiki\ClassicInterwikiLookup;
97 use MediaWiki\Interwiki\InterwikiLookup;
98 use MediaWiki\JobQueue\JobFactory;
99 use MediaWiki\JobQueue\JobQueueGroupFactory;
100 use MediaWiki\Json\JsonCodec;
101 use MediaWiki\Languages\LanguageConverterFactory;
102 use MediaWiki\Languages\LanguageFactory;
103 use MediaWiki\Languages\LanguageFallback;
104 use MediaWiki\Languages\LanguageNameUtils;
105 use MediaWiki\Linker\LinkRenderer;
106 use MediaWiki\Linker\LinkRendererFactory;
107 use MediaWiki\Linker\LinksMigration;
108 use MediaWiki\Linker\LinkTargetLookup;
109 use MediaWiki\Linker\LinkTargetStore;
110 use MediaWiki\Logger\LoggerFactory;
111 use MediaWiki\Mail\Emailer;
112 use MediaWiki\Mail\EmailUser;
113 use MediaWiki\Mail\EmailUserFactory;
114 use MediaWiki\Mail\IEmailer;
115 use MediaWiki\MainConfigNames;
116 use MediaWiki\MediaWikiServices;
117 use MediaWiki\Message\MessageFormatterFactory;
118 use MediaWiki\Page\ContentModelChangeFactory;
119 use MediaWiki\Page\DeletePageFactory;
120 use MediaWiki\Page\File\BadFileLookup;
121 use MediaWiki\Page\MergeHistoryFactory;
122 use MediaWiki\Page\MovePageFactory;
123 use MediaWiki\Page\PageCommandFactory;
124 use MediaWiki\Page\PageProps;
125 use MediaWiki\Page\PageStore;
126 use MediaWiki\Page\PageStoreFactory;
127 use MediaWiki\Page\ParserOutputAccess;
128 use MediaWiki\Page\RedirectLookup;
129 use MediaWiki\Page\RedirectStore;
130 use MediaWiki\Page\RollbackPageFactory;
131 use MediaWiki\Page\UndeletePageFactory;
132 use MediaWiki\Page\WikiPageFactory;
133 use MediaWiki\Parser\MagicWordFactory;
134 use MediaWiki\Parser\ParserCacheFactory;
135 use MediaWiki\Parser\ParserObserver;
136 use MediaWiki\Parser\Parsoid\Config\DataAccess as MWDataAccess;
137 use MediaWiki\Parser\Parsoid\Config\PageConfigFactory as MWPageConfigFactory;
138 use MediaWiki\Parser\Parsoid\Config\SiteConfig as MWSiteConfig;
139 use MediaWiki\Parser\Parsoid\HtmlTransformFactory;
140 use MediaWiki\Parser\Parsoid\ParsoidOutputAccess;
141 use MediaWiki\Parser\Parsoid\ParsoidParserFactory;
142 use MediaWiki\Permissions\GrantsInfo;
143 use MediaWiki\Permissions\GrantsLocalization;
144 use MediaWiki\Permissions\GroupPermissionsLookup;
145 use MediaWiki\Permissions\PermissionManager;
146 use MediaWiki\Permissions\RateLimiter;
147 use MediaWiki\Permissions\RestrictionStore;
148 use MediaWiki\PoolCounter\PoolCounterFactory;
149 use MediaWiki\Preferences\DefaultPreferencesFactory;
150 use MediaWiki\Preferences\PreferencesFactory;
151 use MediaWiki\Preferences\SignatureValidator;
152 use MediaWiki\Preferences\SignatureValidatorFactory;
153 use MediaWiki\Request\ProxyLookup;
154 use MediaWiki\Request\WebRequest;
155 use MediaWiki\ResourceLoader\MessageBlobStore;
156 use MediaWiki\ResourceLoader\ResourceLoader;
157 use MediaWiki\Rest\Handler\Helper\PageRestHelperFactory;
158 use MediaWiki\Revision\ArchivedRevisionLookup;
159 use MediaWiki\Revision\ContributionsLookup;
160 use MediaWiki\Revision\MainSlotRoleHandler;
161 use MediaWiki\Revision\RevisionFactory;
162 use MediaWiki\Revision\RevisionLookup;
163 use MediaWiki\Revision\RevisionRenderer;
164 use MediaWiki\Revision\RevisionStore;
165 use MediaWiki\Revision\RevisionStoreFactory;
166 use MediaWiki\Revision\SlotRecord;
167 use MediaWiki\Revision\SlotRoleRegistry;
168 use MediaWiki\Search\SearchResultThumbnailProvider;
169 use MediaWiki\Search\TitleMatcher;
170 use MediaWiki\Settings\Config\ConfigSchema;
171 use MediaWiki\Settings\SettingsBuilder;
172 use MediaWiki\Shell\CommandFactory;
173 use MediaWiki\Shell\ShellboxClientFactory;
174 use MediaWiki\SpecialPage\SpecialPageFactory;
175 use MediaWiki\Storage\BlobStore;
176 use MediaWiki\Storage\BlobStoreFactory;
177 use MediaWiki\Storage\EditResultCache;
178 use MediaWiki\Storage\NameTableStore;
179 use MediaWiki\Storage\NameTableStoreFactory;
180 use MediaWiki\Storage\PageEditStash;
181 use MediaWiki\Storage\PageUpdaterFactory;
182 use MediaWiki\Storage\RevertedTagUpdateManager;
183 use MediaWiki\Storage\SqlBlobStore;
184 use MediaWiki\Tidy\RemexDriver;
185 use MediaWiki\Tidy\TidyDriverBase;
186 use MediaWiki\Title\MediaWikiTitleCodec;
187 use MediaWiki\Title\NamespaceInfo;
188 use MediaWiki\Title\TitleFactory;
189 use MediaWiki\Title\TitleFormatter;
190 use MediaWiki\Title\TitleParser;
191 use MediaWiki\User\ActorMigration;
192 use MediaWiki\User\ActorNormalization;
193 use MediaWiki\User\ActorStore;
194 use MediaWiki\User\ActorStoreFactory;
195 use MediaWiki\User\BotPasswordStore;
196 use MediaWiki\User\CentralId\CentralIdLookup;
197 use MediaWiki\User\CentralId\CentralIdLookupFactory;
198 use MediaWiki\User\DefaultOptionsLookup;
199 use MediaWiki\User\PasswordReset;
200 use MediaWiki\User\Registration\LocalUserRegistrationProvider;
201 use MediaWiki\User\Registration\UserRegistrationLookup;
202 use MediaWiki\User\TalkPageNotificationManager;
203 use MediaWiki\User\TempUser\RealTempUserConfig;
204 use MediaWiki\User\TempUser\TempUserCreator;
205 use MediaWiki\User\UserEditTracker;
206 use MediaWiki\User\UserFactory;
207 use MediaWiki\User\UserGroupManager;
208 use MediaWiki\User\UserGroupManagerFactory;
209 use MediaWiki\User\UserIdentity;
210 use MediaWiki\User\UserIdentityLookup;
211 use MediaWiki\User\UserIdentityUtils;
212 use MediaWiki\User\UserNamePrefixSearch;
213 use MediaWiki\User\UserNameUtils;
214 use MediaWiki\User\UserOptionsLookup;
215 use MediaWiki\User\UserOptionsManager;
216 use MediaWiki\Utils\UrlUtils;
217 use MediaWiki\Watchlist\WatchlistManager;
218 use MediaWiki\WikiMap\WikiMap;
219 use Wikimedia\DependencyStore\KeyValueDependencyStore;
220 use Wikimedia\DependencyStore\SqlModuleDependencyStore;
221 use Wikimedia\EventRelayer\EventRelayerGroup;
222 use Wikimedia\Message\IMessageFormatterFactory;
223 use Wikimedia\ObjectFactory\ObjectFactory;
224 use Wikimedia\Parsoid\Config\DataAccess;
225 use Wikimedia\Parsoid\Config\SiteConfig;
226 use Wikimedia\Parsoid\Parsoid;
227 use Wikimedia\Rdbms\ChronologyProtector;
228 use Wikimedia\Rdbms\ConfiguredReadOnlyMode;
229 use Wikimedia\Rdbms\DatabaseFactory;
230 use Wikimedia\Rdbms\ReadOnlyMode;
231 use Wikimedia\RequestTimeout\CriticalSectionProvider;
232 use Wikimedia\RequestTimeout\RequestTimeout;
233 use Wikimedia\Stats\StatsCache;
234 use Wikimedia\Stats\StatsFactory;
235 use Wikimedia\UUID\GlobalIdGenerator;
236 use Wikimedia\WRStats\BagOStuffStatsStore;
237 use Wikimedia\WRStats\WRStatsFactory;
239 /** @phpcs-require-sorted-array */
240 return [
241 'ActionFactory' => static function ( MediaWikiServices $services ): ActionFactory {
242 return new ActionFactory(
243 $services->getMainConfig()->get( MainConfigNames::Actions ),
244 LoggerFactory::getInstance( 'ActionFactory' ),
245 $services->getObjectFactory(),
246 $services->getHookContainer()
250 'ActorMigration' => static function ( MediaWikiServices $services ): ActorMigration {
251 return new ActorMigration(
252 SCHEMA_COMPAT_NEW,
253 $services->getActorStoreFactory()
257 'ActorNormalization' => static function ( MediaWikiServices $services ): ActorNormalization {
258 return $services->getActorStoreFactory()->getActorNormalization();
261 'ActorStore' => static function ( MediaWikiServices $services ): ActorStore {
262 return $services->getActorStoreFactory()->getActorStore();
265 'ActorStoreFactory' => static function ( MediaWikiServices $services ): ActorStoreFactory {
266 return new ActorStoreFactory(
267 new ServiceOptions( ActorStoreFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
268 $services->getDBLoadBalancerFactory(),
269 $services->getUserNameUtils(),
270 $services->getTempUserConfig(),
271 LoggerFactory::getInstance( 'ActorStore' )
275 'ArchivedRevisionLookup' => static function ( MediaWikiServices $services ): ArchivedRevisionLookup {
276 return new ArchivedRevisionLookup(
277 $services->getDBLoadBalancerFactory(),
278 $services->getRevisionStore()
282 'AuthManager' => static function ( MediaWikiServices $services ): AuthManager {
283 $authManager = new AuthManager(
284 RequestContext::getMain()->getRequest(),
285 $services->getMainConfig(),
286 $services->getObjectFactory(),
287 $services->getHookContainer(),
288 $services->getReadOnlyMode(),
289 $services->getUserNameUtils(),
290 $services->getBlockManager(),
291 $services->getWatchlistManager(),
292 $services->getDBLoadBalancer(),
293 $services->getContentLanguage(),
294 $services->getLanguageConverterFactory(),
295 $services->getBotPasswordStore(),
296 $services->getUserFactory(),
297 $services->getUserIdentityLookup(),
298 $services->getUserOptionsManager()
300 $authManager->setLogger( LoggerFactory::getInstance( 'authentication' ) );
301 return $authManager;
304 'BacklinkCacheFactory' => static function ( MediaWikiServices $services ): BacklinkCacheFactory {
305 return new BacklinkCacheFactory(
306 new ServiceOptions(
307 BacklinkCache::CONSTRUCTOR_OPTIONS,
308 $services->getMainConfig()
310 $services->getLinksMigration(),
311 $services->getMainWANObjectCache(),
312 $services->getHookContainer(),
313 $services->getDBLoadBalancerFactory()
317 'BadFileLookup' => static function ( MediaWikiServices $services ): BadFileLookup {
318 return new BadFileLookup(
319 static function () {
320 return wfMessage( 'bad_image_list' )->inContentLanguage()->plain();
322 $services->getLocalServerObjectCache(),
323 $services->getRepoGroup(),
324 $services->getTitleParser(),
325 $services->getHookContainer()
329 'BlobStore' => static function ( MediaWikiServices $services ): BlobStore {
330 return $services->getService( '_SqlBlobStore' );
333 'BlobStoreFactory' => static function ( MediaWikiServices $services ): BlobStoreFactory {
334 return new BlobStoreFactory(
335 $services->getDBLoadBalancerFactory(),
336 $services->getExternalStoreAccess(),
337 $services->getMainWANObjectCache(),
338 new ServiceOptions( BlobStoreFactory::CONSTRUCTOR_OPTIONS,
339 $services->getMainConfig() )
343 'BlockActionInfo' => static function ( MediaWikiServices $services ): BlockActionInfo {
344 return new BlockActionInfo( $services->getHookContainer() );
347 'BlockErrorFormatter' => static function ( MediaWikiServices $services ): BlockErrorFormatter {
348 return new BlockErrorFormatter(
349 $services->getTitleFormatter(),
350 $services->getHookContainer(),
351 $services->getUserIdentityUtils()
355 'BlockManager' => static function ( MediaWikiServices $services ): BlockManager {
356 return new BlockManager(
357 new ServiceOptions(
358 BlockManager::CONSTRUCTOR_OPTIONS,
359 $services->getMainConfig()
361 $services->getPermissionManager(),
362 $services->getUserFactory(),
363 $services->getUserIdentityUtils(),
364 LoggerFactory::getInstance( 'BlockManager' ),
365 $services->getHookContainer()
369 'BlockPermissionCheckerFactory' => static function (
370 MediaWikiServices $services
371 ): BlockPermissionCheckerFactory {
372 return new BlockPermissionCheckerFactory(
373 new ServiceOptions(
374 BlockPermissionCheckerFactory::CONSTRUCTOR_OPTIONS,
375 $services->getMainConfig()
377 $services->getBlockUtils()
381 'BlockRestrictionStore' => static function ( MediaWikiServices $services ): BlockRestrictionStore {
382 return $services->getBlockRestrictionStoreFactory()->getBlockRestrictionStore( WikiAwareEntity::LOCAL );
385 'BlockRestrictionStoreFactory' => static function ( MediaWikiServices $services ): BlockRestrictionStoreFactory {
386 return new BlockRestrictionStoreFactory(
387 $services->getDBLoadBalancerFactory()
391 'BlockUserFactory' => static function ( MediaWikiServices $services ): BlockUserFactory {
392 return $services->getService( '_UserBlockCommandFactory' );
395 'BlockUtils' => static function ( MediaWikiServices $services ): BlockUtils {
396 return new BlockUtils(
397 new ServiceOptions(
398 BlockUtils::CONSTRUCTOR_OPTIONS,
399 $services->getMainConfig()
401 $services->getUserIdentityLookup(),
402 $services->getUserNameUtils()
406 'BotPasswordStore' => static function ( MediaWikiServices $services ): BotPasswordStore {
407 return new BotPasswordStore(
408 new ServiceOptions(
409 BotPasswordStore::CONSTRUCTOR_OPTIONS,
410 $services->getMainConfig()
412 $services->getCentralIdLookup(),
413 $services->getDBLoadBalancerFactory()
417 'CentralIdLookup' => static function ( MediaWikiServices $services ): CentralIdLookup {
418 return $services->getCentralIdLookupFactory()->getLookup();
421 'CentralIdLookupFactory' => static function ( MediaWikiServices $services ): CentralIdLookupFactory {
422 return new CentralIdLookupFactory(
423 new ServiceOptions( CentralIdLookupFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
424 $services->getObjectFactory(),
425 $services->getUserIdentityLookup()
429 'ChangeTagDefStore' => static function ( MediaWikiServices $services ): NameTableStore {
430 return $services->getNameTableStoreFactory()->getChangeTagDef();
433 'ChangeTagsStore' => static function ( MediaWikiServices $services ): ChangeTagsStore {
434 return new ChangeTagsStore(
435 $services->getDBLoadBalancerFactory(),
436 $services->getChangeTagDefStore(),
437 $services->getMainWANObjectCache(),
438 $services->getHookContainer(),
439 LoggerFactory::getInstance( 'ChangeTags' ),
440 $services->getUserFactory(),
441 new ServiceOptions(
442 ChangeTagsStore::CONSTRUCTOR_OPTIONS,
443 $services->getMainConfig()
448 'ChronologyProtector' => static function ( MediaWikiServices $services ): ChronologyProtector {
449 $mainConfig = $services->getMainConfig();
450 $cpStashType = $mainConfig->get( MainConfigNames::ChronologyProtectorStash );
451 $isMainCacheBad = ObjectCache::isDatabaseId( $mainConfig->get( MainConfigNames::MainCacheType ) );
453 if ( is_string( $cpStashType ) ) {
454 $cpStash = ObjectCache::getInstance( $cpStashType );
455 } elseif ( $isMainCacheBad ) {
456 $cpStash = new EmptyBagOStuff();
457 } else {
458 $cpStash = ObjectCache::getLocalClusterInstance();
461 $chronologyProtector = new ChronologyProtector(
462 $cpStash,
463 $mainConfig->get( MainConfigNames::ChronologyProtectorSecret ),
464 $mainConfig->get( 'CommandLineMode' ),
465 LoggerFactory::getInstance( 'rdbms' )
468 // Use the global WebRequest singleton. The main reason for using this
469 // is to call WebRequest::getIP() which is non-trivial to reproduce statically
470 // because it needs $wgUsePrivateIPs, as well as ProxyLookup and HookRunner services.
471 // TODO: Create a static version of WebRequest::getIP that accepts these three
472 // as dependencies, and then call that here. The other uses of $req below can
473 // trivially use $_COOKIES, $_GET and $_SERVER instead.
474 $req = RequestContext::getMain()->getRequest();
476 // Set user IP/agent information for agent session consistency purposes
477 $reqStart = (int)( $_SERVER['REQUEST_TIME_FLOAT'] ?? time() );
478 $cpPosInfo = ChronologyProtector::getCPInfoFromCookieValue(
479 // The cookie has no prefix and is set by MediaWiki::preOutputCommit()
480 $req->getCookie( 'cpPosIndex', '' ),
481 // Mitigate broken client-side cookie expiration handling (T190082)
482 $reqStart - ChronologyProtector::POSITION_COOKIE_TTL
484 $chronologyProtector->setRequestInfo( [
485 'IPAddress' => $req->getIP(),
486 'UserAgent' => $req->getHeader( 'User-Agent' ),
487 'ChronologyPositionIndex' => $req->getInt( 'cpPosIndex', $cpPosInfo['index'] ),
488 'ChronologyClientId' => $cpPosInfo['clientId'] ?? null,
489 ] );
490 return $chronologyProtector;
493 'CollationFactory' => static function ( MediaWikiServices $services ): CollationFactory {
494 return new CollationFactory(
495 new ServiceOptions(
496 CollationFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
497 $services->getObjectFactory(),
498 $services->getHookContainer()
502 'CommentFormatter' => static function ( MediaWikiServices $services ): CommentFormatter {
503 return new CommentFormatter(
504 $services->getCommentParserFactory()
508 'CommentParserFactory' => static function ( MediaWikiServices $services ): CommentParserFactory {
509 return new CommentParserFactory(
510 $services->getLinkRendererFactory()->create( [ 'renderForComment' => true ] ),
511 $services->getLinkBatchFactory(),
512 $services->getLinkCache(),
513 $services->getRepoGroup(),
514 RequestContext::getMain()->getLanguage(),
515 $services->getContentLanguage(),
516 $services->getTitleParser(),
517 $services->getNamespaceInfo(),
518 $services->getHookContainer()
522 'CommentStore' => static function ( MediaWikiServices $services ): CommentStore {
523 return new CommentStore( $services->getContentLanguage() );
526 'ConfigFactory' => static function ( MediaWikiServices $services ): ConfigFactory {
527 // Use the bootstrap config to initialize the ConfigFactory.
528 $registry = $services->getBootstrapConfig()->get( MainConfigNames::ConfigRegistry );
529 $factory = new ConfigFactory();
531 foreach ( $registry as $name => $callback ) {
532 $factory->register( $name, $callback );
534 return $factory;
537 'ConfigRepository' => static function ( MediaWikiServices $services ): ConfigRepository {
538 return new ConfigRepository( $services->getConfigFactory() );
541 'ConfigSchema' => static function ( MediaWikiServices $services ): ConfigSchema {
542 /** @var SettingsBuilder $settings */
543 $settings = $services->get( '_SettingsBuilder' );
544 return $settings->getConfigSchema();
547 'ConfiguredReadOnlyMode' => static function ( MediaWikiServices $services ): ConfiguredReadOnlyMode {
548 $config = $services->getMainConfig();
549 return new ConfiguredReadOnlyMode(
550 $config->get( MainConfigNames::ReadOnly ),
551 $config->get( MainConfigNames::ReadOnlyFile )
555 'ContentHandlerFactory' => static function ( MediaWikiServices $services ): IContentHandlerFactory {
556 $contentHandlerConfig = $services->getMainConfig()->get( MainConfigNames::ContentHandlers );
558 return new ContentHandlerFactory(
559 $contentHandlerConfig,
560 $services->getObjectFactory(),
561 $services->getHookContainer(),
562 LoggerFactory::getInstance( 'ContentHandler' )
566 'ContentLanguage' => static function ( MediaWikiServices $services ): Language {
567 return $services->getLanguageFactory()->getLanguage(
568 $services->getMainConfig()->get( MainConfigNames::LanguageCode ) );
571 'ContentModelChangeFactory' => static function ( MediaWikiServices $services ): ContentModelChangeFactory {
572 return $services->getService( '_PageCommandFactory' );
575 'ContentModelStore' => static function ( MediaWikiServices $services ): NameTableStore {
576 return $services->getNameTableStoreFactory()->getContentModels();
579 'ContentRenderer' => static function ( MediaWikiServices $services ): ContentRenderer {
580 return new ContentRenderer( $services->getContentHandlerFactory() );
583 'ContentTransformer' => static function ( MediaWikiServices $services ): ContentTransformer {
584 return new ContentTransformer( $services->getContentHandlerFactory() );
587 'ContributionsLookup' => static function ( MediaWikiServices $services ): ContributionsLookup {
588 return new ContributionsLookup(
589 $services->getRevisionStore(),
590 $services->getLinkRendererFactory(),
591 $services->getLinkBatchFactory(),
592 $services->getHookContainer(),
593 $services->getDBLoadBalancerFactory(),
594 $services->getNamespaceInfo(),
595 $services->getCommentFormatter()
599 'CriticalSectionProvider' => static function ( MediaWikiServices $services ): CriticalSectionProvider {
600 $config = $services->getMainConfig();
601 $limit = $GLOBALS[ 'wgCommandLineMode' ] ? INF : $config->get( MainConfigNames::CriticalSectionTimeLimit );
602 return RequestTimeout::singleton()->createCriticalSectionProvider( $limit );
605 'CryptHKDF' => static function ( MediaWikiServices $services ): CryptHKDF {
606 $config = $services->getMainConfig();
608 $secret = $config->get( MainConfigNames::HKDFSecret ) ?: $config->get( MainConfigNames::SecretKey );
609 if ( !$secret ) {
610 throw new RuntimeException( "Cannot use MWCryptHKDF without a secret." );
613 // In HKDF, the context can be known to the attacker, but this will
614 // keep simultaneous runs from producing the same output.
615 $context = [ microtime(), getmypid(), gethostname() ];
617 // Setup salt cache. Use APC, or fallback to the main cache if it isn't setup
618 $cache = $services->getLocalServerObjectCache();
619 if ( $cache instanceof EmptyBagOStuff ) {
620 $cache = ObjectCache::getLocalClusterInstance();
623 return new CryptHKDF( $secret, $config->get( MainConfigNames::HKDFAlgorithm ), $cache, $context );
626 'DatabaseBlockStore' => static function ( MediaWikiServices $services ): DatabaseBlockStore {
627 return $services->getDatabaseBlockStoreFactory()->getDatabaseBlockStore( DatabaseBlock::LOCAL );
630 'DatabaseBlockStoreFactory' => static function ( MediaWikiServices $services ): DatabaseBlockStoreFactory {
631 return new DatabaseBlockStoreFactory(
632 new ServiceOptions(
633 DatabaseBlockStoreFactory::CONSTRUCTOR_OPTIONS,
634 $services->getMainConfig()
636 LoggerFactory::getInstance( 'DatabaseBlockStore' ),
637 $services->getActorStoreFactory(),
638 $services->getBlockRestrictionStoreFactory(),
639 $services->getCommentStore(),
640 $services->getHookContainer(),
641 $services->getDBLoadBalancerFactory(),
642 $services->getReadOnlyMode(),
643 $services->getUserFactory()
647 'DatabaseFactory' => static function ( MediaWikiServices $services ): DatabaseFactory {
648 return new DatabaseFactory(
649 [ 'debugSql' => $services->getMainConfig()->get( MainConfigNames::DebugDumpSql ) ]
653 'DateFormatterFactory' => static function ( MediaWikiServices $services ): DateFormatterFactory {
654 return new DateFormatterFactory();
657 'DBLoadBalancer' => static function ( MediaWikiServices $services ): Wikimedia\Rdbms\ILoadBalancer {
658 // just return the default LB from the DBLoadBalancerFactory service
659 return $services->getDBLoadBalancerFactory()->getMainLB();
662 'DBLoadBalancerFactory' =>
663 static function ( MediaWikiServices $services ): Wikimedia\Rdbms\LBFactory {
664 $mainConfig = $services->getMainConfig();
665 $lbFactoryConfigBuilder = $services->getDBLoadBalancerFactoryConfigBuilder();
667 $lbConf = $lbFactoryConfigBuilder->applyDefaultConfig(
668 $mainConfig->get( MainConfigNames::LBFactoryConf )
671 $class = $lbFactoryConfigBuilder->getLBFactoryClass( $lbConf );
672 $instance = new $class( $lbConf );
674 $lbFactoryConfigBuilder->setDomainAliases( $instance );
676 // NOTE: This accesses ProxyLookup from the MediaWikiServices singleton
677 // for non-essential non-nonimal purposes (via WebRequest::getIP).
678 // This state is fine (and meant) to be consistent for a given PHP process,
679 // even if applied to the service container for a different wiki.
680 $lbFactoryConfigBuilder->applyGlobalState(
681 $instance,
682 $mainConfig,
683 $services->getStatsdDataFactory()
686 return $instance;
689 'DBLoadBalancerFactoryConfigBuilder' => static function ( MediaWikiServices $services ): MWLBFactory {
690 $mainConfig = $services->getMainConfig();
691 if ( ObjectCache::isDatabaseId( $mainConfig->get( MainConfigNames::MainCacheType ) ) ) {
692 $wanCache = WANObjectCache::newEmpty();
693 } else {
694 $wanCache = $services->getMainWANObjectCache();
696 $srvCache = $services->getLocalServerObjectCache();
697 if ( $srvCache instanceof EmptyBagOStuff ) {
698 // Use process cache if no APCU or other local-server cache (e.g. on CLI)
699 $srvCache = new HashBagOStuff( [ 'maxKeys' => 100 ] );
702 return new MWLBFactory(
703 new ServiceOptions( MWLBFactory::APPLY_DEFAULT_CONFIG_OPTIONS, $services->getMainConfig() ),
704 new ConfiguredReadOnlyMode(
705 $mainConfig->get( MainConfigNames::ReadOnly ),
706 $mainConfig->get( MainConfigNames::ReadOnlyFile )
708 $services->getChronologyProtector(),
709 $srvCache,
710 $wanCache,
711 $services->getCriticalSectionProvider(),
712 $services->getStatsdDataFactory(),
713 ExtensionRegistry::getInstance()->getAttribute( 'DatabaseVirtualDomains' )
717 'DeletePageFactory' => static function ( MediaWikiServices $services ): DeletePageFactory {
718 return $services->getService( '_PageCommandFactory' );
721 'Emailer' => static function ( MediaWikiServices $services ): IEmailer {
722 return new Emailer();
725 'EmailUserFactory' => static function ( MediaWikiServices $services ): EmailUserFactory {
726 return new EmailUserFactory(
727 new ServiceOptions( EmailUser::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
728 $services->getHookContainer(),
729 $services->getUserOptionsLookup(),
730 $services->getCentralIdLookup(),
731 $services->getUserFactory(),
732 $services->getEmailer(),
733 $services->getMessageFormatterFactory(),
734 $services->getMessageFormatterFactory()->getTextFormatter( $services->getContentLanguage()->getCode() )
738 'EventRelayerGroup' => static function ( MediaWikiServices $services ): EventRelayerGroup {
739 return new EventRelayerGroup( $services->getMainConfig()->get( MainConfigNames::EventRelayerConfig ) );
742 'ExternalStoreAccess' => static function ( MediaWikiServices $services ): ExternalStoreAccess {
743 return new ExternalStoreAccess(
744 $services->getExternalStoreFactory(),
745 LoggerFactory::getInstance( 'ExternalStore' )
749 'ExternalStoreFactory' => static function ( MediaWikiServices $services ): ExternalStoreFactory {
750 $config = $services->getMainConfig();
751 $writeStores = $config->get( MainConfigNames::DefaultExternalStore );
753 return new ExternalStoreFactory(
754 $config->get( MainConfigNames::ExternalStores ),
755 ( $writeStores !== false ) ? (array)$writeStores : [],
756 $services->getDBLoadBalancer()->getLocalDomainID(),
757 LoggerFactory::getInstance( 'ExternalStore' )
761 'FileBackendGroup' => static function ( MediaWikiServices $services ): FileBackendGroup {
762 $mainConfig = $services->getMainConfig();
764 $ld = WikiMap::getCurrentWikiDbDomain();
765 $fallbackWikiId = WikiMap::getWikiIdFromDbDomain( $ld );
766 // If the local wiki ID and local domain ID do not match, probably due to a non-default
767 // schema, issue a warning. A non-default schema indicates that it might be used to
768 // disambiguate different wikis.
769 $legacyDomainId = strlen( $ld->getTablePrefix() )
770 ? "{$ld->getDatabase()}-{$ld->getTablePrefix()}"
771 : $ld->getDatabase();
772 if ( $ld->getSchema() !== null && $legacyDomainId !== $fallbackWikiId ) {
773 wfWarn(
774 "Legacy default 'domainId' is '$legacyDomainId' but wiki ID is '$fallbackWikiId'."
778 $cache = $services->getLocalServerObjectCache();
779 if ( $cache instanceof EmptyBagOStuff ) {
780 $cache = new HashBagOStuff();
783 return new FileBackendGroup(
784 new ServiceOptions( FileBackendGroup::CONSTRUCTOR_OPTIONS, $mainConfig,
785 [ 'fallbackWikiId' => $fallbackWikiId ] ),
786 $services->getReadOnlyMode(),
787 $cache,
788 $services->getMainWANObjectCache(),
789 $services->getMimeAnalyzer(),
790 $services->getLockManagerGroupFactory(),
791 $services->getTempFSFileFactory(),
792 $services->getObjectFactory()
796 'GenderCache' => static function ( MediaWikiServices $services ): GenderCache {
797 $nsInfo = $services->getNamespaceInfo();
798 // Database layer may be disabled, so processing without database connection
799 $dbLoadBalancer = $services->isServiceDisabled( 'DBLoadBalancer' )
800 ? null
801 : $services->getDBLoadBalancerFactory();
802 return new GenderCache( $nsInfo, $dbLoadBalancer, $services->get( '_DefaultOptionsLookup' ) );
805 'GlobalIdGenerator' => static function ( MediaWikiServices $services ): GlobalIdGenerator {
806 $mainConfig = $services->getMainConfig();
808 return new GlobalIdGenerator(
809 $mainConfig->get( MainConfigNames::TmpDirectory ),
810 static function ( $command ) {
811 return wfShellExec( $command );
816 'GrantsInfo' => static function ( MediaWikiServices $services ): GrantsInfo {
817 return new GrantsInfo(
818 new ServiceOptions(
819 GrantsInfo::CONSTRUCTOR_OPTIONS,
820 $services->getMainConfig()
825 'GrantsLocalization' => static function ( MediaWikiServices $services ): GrantsLocalization {
826 return new GrantsLocalization(
827 $services->getGrantsInfo(),
828 $services->getLinkRenderer(),
829 $services->getLanguageFactory(),
830 $services->getContentLanguage()
834 'GroupPermissionsLookup' => static function ( MediaWikiServices $services ): GroupPermissionsLookup {
835 return new GroupPermissionsLookup(
836 new ServiceOptions( GroupPermissionsLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig() )
840 'HookContainer' => static function ( MediaWikiServices $services ): HookContainer {
841 // NOTE: This is called while $services is being initialized, in order to call the
842 // MediaWikiServices hook.
844 $configHooks = $services->getBootstrapConfig()->get( MainConfigNames::Hooks );
846 // If we are instantiating this service after $wgHooks was replaced by a fake,
847 // get the original array out of the object. This should only happen in the installer,
848 // when it calls resetMediaWikiServices().
849 if ( $configHooks instanceof FauxGlobalHookArray ) {
850 $configHooks = $configHooks->getOriginalArray();
853 $extRegistry = ExtensionRegistry::getInstance();
854 $extHooks = $extRegistry->getAttribute( 'Hooks' );
855 $extDeprecatedHooks = $extRegistry->getAttribute( 'DeprecatedHooks' );
857 $hookRegistry = new StaticHookRegistry( $configHooks, $extHooks, $extDeprecatedHooks );
858 $hookContainer = new HookContainer(
859 $hookRegistry,
860 $services->getObjectFactory()
863 return $hookContainer;
866 'HtmlCacheUpdater' => static function ( MediaWikiServices $services ): HtmlCacheUpdater {
867 $config = $services->getMainConfig();
869 return new HtmlCacheUpdater(
870 $services->getHookContainer(),
871 $services->getTitleFactory(),
872 $config->get( MainConfigNames::CdnReboundPurgeDelay ),
873 $config->get( MainConfigNames::UseFileCache ),
874 $config->get( MainConfigNames::CdnMaxAge )
878 'HtmlTransformFactory' => static function ( MediaWikiServices $services ): HtmlTransformFactory {
879 return new HtmlTransformFactory(
880 $services->getService( '_Parsoid' ),
881 $services->getMainConfig()->get( MainConfigNames::ParsoidSettings ),
882 $services->getParsoidPageConfigFactory(),
883 $services->getContentHandlerFactory(),
884 $services->getParsoidSiteConfig(),
885 $services->getTitleFactory(),
886 $services->getLanguageConverterFactory(),
887 $services->getLanguageFactory()
891 'HttpRequestFactory' =>
892 static function ( MediaWikiServices $services ): HttpRequestFactory {
893 return new HttpRequestFactory(
894 new ServiceOptions(
895 HttpRequestFactory::CONSTRUCTOR_OPTIONS,
896 $services->getMainConfig()
898 LoggerFactory::getInstance( 'http' ),
899 Telemetry::getInstance()
903 'InterwikiLookup' => static function ( MediaWikiServices $services ): InterwikiLookup {
904 return new ClassicInterwikiLookup(
905 new ServiceOptions(
906 ClassicInterwikiLookup::CONSTRUCTOR_OPTIONS,
907 $services->getMainConfig(),
908 [ 'wikiId' => WikiMap::getCurrentWikiId() ]
910 $services->getContentLanguage(),
911 $services->getMainWANObjectCache(),
912 $services->getHookContainer(),
913 $services->getDBLoadBalancerFactory()
917 'IntroMessageBuilder' => static function ( MediaWikiServices $services ): IntroMessageBuilder {
918 return new IntroMessageBuilder(
919 $services->getMainConfig(),
920 $services->getLinkRenderer(),
921 $services->getPermissionManager(),
922 $services->getUserNameUtils(),
923 $services->getTempUserCreator(),
924 $services->getUserFactory(),
925 $services->getRestrictionStore(),
926 $services->getReadOnlyMode(),
927 $services->getSpecialPageFactory(),
928 $services->getRepoGroup(),
929 $services->getNamespaceInfo(),
930 $services->getSkinFactory()
934 'JobFactory' => static function ( MediaWikiServices $services ): JobFactory {
935 return new JobFactory(
936 $services->getObjectFactory(),
937 $services->getMainConfig()->get( MainConfigNames::JobClasses )
941 'JobQueueGroup' => static function ( MediaWikiServices $services ): JobQueueGroup {
942 return $services->getJobQueueGroupFactory()->makeJobQueueGroup();
945 'JobQueueGroupFactory' => static function ( MediaWikiServices $services ): JobQueueGroupFactory {
946 return new JobQueueGroupFactory(
947 new ServiceOptions( JobQueueGroupFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
948 $services->getReadOnlyMode(),
949 $services->getStatsdDataFactory(),
950 $services->getMainWANObjectCache(),
951 $services->getGlobalIdGenerator()
955 'JobRunner' => static function ( MediaWikiServices $services ): JobRunner {
956 return new JobRunner(
957 new ServiceOptions( JobRunner::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
958 $services->getDBLoadBalancerFactory(),
959 $services->getJobQueueGroup(),
960 $services->getReadOnlyMode(),
961 $services->getLinkCache(),
962 $services->getStatsdDataFactory(),
963 LoggerFactory::getInstance( 'runJobs' )
967 'JsonCodec' => static function ( MediaWikiServices $services ): JsonCodec {
968 return new JsonCodec();
971 'LanguageConverterFactory' => static function ( MediaWikiServices $services ): LanguageConverterFactory {
972 $usePigLatinVariant = $services->getMainConfig()->get( MainConfigNames::UsePigLatinVariant );
973 $isConversionDisabled = $services->getMainConfig()->get( MainConfigNames::DisableLangConversion );
974 $isTitleConversionDisabled = $services->getMainConfig()->get( MainConfigNames::DisableTitleConversion );
975 return new LanguageConverterFactory(
976 $services->getObjectFactory(),
977 $usePigLatinVariant,
978 $isConversionDisabled,
979 $isTitleConversionDisabled,
980 static function () use ( $services ) {
981 return $services->getContentLanguage();
986 'LanguageFactory' => static function ( MediaWikiServices $services ): LanguageFactory {
987 return new LanguageFactory(
988 new ServiceOptions( LanguageFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
989 $services->getNamespaceInfo(),
990 $services->getLocalisationCache(),
991 $services->getLanguageNameUtils(),
992 $services->getLanguageFallback(),
993 $services->getLanguageConverterFactory(),
994 $services->getHookContainer(),
995 $services->getMainConfig()
999 'LanguageFallback' => static function ( MediaWikiServices $services ): LanguageFallback {
1000 return new LanguageFallback(
1001 $services->getMainConfig()->get( MainConfigNames::LanguageCode ),
1002 $services->getLocalisationCache(),
1003 $services->getLanguageNameUtils()
1007 'LanguageNameUtils' => static function ( MediaWikiServices $services ): LanguageNameUtils {
1008 return new LanguageNameUtils(
1009 new ServiceOptions(
1010 LanguageNameUtils::CONSTRUCTOR_OPTIONS,
1011 $services->getMainConfig()
1013 $services->getHookContainer()
1017 'LinkBatchFactory' => static function ( MediaWikiServices $services ): LinkBatchFactory {
1018 return new LinkBatchFactory(
1019 $services->getLinkCache(),
1020 $services->getTitleFormatter(),
1021 $services->getContentLanguage(),
1022 $services->getGenderCache(),
1023 $services->getDBLoadBalancerFactory(),
1024 $services->getLinksMigration(),
1025 LoggerFactory::getInstance( 'LinkBatch' )
1029 'LinkCache' => static function ( MediaWikiServices $services ): LinkCache {
1030 // Database layer may be disabled, so processing without database connection
1031 $dbLoadBalancer = $services->isServiceDisabled( 'DBLoadBalancer' )
1032 ? null
1033 : $services->getDBLoadBalancer();
1034 $linkCache = new LinkCache(
1035 $services->getTitleFormatter(),
1036 $services->getMainWANObjectCache(),
1037 $services->getNamespaceInfo(),
1038 $dbLoadBalancer
1040 $linkCache->setLogger( LoggerFactory::getInstance( 'LinkCache' ) );
1041 return $linkCache;
1044 'LinkRenderer' => static function ( MediaWikiServices $services ): LinkRenderer {
1045 return $services->getLinkRendererFactory()->create();
1048 'LinkRendererFactory' => static function ( MediaWikiServices $services ): LinkRendererFactory {
1049 return new LinkRendererFactory(
1050 $services->getTitleFormatter(),
1051 $services->getLinkCache(),
1052 $services->getSpecialPageFactory(),
1053 $services->getHookContainer()
1057 'LinksMigration' => static function ( MediaWikiServices $services ): LinksMigration {
1058 return new LinksMigration(
1059 $services->getMainConfig(),
1060 $services->getLinkTargetLookup()
1064 'LinkTargetLookup' => static function ( MediaWikiServices $services ): LinkTargetLookup {
1065 return new LinkTargetStore(
1066 $services->getDBLoadBalancerFactory(),
1067 $services->getLocalServerObjectCache(),
1068 $services->getMainWANObjectCache()
1072 'LocalisationCache' => static function ( MediaWikiServices $services ): LocalisationCache {
1073 $conf = $services->getMainConfig()->get( MainConfigNames::LocalisationCacheConf );
1075 $logger = LoggerFactory::getInstance( 'localisation' );
1077 $store = LocalisationCache::getStoreFromConf(
1078 $conf, $services->getMainConfig()->get( MainConfigNames::CacheDirectory ) );
1079 $logger->debug( 'LocalisationCache using store ' . get_class( $store ) );
1081 return new $conf['class'](
1082 new ServiceOptions(
1083 LocalisationCache::CONSTRUCTOR_OPTIONS,
1084 // Two of the options are stored in $wgLocalisationCacheConf
1085 $conf,
1086 // In case someone set that config variable and didn't reset all keys, set defaults.
1088 'forceRecache' => false,
1089 'manualRecache' => false,
1091 // Some other options come from config itself
1092 $services->getMainConfig()
1094 $store,
1095 $logger,
1096 [ static function () use ( $services ) {
1097 // NOTE: Make sure we use the same cache object that is assigned in the
1098 // constructor of the MessageBlobStore class used by ResourceLoader.
1099 // T231866: Avoid circular dependency via ResourceLoader.
1100 MessageBlobStore::clearGlobalCacheEntry( $services->getMainWANObjectCache() );
1101 } ],
1102 $services->getLanguageNameUtils(),
1103 $services->getHookContainer()
1107 'LocalServerObjectCache' => static function ( MediaWikiServices $services ): BagOStuff {
1108 return ObjectCache::makeLocalServerCache();
1111 'LockManagerGroupFactory' => static function ( MediaWikiServices $services ): LockManagerGroupFactory {
1112 return new LockManagerGroupFactory(
1113 WikiMap::getCurrentWikiDbDomain()->getId(),
1114 $services->getMainConfig()->get( MainConfigNames::LockManagers )
1118 'MagicWordFactory' => static function ( MediaWikiServices $services ): MagicWordFactory {
1119 return new MagicWordFactory(
1120 $services->getContentLanguage(),
1121 $services->getHookContainer()
1125 'MainConfig' => static function ( MediaWikiServices $services ): Config {
1126 // Use the 'main' config from the ConfigFactory service.
1127 return $services->getConfigFactory()->makeConfig( 'main' );
1130 'MainObjectStash' => static function ( MediaWikiServices $services ): BagOStuff {
1131 $mainConfig = $services->getMainConfig();
1133 $id = $mainConfig->get( MainConfigNames::MainStash );
1134 $params = $mainConfig->get( MainConfigNames::ObjectCaches )[$id] ?? null;
1135 if ( !$params ) {
1136 throw new ConfigException(
1137 "\$wgObjectCaches must have \"$id\" set (via \$wgMainStash)"
1141 $store = ObjectCache::newFromParams( $params, $services );
1142 $store->getLogger()->debug( 'MainObjectStash using store {class}', [
1143 'class' => get_class( $store )
1144 ] );
1146 return $store;
1149 'MainWANObjectCache' => static function ( MediaWikiServices $services ): WANObjectCache {
1150 $mainConfig = $services->getMainConfig();
1152 $store = $services->get( '_LocalClusterCache' );
1153 $logger = $store->getLogger();
1154 $logger->debug( 'MainWANObjectCache using store {class}', [
1155 'class' => get_class( $store )
1156 ] );
1158 $wanParams = $mainConfig->get( MainConfigNames::WANObjectCache ) + [
1159 'cache' => $store,
1160 'logger' => $logger,
1161 'secret' => $mainConfig->get( MainConfigNames::SecretKey ),
1163 if ( !$GLOBALS[ 'wgCommandLineMode' ] ) {
1164 // Send the statsd data post-send on HTTP requests; avoid in CLI mode (T181385)
1165 $wanParams['stats'] = $services->getStatsdDataFactory();
1166 // Let pre-emptive refreshes happen post-send on HTTP requests
1167 $wanParams['asyncHandler'] = [ DeferredUpdates::class, 'addCallableUpdate' ];
1169 return new WANObjectCache( $wanParams );
1172 'MediaHandlerFactory' => static function ( MediaWikiServices $services ): MediaHandlerFactory {
1173 return new MediaHandlerFactory(
1174 LoggerFactory::getInstance( 'MediaHandlerFactory' ),
1175 $services->getMainConfig()->get( MainConfigNames::MediaHandlers )
1179 'MergeHistoryFactory' => static function ( MediaWikiServices $services ): MergeHistoryFactory {
1180 return $services->getService( '_PageCommandFactory' );
1183 'MessageCache' => static function ( MediaWikiServices $services ): MessageCache {
1184 $mainConfig = $services->getMainConfig();
1185 $clusterCache = ObjectCache::getInstance( $mainConfig->get( MainConfigNames::MessageCacheType ) );
1186 $srvCache = $mainConfig->get( MainConfigNames::UseLocalMessageCache )
1187 ? $services->getLocalServerObjectCache()
1188 : new EmptyBagOStuff();
1190 $logger = LoggerFactory::getInstance( 'MessageCache' );
1191 $logger->debug( 'MessageCache using store {class}', [
1192 'class' => get_class( $clusterCache )
1193 ] );
1195 $options = new ServiceOptions( MessageCache::CONSTRUCTOR_OPTIONS, $mainConfig );
1197 return new MessageCache(
1198 $services->getMainWANObjectCache(),
1199 $clusterCache,
1200 $srvCache,
1201 $services->getContentLanguage(),
1202 $services->getLanguageConverterFactory(),
1203 $logger,
1204 $options,
1205 $services->getLanguageFactory(),
1206 $services->getLocalisationCache(),
1207 $services->getLanguageNameUtils(),
1208 $services->getLanguageFallback(),
1209 $services->getHookContainer(),
1210 $services->getParserFactory()
1214 'MessageFormatterFactory' => static function ( MediaWikiServices $services ): IMessageFormatterFactory {
1215 return new MessageFormatterFactory();
1218 'MimeAnalyzer' => static function ( MediaWikiServices $services ): MimeAnalyzer {
1219 $logger = LoggerFactory::getInstance( 'Mime' );
1220 $mainConfig = $services->getMainConfig();
1221 $hookRunner = new HookRunner( $services->getHookContainer() );
1222 $params = [
1223 'typeFile' => $mainConfig->get( MainConfigNames::MimeTypeFile ),
1224 'infoFile' => $mainConfig->get( MainConfigNames::MimeInfoFile ),
1225 'xmlTypes' => $mainConfig->get( MainConfigNames::XMLMimeTypes ),
1226 'guessCallback' =>
1227 static function ( $mimeAnalyzer, &$head, &$tail, $file, &$mime )
1228 use ( $logger, $hookRunner ) {
1229 // Also test DjVu
1230 $deja = new DjVuImage( $file );
1231 if ( $deja->isValid() ) {
1232 $logger->info( "Detected $file as image/vnd.djvu\n" );
1233 $mime = 'image/vnd.djvu';
1235 return;
1237 // Some strings by reference for performance - assuming well-behaved hooks
1238 $hookRunner->onMimeMagicGuessFromContent(
1239 $mimeAnalyzer, $head, $tail, $file, $mime );
1241 'extCallback' => static function ( $mimeAnalyzer, $ext, &$mime ) use ( $hookRunner ) {
1242 // Media handling extensions can improve the MIME detected
1243 $hookRunner->onMimeMagicImproveFromExtension( $mimeAnalyzer, $ext, $mime );
1245 'initCallback' => static function ( $mimeAnalyzer ) use ( $hookRunner ) {
1246 // Allow media handling extensions adding MIME-types and MIME-info
1247 $hookRunner->onMimeMagicInit( $mimeAnalyzer );
1249 'logger' => $logger
1252 if ( $params['infoFile'] === 'includes/mime.info' ) {
1253 $params['infoFile'] = MimeAnalyzer::USE_INTERNAL;
1256 if ( $params['typeFile'] === 'includes/mime.types' ) {
1257 $params['typeFile'] = MimeAnalyzer::USE_INTERNAL;
1260 $detectorCmd = $mainConfig->get( MainConfigNames::MimeDetectorCommand );
1261 if ( $detectorCmd ) {
1262 $factory = $services->getShellCommandFactory();
1263 $params['detectCallback'] = static function ( $file ) use ( $detectorCmd, $factory ) {
1264 $result = $factory->create()
1265 // $wgMimeDetectorCommand can contain commands with parameters
1266 ->unsafeParams( $detectorCmd )
1267 ->params( $file )
1268 ->execute();
1269 return $result->getStdout();
1273 return new MimeAnalyzer( $params );
1276 'MovePageFactory' => static function ( MediaWikiServices $services ): MovePageFactory {
1277 return $services->getService( '_PageCommandFactory' );
1280 'NamespaceInfo' => static function ( MediaWikiServices $services ): NamespaceInfo {
1281 return new NamespaceInfo(
1282 new ServiceOptions( NamespaceInfo::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1283 $services->getHookContainer(),
1284 ExtensionRegistry::getInstance()->getAttribute( 'ExtensionNamespaces' ),
1285 ExtensionRegistry::getInstance()->getAttribute( 'ImmovableNamespaces' )
1289 'NameTableStoreFactory' => static function ( MediaWikiServices $services ): NameTableStoreFactory {
1290 return new NameTableStoreFactory(
1291 $services->getDBLoadBalancerFactory(),
1292 $services->getMainWANObjectCache(),
1293 LoggerFactory::getInstance( 'NameTableSqlStore' )
1297 'ObjectFactory' => static function ( MediaWikiServices $services ): ObjectFactory {
1298 return new ObjectFactory( $services );
1301 'OldRevisionImporter' => static function ( MediaWikiServices $services ): OldRevisionImporter {
1302 return new ImportableOldRevisionImporter(
1303 true,
1304 LoggerFactory::getInstance( 'OldRevisionImporter' ),
1305 $services->getDBLoadBalancerFactory(),
1306 $services->getRevisionStore(),
1307 $services->getSlotRoleRegistry(),
1308 $services->getWikiPageFactory(),
1309 $services->getPageUpdaterFactory(),
1310 $services->getUserFactory()
1314 'PageEditStash' => static function ( MediaWikiServices $services ): PageEditStash {
1315 return new PageEditStash(
1316 ObjectCache::getLocalClusterInstance(),
1317 $services->getDBLoadBalancerFactory(),
1318 LoggerFactory::getInstance( 'StashEdit' ),
1319 $services->getStatsdDataFactory(),
1320 $services->getUserEditTracker(),
1321 $services->getUserFactory(),
1322 $services->getWikiPageFactory(),
1323 $services->getHookContainer(),
1324 defined( 'MEDIAWIKI_JOB_RUNNER' ) || $GLOBALS[ 'wgCommandLineMode' ]
1325 ? PageEditStash::INITIATOR_JOB_OR_CLI
1326 : PageEditStash::INITIATOR_USER
1330 'PageProps' => static function ( MediaWikiServices $services ): PageProps {
1331 return new PageProps(
1332 $services->getLinkBatchFactory(),
1333 $services->getDBLoadBalancerFactory()
1337 'PageRestHelperFactory' => static function ( MediaWikiServices $services ): PageRestHelperFactory {
1338 return new PageRestHelperFactory(
1339 new ServiceOptions( PageRestHelperFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1340 $services->getRevisionLookup(),
1341 $services->getTitleFormatter(),
1342 $services->getPageStore(),
1343 $services->getParsoidOutputStash(),
1344 $services->getStatsdDataFactory(),
1345 $services->getParsoidOutputAccess(),
1346 $services->getHtmlTransformFactory(),
1347 $services->getContentHandlerFactory(),
1348 $services->getLanguageFactory(),
1349 $services->getRedirectStore(),
1350 $services->getLanguageConverterFactory()
1354 'PageStore' => static function ( MediaWikiServices $services ): PageStore {
1355 return $services->getPageStoreFactory()->getPageStore();
1358 'PageStoreFactory' => static function ( MediaWikiServices $services ): PageStoreFactory {
1359 $options = new ServiceOptions(
1360 PageStoreFactory::CONSTRUCTOR_OPTIONS,
1361 $services->getMainConfig()
1364 return new PageStoreFactory(
1365 $options,
1366 $services->getDBLoadBalancerFactory(),
1367 $services->getNamespaceInfo(),
1368 $services->getTitleParser(),
1369 $services->getLinkCache(),
1370 $services->getStatsdDataFactory()
1374 'PageUpdaterFactory' => static function (
1375 MediaWikiServices $services
1376 ): PageUpdaterFactory {
1377 $editResultCache = new EditResultCache(
1378 $services->getMainObjectStash(),
1379 $services->getDBLoadBalancerFactory(),
1380 new ServiceOptions(
1381 EditResultCache::CONSTRUCTOR_OPTIONS,
1382 $services->getMainConfig()
1386 return new PageUpdaterFactory(
1387 $services->getRevisionStore(),
1388 $services->getRevisionRenderer(),
1389 $services->getSlotRoleRegistry(),
1390 $services->getParserCache(),
1391 $services->getJobQueueGroup(),
1392 $services->getMessageCache(),
1393 $services->getContentLanguage(),
1394 $services->getDBLoadBalancerFactory(),
1395 $services->getContentHandlerFactory(),
1396 $services->getHookContainer(),
1397 $editResultCache,
1398 $services->getUserNameUtils(),
1399 LoggerFactory::getInstance( 'SavePage' ),
1400 new ServiceOptions(
1401 PageUpdaterFactory::CONSTRUCTOR_OPTIONS,
1402 $services->getMainConfig()
1404 $services->getUserEditTracker(),
1405 $services->getUserGroupManager(),
1406 $services->getTitleFormatter(),
1407 $services->getContentTransformer(),
1408 $services->getPageEditStash(),
1409 $services->getTalkPageNotificationManager(),
1410 $services->getMainWANObjectCache(),
1411 $services->getPermissionManager(),
1412 $services->getWikiPageFactory(),
1413 $services->getChangeTagsStore()->getSoftwareTags()
1417 'Parser' => static function ( MediaWikiServices $services ): Parser {
1418 return $services->getParserFactory()->getMainInstance();
1421 'ParserCache' => static function ( MediaWikiServices $services ): ParserCache {
1422 return $services->getParserCacheFactory()
1423 ->getParserCache( ParserCacheFactory::DEFAULT_NAME );
1426 'ParserCacheFactory' => static function ( MediaWikiServices $services ): ParserCacheFactory {
1427 $config = $services->getMainConfig();
1428 $cache = ObjectCache::getInstance( $config->get( MainConfigNames::ParserCacheType ) );
1429 $wanCache = $services->getMainWANObjectCache();
1431 $options = new ServiceOptions( ParserCacheFactory::CONSTRUCTOR_OPTIONS, $config );
1433 return new ParserCacheFactory(
1434 $cache,
1435 $wanCache,
1436 $services->getHookContainer(),
1437 $services->getJsonCodec(),
1438 $services->getStatsdDataFactory(),
1439 LoggerFactory::getInstance( 'ParserCache' ),
1440 $options,
1441 $services->getTitleFactory(),
1442 $services->getWikiPageFactory()
1446 'ParserFactory' => static function ( MediaWikiServices $services ): ParserFactory {
1447 $options = new ServiceOptions( Parser::CONSTRUCTOR_OPTIONS,
1448 $services->getMainConfig()
1451 return new ParserFactory(
1452 $options,
1453 $services->getMagicWordFactory(),
1454 $services->getContentLanguage(),
1455 $services->getUrlUtils(),
1456 $services->getSpecialPageFactory(),
1457 $services->getLinkRendererFactory(),
1458 $services->getNamespaceInfo(),
1459 LoggerFactory::getInstance( 'Parser' ),
1460 $services->getBadFileLookup(),
1461 $services->getLanguageConverterFactory(),
1462 $services->getHookContainer(),
1463 $services->getTidy(),
1464 $services->getMainWANObjectCache(),
1465 $services->getUserOptionsLookup(),
1466 $services->getUserFactory(),
1467 $services->getTitleFormatter(),
1468 $services->getHttpRequestFactory(),
1469 $services->getTrackingCategories(),
1470 $services->getSignatureValidatorFactory(),
1471 $services->getUserNameUtils()
1475 'ParserOutputAccess' => static function ( MediaWikiServices $services ): ParserOutputAccess {
1476 return new ParserOutputAccess(
1477 $services->getParserCacheFactory(),
1478 $services->getRevisionLookup(),
1479 $services->getRevisionRenderer(),
1480 $services->getStatsdDataFactory(),
1481 $services->getDBLoadBalancerFactory(),
1482 $services->getChronologyProtector(),
1483 LoggerFactory::getProvider(),
1484 $services->getWikiPageFactory(),
1485 $services->getTitleFormatter()
1489 'ParsoidDataAccess' => static function ( MediaWikiServices $services ): DataAccess {
1490 $mainConfig = $services->getMainConfig();
1491 return new MWDataAccess(
1492 new ServiceOptions( MWDataAccess::CONSTRUCTOR_OPTIONS, $mainConfig ),
1493 $services->getRepoGroup(),
1494 $services->getBadFileLookup(),
1495 $services->getHookContainer(),
1496 $services->getContentTransformer(),
1497 $services->getReadOnlyMode(),
1498 $services->getParserFactory(), // *legacy* parser factory
1499 $services->getLinkBatchFactory()
1503 'ParsoidOutputAccess' => static function ( MediaWikiServices $services ): ParsoidOutputAccess {
1504 return new ParsoidOutputAccess(
1505 new ServiceOptions(
1506 ParsoidOutputAccess::CONSTRUCTOR_OPTIONS,
1507 $services->getMainConfig(),
1508 [ 'ParsoidWikiID' => WikiMap::getCurrentWikiId() ]
1510 $services->getParsoidParserFactory(),
1511 $services->getParserOutputAccess(),
1512 $services->getPageStore(),
1513 $services->getRevisionLookup(),
1514 $services->getParsoidSiteConfig(),
1515 $services->getContentHandlerFactory()
1519 'ParsoidOutputStash' => static function ( MediaWikiServices $services ): ParsoidOutputStash {
1520 // TODO: Determine storage requirements and config options for stashing parsoid
1521 // output for VE edits (T309016).
1522 $config = $services->getMainConfig()->get( MainConfigNames::ParsoidCacheConfig );
1523 $backend = $config['StashType']
1524 ? ObjectCache::getInstance( $config['StashType'] )
1525 : $services->getMainObjectStash();
1527 return new SimpleParsoidOutputStash(
1528 $services->getContentHandlerFactory(),
1529 $backend,
1530 $config['StashDuration']
1534 'ParsoidPageConfigFactory' => static function ( MediaWikiServices $services ): MWPageConfigFactory {
1535 return new MWPageConfigFactory(
1536 $services->getRevisionStore(),
1537 $services->getSlotRoleRegistry(),
1538 $services->getLanguageFactory()
1542 'ParsoidParserFactory' => static function ( MediaWikiServices $services ): ParsoidParserFactory {
1543 return new ParsoidParserFactory(
1544 $services->getParsoidSiteConfig(),
1545 $services->getParsoidDataAccess(),
1546 $services->getParsoidPageConfigFactory(),
1547 $services->getLanguageConverterFactory(),
1548 $services->getParserFactory(),
1549 $services->getGlobalIdGenerator()
1553 'ParsoidSiteConfig' => static function ( MediaWikiServices $services ): SiteConfig {
1554 $mainConfig = $services->getMainConfig();
1555 $parsoidSettings = $mainConfig->get( MainConfigNames::ParsoidSettings );
1556 return new MWSiteConfig(
1557 new ServiceOptions( MWSiteConfig::CONSTRUCTOR_OPTIONS, $mainConfig ),
1558 $parsoidSettings,
1559 $services->getObjectFactory(),
1560 $services->getContentLanguage(),
1561 $services->getStatsdDataFactory(),
1562 $services->getMagicWordFactory(),
1563 $services->getNamespaceInfo(),
1564 $services->getSpecialPageFactory(),
1565 $services->getInterwikiLookup(),
1566 $services->getUserOptionsLookup(),
1567 $services->getLanguageFactory(),
1568 $services->getLanguageConverterFactory(),
1569 $services->getLanguageNameUtils(),
1570 $services->getUrlUtils(),
1571 ExtensionRegistry::getInstance()->getAttribute( 'ParsoidModules' ),
1572 // These arguments are temporary and will be removed once
1573 // better solutions are found.
1574 $services->getParserFactory(), // T268776
1575 $mainConfig, // T268777
1576 ExtensionRegistry::getInstance()->isLoaded( 'TimedMediaHandler' )
1580 'PasswordFactory' => static function ( MediaWikiServices $services ): PasswordFactory {
1581 $config = $services->getMainConfig();
1582 return new PasswordFactory(
1583 $config->get( MainConfigNames::PasswordConfig ),
1584 $config->get( MainConfigNames::PasswordDefault )
1588 'PasswordReset' => static function ( MediaWikiServices $services ): PasswordReset {
1589 $options = new ServiceOptions( PasswordReset::CONSTRUCTOR_OPTIONS, $services->getMainConfig() );
1590 return new PasswordReset(
1591 $options,
1592 LoggerFactory::getInstance( 'authentication' ),
1593 $services->getAuthManager(),
1594 $services->getHookContainer(),
1595 $services->getDBLoadBalancerFactory(),
1596 $services->getUserFactory(),
1597 $services->getUserNameUtils(),
1598 $services->getUserOptionsLookup()
1602 'PerDbNameStatsdDataFactory' =>
1603 static function ( MediaWikiServices $services ): StatsdDataFactoryInterface {
1604 $config = $services->getMainConfig();
1605 $wiki = $config->get( MainConfigNames::DBname );
1606 return new PrefixingStatsdDataFactoryProxy(
1607 $services->getStatsdDataFactory(),
1608 $wiki
1612 'PermissionManager' => static function ( MediaWikiServices $services ): PermissionManager {
1613 return new PermissionManager(
1614 new ServiceOptions(
1615 PermissionManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
1617 $services->getSpecialPageFactory(),
1618 $services->getNamespaceInfo(),
1619 $services->getGroupPermissionsLookup(),
1620 $services->getUserGroupManager(),
1621 $services->getBlockErrorFormatter(),
1622 $services->getHookContainer(),
1623 $services->getUserCache(),
1624 $services->getRedirectLookup(),
1625 $services->getRestrictionStore(),
1626 $services->getTitleFormatter(),
1627 $services->getTempUserConfig(),
1628 $services->getUserFactory(),
1629 $services->getActionFactory()
1633 'Pingback' => static function ( MediaWikiServices $services ): PingBack {
1634 return new Pingback(
1635 $services->getMainConfig(),
1636 $services->getDBLoadBalancerFactory(),
1637 ObjectCache::getLocalClusterInstance(),
1638 $services->getHttpRequestFactory(),
1639 LoggerFactory::getInstance( 'Pingback' )
1643 'PoolCounterFactory' => static function ( MediaWikiServices $services ): PoolCounterFactory {
1644 $mainConfig = $services->getMainConfig();
1645 return new PoolCounterFactory(
1646 $mainConfig->get( MainConfigNames::PoolCounterConf ),
1647 $mainConfig->get( MainConfigNames::PoolCountClientConf )
1651 'PreferencesFactory' => static function ( MediaWikiServices $services ): PreferencesFactory {
1652 $factory = new DefaultPreferencesFactory(
1653 new ServiceOptions(
1654 DefaultPreferencesFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1655 $services->getContentLanguage(),
1656 $services->getAuthManager(),
1657 $services->getLinkRendererFactory()->create(),
1658 $services->getNamespaceInfo(),
1659 $services->getPermissionManager(),
1660 $services->getLanguageConverterFactory()->getLanguageConverter(),
1661 $services->getLanguageNameUtils(),
1662 $services->getHookContainer(),
1663 $services->getUserOptionsManager(),
1664 $services->getLanguageConverterFactory(),
1665 $services->getParserFactory(),
1666 $services->getSkinFactory(),
1667 $services->getUserGroupManager(),
1668 $services->getSignatureValidatorFactory(),
1669 $services->getMainConfig()
1671 $factory->setLogger( LoggerFactory::getInstance( 'preferences' ) );
1673 return $factory;
1676 'PreloadedContentBuilder' => static function ( MediaWikiServices $services ): PreloadedContentBuilder {
1677 return new PreloadedContentBuilder(
1678 $services->getContentHandlerFactory(),
1679 $services->getWikiPageFactory(),
1680 $services->getRedirectLookup(),
1681 $services->getSpecialPageFactory(),
1682 $services->getContentTransformer(),
1683 $services->getHookContainer(),
1687 'ProxyLookup' => static function ( MediaWikiServices $services ): ProxyLookup {
1688 $mainConfig = $services->getMainConfig();
1689 return new ProxyLookup(
1690 $mainConfig->get( MainConfigNames::CdnServers ),
1691 $mainConfig->get( MainConfigNames::CdnServersNoPurge ),
1692 $services->getHookContainer()
1696 'RateLimiter' => static function ( MediaWikiServices $services ): RateLimiter {
1697 $rateLimiter = new RateLimiter(
1698 new ServiceOptions( RateLimiter::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1699 $services->getWRStatsFactory(),
1700 $services->getCentralIdLookupFactory()->getNonLocalLookup(),
1701 $services->getUserFactory(),
1702 $services->getUserGroupManager(),
1703 $services->getHookContainer()
1706 $rateLimiter->setStats( $services->getStatsdDataFactory() );
1708 return $rateLimiter;
1711 'ReadOnlyMode' => static function ( MediaWikiServices $services ): ReadOnlyMode {
1712 return new ReadOnlyMode(
1713 new ConfiguredReadOnlyMode(
1714 $services->getMainConfig()->get( MainConfigNames::ReadOnly ),
1715 $services->getMainConfig()->get( MainConfigNames::ReadOnlyFile )
1717 $services->getDBLoadBalancerFactory()
1721 'RedirectLookup' => static function ( MediaWikiServices $services ): RedirectLookup {
1722 return $services->getRedirectStore();
1725 'RedirectStore' => static function ( MediaWikiServices $services ): RedirectStore {
1726 return new RedirectStore( $services->getWikiPageFactory() );
1729 'RepoGroup' => static function ( MediaWikiServices $services ): RepoGroup {
1730 $config = $services->getMainConfig();
1731 return new RepoGroup(
1732 $config->get( MainConfigNames::LocalFileRepo ),
1733 $config->get( MainConfigNames::ForeignFileRepos ),
1734 $services->getMainWANObjectCache(),
1735 $services->getMimeAnalyzer()
1739 'ResourceLoader' => static function ( MediaWikiServices $services ): ResourceLoader {
1740 $config = $services->getMainConfig();
1742 $maxage = $config->get( MainConfigNames::ResourceLoaderMaxage );
1743 $rl = new ResourceLoader(
1744 $config,
1745 LoggerFactory::getInstance( 'resourceloader' ),
1746 $config->get( MainConfigNames::ResourceLoaderUseObjectCacheForDeps )
1747 ? new KeyValueDependencyStore( $services->getMainObjectStash() )
1748 : new SqlModuleDependencyStore( $services->getDBLoadBalancer() ),
1750 'loadScript' => $config->get( MainConfigNames::LoadScript ),
1751 'maxageVersioned' => $maxage['versioned'] ?? null,
1752 'maxageUnversioned' => $maxage['unversioned'] ?? null,
1756 $extRegistry = ExtensionRegistry::getInstance();
1757 // Attribute has precedence over config
1758 $modules = $extRegistry->getAttribute( 'ResourceModules' )
1759 + $config->get( MainConfigNames::ResourceModules );
1760 $moduleSkinStyles = $extRegistry->getAttribute( 'ResourceModuleSkinStyles' )
1761 + $config->get( MainConfigNames::ResourceModuleSkinStyles );
1763 $rl->setModuleSkinStyles( $moduleSkinStyles );
1764 $rl->addSource( $config->get( MainConfigNames::ResourceLoaderSources ) );
1766 // Core modules, then extension/skin modules
1767 $rl->register( include MW_INSTALL_PATH . '/resources/Resources.php' );
1768 $rl->register( $modules );
1769 $hookRunner = new \MediaWiki\ResourceLoader\HookRunner( $services->getHookContainer() );
1770 $hookRunner->onResourceLoaderRegisterModules( $rl );
1772 $msgPosterAttrib = $extRegistry->getAttribute( 'MessagePosterModule' );
1773 $rl->register( 'mediawiki.messagePoster', [
1774 'localBasePath' => MW_INSTALL_PATH,
1775 'debugRaw' => false,
1776 'scripts' => array_merge(
1778 "resources/src/mediawiki.messagePoster/factory.js",
1779 "resources/src/mediawiki.messagePoster/MessagePoster.js",
1780 "resources/src/mediawiki.messagePoster/WikitextMessagePoster.js",
1782 $msgPosterAttrib['scripts'] ?? []
1784 'dependencies' => array_merge(
1786 'oojs',
1787 'mediawiki.api',
1788 'mediawiki.ForeignApi',
1790 $msgPosterAttrib['dependencies'] ?? []
1792 'targets' => [ 'desktop', 'mobile' ],
1793 ] );
1795 if ( $config->get( MainConfigNames::EnableJavaScriptTest ) === true ) {
1796 $rl->registerTestModules();
1799 return $rl;
1802 'RestrictionStore' => static function ( MediaWikiServices $services ): RestrictionStore {
1803 return new RestrictionStore(
1804 new ServiceOptions(
1805 RestrictionStore::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
1807 $services->getMainWANObjectCache(),
1808 $services->getDBLoadBalancer(),
1809 $services->getLinkCache(),
1810 $services->getLinksMigration(),
1811 $services->getCommentStore(),
1812 $services->getHookContainer(),
1813 $services->getPageStore()
1817 'RevertedTagUpdateManager' => static function ( MediaWikiServices $services ): RevertedTagUpdateManager {
1818 $editResultCache = new EditResultCache(
1819 $services->getMainObjectStash(),
1820 $services->getDBLoadBalancerFactory(),
1821 new ServiceOptions(
1822 EditResultCache::CONSTRUCTOR_OPTIONS,
1823 $services->getMainConfig()
1827 return new RevertedTagUpdateManager(
1828 $editResultCache,
1829 $services->getJobQueueGroup()
1833 'RevisionFactory' => static function ( MediaWikiServices $services ): RevisionFactory {
1834 return $services->getRevisionStore();
1837 'RevisionLookup' => static function ( MediaWikiServices $services ): RevisionLookup {
1838 return $services->getRevisionStore();
1841 'RevisionRenderer' => static function ( MediaWikiServices $services ): RevisionRenderer {
1842 $renderer = new RevisionRenderer(
1843 $services->getDBLoadBalancer(),
1844 $services->getSlotRoleRegistry(),
1845 $services->getContentRenderer()
1848 $renderer->setLogger( LoggerFactory::getInstance( 'SaveParse' ) );
1849 return $renderer;
1852 'RevisionStore' => static function ( MediaWikiServices $services ): RevisionStore {
1853 return $services->getRevisionStoreFactory()->getRevisionStore();
1856 'RevisionStoreFactory' => static function ( MediaWikiServices $services ): RevisionStoreFactory {
1857 return new RevisionStoreFactory(
1858 $services->getDBLoadBalancerFactory(),
1859 $services->getBlobStoreFactory(),
1860 $services->getNameTableStoreFactory(),
1861 $services->getSlotRoleRegistry(),
1862 $services->getMainWANObjectCache(),
1863 $services->getLocalServerObjectCache(),
1864 $services->getCommentStore(),
1865 $services->getActorMigration(),
1866 $services->getActorStoreFactory(),
1867 LoggerFactory::getInstance( 'RevisionStore' ),
1868 $services->getContentHandlerFactory(),
1869 $services->getPageStoreFactory(),
1870 $services->getTitleFactory(),
1871 $services->getHookContainer()
1875 'RollbackPageFactory' => static function ( MediaWikiServices $services ): RollbackPageFactory {
1876 return $services->get( '_PageCommandFactory' );
1879 'RowCommentFormatter' => static function ( MediaWikiServices $services ): RowCommentFormatter {
1880 return new RowCommentFormatter(
1881 $services->getCommentParserFactory(),
1882 $services->getCommentStore()
1886 'SearchEngineConfig' => static function ( MediaWikiServices $services ): SearchEngineConfig {
1887 // @todo This should not take a Config object, but it's not so easy to remove because it
1888 // exposes it in a getter, which is actually used.
1889 return new SearchEngineConfig(
1890 $services->getMainConfig(),
1891 $services->getContentLanguage(),
1892 $services->getHookContainer(),
1893 ExtensionRegistry::getInstance()->getAttribute( 'SearchMappings' ),
1894 $services->getUserOptionsLookup()
1898 'SearchEngineFactory' => static function ( MediaWikiServices $services ): SearchEngineFactory {
1899 return new SearchEngineFactory(
1900 $services->getSearchEngineConfig(),
1901 $services->getHookContainer(),
1902 $services->getDBLoadBalancerFactory()
1906 'SearchResultThumbnailProvider' => static function ( MediaWikiServices $services ): SearchResultThumbnailProvider {
1907 return new SearchResultThumbnailProvider(
1908 $services->getRepoGroup(),
1909 $services->getHookContainer()
1913 'ShellboxClientFactory' => static function ( MediaWikiServices $services ): ShellboxClientFactory {
1914 $urls = $services->getMainConfig()->get( MainConfigNames::ShellboxUrls );
1916 return new ShellboxClientFactory(
1917 $services->getHttpRequestFactory(),
1918 $urls,
1919 $services->getMainConfig()->get( MainConfigNames::ShellboxSecretKey )
1923 'ShellCommandFactory' => static function ( MediaWikiServices $services ): CommandFactory {
1924 $config = $services->getMainConfig();
1926 $limits = [
1927 'time' => $config->get( MainConfigNames::MaxShellTime ),
1928 'walltime' => $config->get( MainConfigNames::MaxShellWallClockTime ),
1929 'memory' => $config->get( MainConfigNames::MaxShellMemory ),
1930 'filesize' => $config->get( MainConfigNames::MaxShellFileSize ),
1932 $cgroup = $config->get( MainConfigNames::ShellCgroup );
1933 $restrictionMethod = $config->get( MainConfigNames::ShellRestrictionMethod );
1935 $factory = new CommandFactory( $services->getShellboxClientFactory(),
1936 $limits, $cgroup, $restrictionMethod );
1937 $factory->setLogger( LoggerFactory::getInstance( 'exec' ) );
1938 $factory->logStderr();
1940 return $factory;
1943 'SignatureValidatorFactory' => static function ( MediaWikiServices $services ): SignatureValidatorFactory {
1944 return new SignatureValidatorFactory(
1945 new ServiceOptions(
1946 SignatureValidator::CONSTRUCTOR_OPTIONS,
1947 $services->getMainConfig()
1949 // Use closures for these to avoid a circular dependency on Parser
1950 static function () use ( $services ) {
1951 return $services->getParserFactory();
1953 static function () use ( $services ) {
1954 return $services->get( '_Parsoid' );
1956 $services->getParsoidPageConfigFactory(),
1957 $services->getSpecialPageFactory(),
1958 $services->getTitleFactory()
1962 'SiteLookup' => static function ( MediaWikiServices $services ): SiteLookup {
1963 // Use SiteStore as the SiteLookup as well. This was originally separated
1964 // to allow for a cacheable read-only interface, but this was never used.
1965 // SiteStore has caching (see below).
1966 return $services->getSiteStore();
1969 'SiteStore' => static function ( MediaWikiServices $services ): SiteStore {
1970 $rawSiteStore = new DBSiteStore( $services->getDBLoadBalancerFactory() );
1972 $cache = $services->getLocalServerObjectCache();
1973 if ( $cache instanceof EmptyBagOStuff ) {
1974 $cache = ObjectCache::getLocalClusterInstance();
1977 return new CachingSiteStore( $rawSiteStore, $cache );
1980 /** @suppress PhanTypeInvalidCallableArrayKey */
1981 'SkinFactory' => static function ( MediaWikiServices $services ): SkinFactory {
1982 $factory = new SkinFactory(
1983 $services->getObjectFactory(),
1984 (array)$services->getMainConfig()->get( MainConfigNames::SkipSkins )
1987 $names = $services->getMainConfig()->get( MainConfigNames::ValidSkinNames );
1989 foreach ( $names as $name => $skin ) {
1990 if ( is_array( $skin ) ) {
1991 $spec = $skin;
1992 $displayName = $skin['displayname'] ?? $name;
1993 $skippable = $skin['skippable'] ?? null;
1994 } else {
1995 $displayName = $skin;
1996 $skippable = null;
1997 $spec = [
1998 'name' => $name,
1999 'class' => "Skin$skin"
2002 $factory->register( $name, $displayName, $spec, $skippable );
2005 // Register a hidden "fallback" skin
2006 $factory->register( 'fallback', 'Fallback', [
2007 'class' => SkinFallback::class,
2008 'args' => [
2010 'name' => 'fallback',
2011 'styles' => [ 'mediawiki.skinning.interface' ],
2012 'templateDirectory' => __DIR__ . '/skins/templates/fallback',
2015 ], true );
2016 // Register a hidden skin for api output
2017 $factory->register( 'apioutput', 'ApiOutput', [
2018 'class' => SkinApi::class,
2019 'args' => [
2021 'name' => 'apioutput',
2022 'styles' => [ 'mediawiki.skinning.interface' ],
2023 'templateDirectory' => __DIR__ . '/skins/templates/apioutput',
2026 ], true );
2028 return $factory;
2031 'SlotRoleRegistry' => static function ( MediaWikiServices $services ): SlotRoleRegistry {
2032 $registry = new SlotRoleRegistry(
2033 $services->getSlotRoleStore()
2036 $config = $services->getMainConfig();
2037 $contentHandlerFactory = $services->getContentHandlerFactory();
2038 $hookContainer = $services->getHookContainer();
2039 $titleFactory = $services->getTitleFactory();
2040 $registry->defineRole(
2041 SlotRecord::MAIN,
2042 static function () use ( $config, $contentHandlerFactory, $hookContainer, $titleFactory ) {
2043 return new MainSlotRoleHandler(
2044 $config->get( MainConfigNames::NamespaceContentModels ),
2045 $contentHandlerFactory,
2046 $hookContainer,
2047 $titleFactory
2052 return $registry;
2055 'SlotRoleStore' => static function ( MediaWikiServices $services ): NameTableStore {
2056 return $services->getNameTableStoreFactory()->getSlotRoles();
2059 'SpamChecker' => static function ( MediaWikiServices $services ): SpamChecker {
2060 return new SpamChecker(
2061 (array)$services->getMainConfig()->get( MainConfigNames::SpamRegex ),
2062 (array)$services->getMainConfig()->get( MainConfigNames::SummarySpamRegex )
2066 'SpecialPageFactory' => static function ( MediaWikiServices $services ): SpecialPageFactory {
2067 return new SpecialPageFactory(
2068 new ServiceOptions(
2069 SpecialPageFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
2070 $services->getContentLanguage(),
2071 $services->getObjectFactory(),
2072 $services->getTitleFactory(),
2073 $services->getHookContainer()
2077 'StatsdDataFactory' => static function ( MediaWikiServices $services ): IBufferingStatsdDataFactory {
2078 return new BufferingStatsdDataFactory(
2079 rtrim( $services->getMainConfig()->get( MainConfigNames::StatsdMetricPrefix ), '.' )
2083 'StatsFactory' => static function ( MediaWikiServices $services ): StatsFactory {
2084 $config = $services->getMainConfig();
2085 $format = \Wikimedia\Stats\OutputFormats::getFormatFromString(
2086 $config->get( MainConfigNames::StatsFormat ) ?? 'null'
2088 $cache = new StatsCache;
2089 $emitter = \Wikimedia\Stats\OutputFormats::getNewEmitter(
2090 $config->get( MainConfigNames::StatsPrefix ) ?? 'MediaWiki',
2091 $cache,
2092 \Wikimedia\Stats\OutputFormats::getNewFormatter( $format ),
2093 $config->get( MainConfigNames::StatsTarget )
2095 $factory = new StatsFactory( $cache, $emitter, LoggerFactory::getInstance( 'Stats' ) );
2096 return $factory->withStatsdDataFactory( $services->getStatsdDataFactory() );
2099 'TalkPageNotificationManager' => static function (
2100 MediaWikiServices $services
2101 ): TalkPageNotificationManager {
2102 return new TalkPageNotificationManager(
2103 new ServiceOptions(
2104 TalkPageNotificationManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
2106 $services->getDBLoadBalancerFactory(),
2107 $services->getReadOnlyMode(),
2108 $services->getRevisionLookup(),
2109 $services->getHookContainer(),
2110 $services->getUserFactory()
2114 'TempFSFileFactory' => static function ( MediaWikiServices $services ): TempFSFileFactory {
2115 return new TempFSFileFactory( $services->getMainConfig()->get( MainConfigNames::TmpDirectory ) );
2118 'TempUserConfig' => static function ( MediaWikiServices $services ): RealTempUserConfig {
2119 return new RealTempUserConfig(
2120 $services->getMainConfig()->get( MainConfigNames::AutoCreateTempUser )
2124 'TempUserCreator' => static function ( MediaWikiServices $services ): TempUserCreator {
2125 $accountCreationThrottle = $services->getMainConfig()->get( MainConfigNames::AccountCreationThrottle );
2126 // T306878: Handle old $wgAccountCreationThrottle format (number of attempts per 24 hours)
2127 if ( !is_array( $accountCreationThrottle ) ) {
2128 $accountCreationThrottle = [ [
2129 'count' => $accountCreationThrottle,
2130 'seconds' => 86400,
2131 ] ];
2134 return new TempUserCreator(
2135 $services->getTempUserConfig(),
2136 $services->getObjectFactory(),
2137 $services->getUserFactory(),
2138 $services->getAuthManager(),
2139 // This is supposed to match ThrottlePreAuthenticationProvider
2140 new Throttler(
2141 $accountCreationThrottle,
2143 'type' => 'acctcreate',
2144 'cache' => $services->getLocalServerObjectCache()
2150 'Tidy' => static function ( MediaWikiServices $services ): TidyDriverBase {
2151 return new RemexDriver(
2152 new ServiceOptions(
2153 RemexDriver::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
2158 'TitleFactory' => static function ( MediaWikiServices $services ): TitleFactory {
2159 return new TitleFactory();
2162 'TitleFormatter' => static function ( MediaWikiServices $services ): TitleFormatter {
2163 return $services->getService( '_MediaWikiTitleCodec' );
2166 'TitleMatcher' => static function ( MediaWikiServices $services ): TitleMatcher {
2167 return new TitleMatcher(
2168 new ServiceOptions(
2169 TitleMatcher::CONSTRUCTOR_OPTIONS,
2170 $services->getMainConfig()
2172 $services->getContentLanguage(),
2173 $services->getLanguageConverterFactory(),
2174 $services->getHookContainer(),
2175 $services->getWikiPageFactory(),
2176 $services->getUserNameUtils(),
2177 $services->getRepoGroup(),
2178 $services->getTitleFactory()
2182 'TitleParser' => static function ( MediaWikiServices $services ): TitleParser {
2183 return $services->getService( '_MediaWikiTitleCodec' );
2186 'TrackingCategories' => static function ( MediaWikiServices $services ): TrackingCategories {
2187 return new TrackingCategories(
2188 new ServiceOptions(
2189 TrackingCategories::CONSTRUCTOR_OPTIONS,
2190 $services->getMainConfig()
2192 $services->getNamespaceInfo(),
2193 $services->getTitleParser(),
2194 LoggerFactory::getInstance( 'TrackingCategories' )
2198 'UnblockUserFactory' => static function ( MediaWikiServices $services ): UnblockUserFactory {
2199 return $services->getService( '_UserBlockCommandFactory' );
2202 'UndeletePageFactory' => static function ( MediaWikiServices $services ): UndeletePageFactory {
2203 return $services->getService( '_PageCommandFactory' );
2206 'UploadRevisionImporter' => static function ( MediaWikiServices $services ): UploadRevisionImporter {
2207 return new ImportableUploadRevisionImporter(
2208 $services->getMainConfig()->get( MainConfigNames::EnableUploads ),
2209 LoggerFactory::getInstance( 'UploadRevisionImporter' )
2213 'UrlUtils' => static function ( MediaWikiServices $services ): UrlUtils {
2214 $config = $services->getMainConfig();
2215 return new UrlUtils( [
2216 UrlUtils::SERVER => $config->get( MainConfigNames::Server ),
2217 UrlUtils::CANONICAL_SERVER => $config->get( MainConfigNames::CanonicalServer ),
2218 UrlUtils::INTERNAL_SERVER => $config->get( MainConfigNames::InternalServer ),
2219 UrlUtils::FALLBACK_PROTOCOL => RequestContext::getMain()->getRequest()->getProtocol(),
2220 UrlUtils::HTTPS_PORT => $config->get( MainConfigNames::HttpsPort ),
2221 UrlUtils::VALID_PROTOCOLS => $config->get( MainConfigNames::UrlProtocols ),
2222 ] );
2225 'UserCache' => static function ( MediaWikiServices $services ): UserCache {
2226 return new UserCache(
2227 LoggerFactory::getInstance( 'UserCache' ),
2228 $services->getDBLoadBalancerFactory(),
2229 $services->getLinkBatchFactory()
2233 'UserEditTracker' => static function ( MediaWikiServices $services ): UserEditTracker {
2234 return new UserEditTracker(
2235 $services->getActorMigration(),
2236 $services->getDBLoadBalancerFactory(),
2237 $services->getJobQueueGroup()
2241 'UserFactory' => static function ( MediaWikiServices $services ): UserFactory {
2242 return new UserFactory(
2243 new ServiceOptions(
2244 UserFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
2246 $services->getDBLoadBalancerFactory(),
2247 $services->getUserNameUtils()
2251 'UserGroupManager' => static function ( MediaWikiServices $services ): UserGroupManager {
2252 return $services->getUserGroupManagerFactory()->getUserGroupManager();
2255 'UserGroupManagerFactory' => static function ( MediaWikiServices $services ): UserGroupManagerFactory {
2256 return new UserGroupManagerFactory(
2257 new ServiceOptions(
2258 UserGroupManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
2260 $services->getReadOnlyMode(),
2261 $services->getDBLoadBalancerFactory(),
2262 $services->getHookContainer(),
2263 $services->getUserEditTracker(),
2264 $services->getGroupPermissionsLookup(),
2265 $services->getJobQueueGroupFactory(),
2266 LoggerFactory::getInstance( 'UserGroupManager' ),
2267 $services->getTempUserConfig(),
2268 [ static function ( UserIdentity $user ) use ( $services ) {
2269 if ( $user->getWikiId() === UserIdentity::LOCAL ) {
2270 $services->getPermissionManager()->invalidateUsersRightsCache( $user );
2272 $services->getUserFactory()->invalidateCache( $user );
2277 'UserIdentityLookup' => static function ( MediaWikiServices $services ): UserIdentityLookup {
2278 return $services->getActorStoreFactory()->getUserIdentityLookup();
2281 'UserIdentityUtils' => static function ( MediaWikiServices $services ): UserIdentityUtils {
2282 return new UserIdentityUtils(
2283 $services->getTempUserConfig()
2287 'UserNamePrefixSearch' => static function ( MediaWikiServices $services ): UserNamePrefixSearch {
2288 return new UserNamePrefixSearch(
2289 $services->getDBLoadBalancerFactory(),
2290 $services->getUserNameUtils()
2294 'UserNameUtils' => static function ( MediaWikiServices $services ): UserNameUtils {
2295 $messageFormatterFactory = new MessageFormatterFactory( Message::FORMAT_PLAIN );
2296 return new UserNameUtils(
2297 new ServiceOptions(
2298 UserNameUtils::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
2300 $services->getContentLanguage(),
2301 LoggerFactory::getInstance( 'UserNameUtils' ),
2302 $services->getTitleParser(),
2303 $messageFormatterFactory->getTextFormatter(
2304 $services->getContentLanguage()->getCode()
2306 $services->getHookContainer(),
2307 $services->getTempUserConfig()
2311 'UserOptionsLookup' => static function ( MediaWikiServices $services ): UserOptionsLookup {
2312 return $services->getUserOptionsManager();
2315 'UserOptionsManager' => static function ( MediaWikiServices $services ): UserOptionsManager {
2316 return new UserOptionsManager(
2317 new ServiceOptions( UserOptionsManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
2318 $services->get( '_DefaultOptionsLookup' ),
2319 $services->getLanguageConverterFactory(),
2320 $services->getDBLoadBalancerFactory(),
2321 LoggerFactory::getInstance( 'UserOptionsManager' ),
2322 $services->getHookContainer(),
2323 $services->getUserFactory(),
2324 $services->getUserNameUtils()
2328 'UserRegistrationLookup' => static function ( MediaWikiServices $services ): UserRegistrationLookup {
2329 $lookup = new UserRegistrationLookup(
2330 new ServiceOptions( UserRegistrationLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
2331 $services->getObjectFactory()
2333 if ( !$lookup->isRegistered( LocalUserRegistrationProvider::TYPE ) ) {
2334 throw new ConfigException( 'UserRegistrationLookup: Local provider is required' );
2336 return $lookup;
2339 'VirtualRESTServiceClient' =>
2340 static function ( MediaWikiServices $services ): VirtualRESTServiceClient {
2341 $config = $services->getMainConfig()->get( MainConfigNames::VirtualRestConfig );
2343 $vrsClient = new VirtualRESTServiceClient(
2344 $services->getHttpRequestFactory()->createMultiClient() );
2345 foreach ( $config['paths'] as $prefix => $serviceConfig ) {
2346 $class = $serviceConfig['class'];
2347 // Merge in the global defaults
2348 $constructArg = $serviceConfig['options'] ?? [];
2349 $constructArg += $config['global'];
2350 // Make the VRS service available at the mount point
2351 $vrsClient->mount( $prefix, [ 'class' => $class, 'config' => $constructArg ] );
2354 return $vrsClient;
2357 'WatchedItemQueryService' =>
2358 static function ( MediaWikiServices $services ): WatchedItemQueryService {
2359 return new WatchedItemQueryService(
2360 $services->getDBLoadBalancerFactory(),
2361 $services->getCommentStore(),
2362 $services->getWatchedItemStore(),
2363 $services->getHookContainer(),
2364 $services->getUserOptionsLookup(),
2365 $services->getMainConfig()->get( MainConfigNames::WatchlistExpiry ),
2366 $services->getMainConfig()->get( MainConfigNames::MaxExecutionTimeForExpensiveQueries )
2370 'WatchedItemStore' => static function ( MediaWikiServices $services ): WatchedItemStore {
2371 $store = new WatchedItemStore(
2372 new ServiceOptions( WatchedItemStore::CONSTRUCTOR_OPTIONS,
2373 $services->getMainConfig() ),
2374 $services->getDBLoadBalancerFactory(),
2375 $services->getJobQueueGroup(),
2376 $services->getMainObjectStash(),
2377 new HashBagOStuff( [ 'maxKeys' => 100 ] ),
2378 $services->getReadOnlyMode(),
2379 $services->getNamespaceInfo(),
2380 $services->getRevisionLookup(),
2381 $services->getLinkBatchFactory()
2383 $store->setStatsdDataFactory( $services->getStatsdDataFactory() );
2385 if ( $services->getMainConfig()->get( MainConfigNames::ReadOnlyWatchedItemStore ) ) {
2386 $store = new NoWriteWatchedItemStore( $store );
2389 return $store;
2392 'WatchlistManager' => static function ( MediaWikiServices $services ): WatchlistManager {
2393 return new WatchlistManager(
2395 WatchlistManager::OPTION_ENOTIF =>
2396 RecentChange::isEnotifEnabled( $services->getMainConfig() ),
2398 $services->getHookContainer(),
2399 $services->getReadOnlyMode(),
2400 $services->getRevisionLookup(),
2401 $services->getTalkPageNotificationManager(),
2402 $services->getWatchedItemStore(),
2403 $services->getUserFactory(),
2404 $services->getNamespaceInfo(),
2405 $services->getWikiPageFactory()
2409 'WikiExporterFactory' => static function ( MediaWikiServices $services ): WikiExporterFactory {
2410 return new WikiExporterFactory(
2411 $services->getHookContainer(),
2412 $services->getRevisionStore(),
2413 $services->getTitleParser(),
2414 $services->getCommentStore()
2418 'WikiImporterFactory' => static function ( MediaWikiServices $services ): WikiImporterFactory {
2419 return new WikiImporterFactory(
2420 $services->getMainConfig(),
2421 $services->getHookContainer(),
2422 $services->getContentLanguage(),
2423 $services->getNamespaceInfo(),
2424 $services->getTitleFactory(),
2425 $services->getWikiPageFactory(),
2426 $services->getWikiRevisionUploadImporter(),
2427 $services->getPermissionManager(),
2428 $services->getContentHandlerFactory(),
2429 $services->getSlotRoleRegistry()
2433 'WikiPageFactory' => static function ( MediaWikiServices $services ): WikiPageFactory {
2434 return new WikiPageFactory(
2435 $services->getTitleFactory(),
2436 new HookRunner( $services->getHookContainer() ),
2437 $services->getDBLoadBalancer()
2441 'WikiRevisionOldRevisionImporterNoUpdates' =>
2442 static function ( MediaWikiServices $services ): ImportableOldRevisionImporter {
2443 return new ImportableOldRevisionImporter(
2444 false,
2445 LoggerFactory::getInstance( 'OldRevisionImporter' ),
2446 $services->getDBLoadBalancerFactory(),
2447 $services->getRevisionStore(),
2448 $services->getSlotRoleRegistry(),
2449 $services->getWikiPageFactory(),
2450 $services->getPageUpdaterFactory(),
2451 $services->getUserFactory()
2455 'WRStatsFactory' => static function ( MediaWikiServices $services ): WRStatsFactory {
2456 return new WRStatsFactory(
2457 new BagOStuffStatsStore(
2458 ObjectCache::getInstance( $services->getMainConfig()->get( MainConfigNames::StatsCacheType ) )
2463 '_DefaultOptionsLookup' => static function ( MediaWikiServices $services ): DefaultOptionsLookup {
2464 return new DefaultOptionsLookup(
2465 new ServiceOptions( DefaultOptionsLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
2466 $services->getContentLanguage(),
2467 $services->getHookContainer(),
2468 $services->getNamespaceInfo(),
2469 defined( 'MW_PHPUNIT_TEST' ) && $services->isStorageDisabled()
2473 '_EditConstraintFactory' => static function ( MediaWikiServices $services ): EditConstraintFactory {
2474 // This service is internal and currently only exists because a significant number
2475 // of dependencies will be needed by different constraints. It is not part of
2476 // the public interface and has no corresponding method in MediaWikiServices
2477 return new EditConstraintFactory(
2478 // Multiple
2479 new ServiceOptions(
2480 EditConstraintFactory::CONSTRUCTOR_OPTIONS,
2481 $services->getMainConfig()
2483 LoggerFactory::getProvider(),
2485 // UserBlockConstraint
2486 $services->getPermissionManager(),
2488 // EditFilterMergedContentHookConstraint
2489 $services->getHookContainer(),
2491 // ReadOnlyConstraint
2492 $services->getReadOnlyMode(),
2494 // SpamRegexConstraint
2495 $services->getSpamChecker()
2499 '_LocalClusterCache' => static function ( MediaWikiServices $services ): BagOStuff {
2500 $mainConfig = $services->getMainConfig();
2501 $id = $mainConfig->get( MainConfigNames::MainCacheType );
2502 $params = $mainConfig->get( MainConfigNames::ObjectCaches )[$id] ?? null;
2503 if ( !$params ) {
2504 throw new ConfigException(
2505 "\$wgObjectCaches must have \"$id\" set (via \$wgMainCacheType)"
2508 return ObjectCache::newFromParams( $params, $services );
2511 '_MediaWikiTitleCodec' => static function ( MediaWikiServices $services ): MediaWikiTitleCodec {
2512 return new MediaWikiTitleCodec(
2513 $services->getContentLanguage(),
2514 $services->getGenderCache(),
2515 $services->getMainConfig()->get( MainConfigNames::LocalInterwikis ),
2516 $services->getInterwikiLookup(),
2517 $services->getNamespaceInfo()
2521 '_PageCommandFactory' => static function ( MediaWikiServices $services ): PageCommandFactory {
2522 return new PageCommandFactory(
2523 $services->getMainConfig(),
2524 $services->getDBLoadBalancerFactory(),
2525 $services->getNamespaceInfo(),
2526 $services->getWatchedItemStore(),
2527 $services->getRepoGroup(),
2528 $services->getReadOnlyMode(),
2529 $services->getContentHandlerFactory(),
2530 $services->getRevisionStore(),
2531 $services->getSpamChecker(),
2532 $services->getTitleFormatter(),
2533 $services->getHookContainer(),
2534 $services->getWikiPageFactory(),
2535 $services->getUserFactory(),
2536 $services->getActorMigration(),
2537 $services->getActorNormalization(),
2538 $services->getTitleFactory(),
2539 $services->getUserEditTracker(),
2540 $services->getCollationFactory(),
2541 $services->getJobQueueGroup(),
2542 $services->getCommentStore(),
2543 $services->getMainObjectStash(),
2544 WikiMap::getCurrentWikiDbDomain()->getId(),
2545 WebRequest::getRequestId(),
2546 $services->getBacklinkCacheFactory(),
2547 LoggerFactory::getInstance( 'UndeletePage' ),
2548 $services->getPageUpdaterFactory(),
2549 $services->getMessageFormatterFactory()->getTextFormatter(
2550 $services->getContentLanguage()->getCode()
2552 $services->getArchivedRevisionLookup(),
2553 $services->getRestrictionStore(),
2554 $services->getLinkTargetLookup()
2558 '_ParserObserver' => static function ( MediaWikiServices $services ): ParserObserver {
2559 return new ParserObserver( LoggerFactory::getInstance( 'DuplicateParse' ) );
2562 '_Parsoid' => static function ( MediaWikiServices $services ): Parsoid {
2563 return new Parsoid(
2564 $services->getParsoidSiteConfig(),
2565 $services->getParsoidDataAccess()
2569 '_SettingsBuilder' => static function ( MediaWikiServices $services ): SettingsBuilder {
2570 return SettingsBuilder::getInstance();
2573 '_SqlBlobStore' => static function ( MediaWikiServices $services ): SqlBlobStore {
2574 return $services->getBlobStoreFactory()->newSqlBlobStore();
2577 '_UserBlockCommandFactory' => static function ( MediaWikiServices $services ): UserBlockCommandFactory {
2578 return new UserBlockCommandFactory(
2579 new ServiceOptions( UserBlockCommandFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
2580 $services->getHookContainer(),
2581 $services->getBlockPermissionCheckerFactory(),
2582 $services->getBlockUtils(),
2583 $services->getDatabaseBlockStore(),
2584 $services->getBlockRestrictionStore(),
2585 $services->getUserFactory(),
2586 $services->getUserEditTracker(),
2587 LoggerFactory::getInstance( 'BlockManager' ),
2588 $services->getTitleFactory(),
2589 $services->getTempUserConfig(),
2590 $services->getBlockActionInfo()
2594 ///////////////////////////////////////////////////////////////////////////
2595 // NOTE: When adding a service here, don't forget to add a getter function
2596 // in the MediaWikiServices class. The convenience getter should just call
2597 // $this->getService( 'FooBarService' ).
2598 ///////////////////////////////////////////////////////////////////////////