MediaWiki REL1_35
ServiceWiring.php
Go to the documentation of this file.
1<?php
47use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
117use Wikimedia\ObjectFactory;
118use Wikimedia\Services\RecursiveServiceDependencyException;
120
121return [
122 'ActorMigration' => function () : ActorMigration {
124 },
125
126 'AuthManager' => function ( MediaWikiServices $services ) : AuthManager {
127 $authManager = new AuthManager(
128 RequestContext::getMain()->getRequest(),
129 $services->getMainConfig(),
130 $services->getObjectFactory(),
131 $services->getPermissionManager(),
132 $services->getHookContainer()
133 );
134 $authManager->setLogger( LoggerFactory::getInstance( 'authentication' ) );
135 return $authManager;
136 },
137
138 'BadFileLookup' => function ( MediaWikiServices $services ) : BadFileLookup {
140 function () {
141 return wfMessage( 'bad_image_list' )->inContentLanguage()->plain();
142 },
143 $services->getLocalServerObjectCache(),
144 $services->getRepoGroup(),
145 $services->getTitleParser(),
146 $services->getHookContainer()
147 );
148 },
149
150 'BlobStore' => function ( MediaWikiServices $services ) : BlobStore {
151 return $services->getService( '_SqlBlobStore' );
152 },
153
154 'BlobStoreFactory' => function ( MediaWikiServices $services ) : BlobStoreFactory {
156 $services->getDBLoadBalancerFactory(),
157 $services->getExternalStoreAccess(),
158 $services->getMainWANObjectCache(),
159 new ServiceOptions( BlobStoreFactory::CONSTRUCTOR_OPTIONS,
160 $services->getMainConfig() )
161 );
162 },
163
164 'BlockErrorFormatter' => function () : BlockErrorFormatter {
166 },
167
168 'BlockManager' => function ( MediaWikiServices $services ) : BlockManager {
170 new ServiceOptions(
171 BlockManager::CONSTRUCTOR_OPTIONS,
172 $services->getMainConfig()
173 ),
174 $services->getPermissionManager(),
175 LoggerFactory::getInstance( 'BlockManager' ),
176 $services->getHookContainer()
177 );
178 },
179
180 'BlockPermissionCheckerFactory' => function (
181 MediaWikiServices $services
184 $services->getPermissionManager()
185 );
186 },
187
188 'BlockRestrictionStore' => function ( MediaWikiServices $services ) : BlockRestrictionStore {
190 $services->getDBLoadBalancer()
191 );
192 },
193
194 'ChangeTagDefStore' => function ( MediaWikiServices $services ) : NameTableStore {
195 return $services->getNameTableStoreFactory()->getChangeTagDef();
196 },
197
198 'CommentStore' => function ( MediaWikiServices $services ) : CommentStore {
200 $services->getContentLanguage(),
202 );
203 },
204
205 'ConfigFactory' => function ( MediaWikiServices $services ) : ConfigFactory {
206 // Use the bootstrap config to initialize the ConfigFactory.
207 $registry = $services->getBootstrapConfig()->get( 'ConfigRegistry' );
208 $factory = new ConfigFactory();
209
210 foreach ( $registry as $name => $callback ) {
211 $factory->register( $name, $callback );
212 }
213 return $factory;
214 },
215
216 'ConfigRepository' => function ( MediaWikiServices $services ) : ConfigRepository {
217 return new ConfigRepository( $services->getConfigFactory() );
218 },
219
220 'ConfiguredReadOnlyMode' => function ( MediaWikiServices $services ) : ConfiguredReadOnlyMode {
221 $config = $services->getMainConfig();
222 return new ConfiguredReadOnlyMode(
223 $config->get( 'ReadOnly' ),
224 $config->get( 'ReadOnlyFile' )
225 );
226 },
227
228 'ContentHandlerFactory' => function ( MediaWikiServices $services ) : IContentHandlerFactory {
229 $contentHandlerConfig = $services->getMainConfig()->get( 'ContentHandlers' );
230
231 return new ContentHandlerFactory(
232 $contentHandlerConfig,
233 $services->getObjectFactory(),
234 $services->getHookContainer(),
235 LoggerFactory::getInstance( 'ContentHandler' )
236 );
237 },
238
239 'ContentLanguage' => function ( MediaWikiServices $services ) : Language {
240 return $services->getLanguageFactory()->getLanguage(
241 $services->getMainConfig()->get( 'LanguageCode' ) );
242 },
243
244 'ContentModelChangeFactory' => function ( MediaWikiServices $services ) : ContentModelChangeFactory {
245 return $services->getService( '_PageCommandFactory' );
246 },
247
248 'ContentModelStore' => function ( MediaWikiServices $services ) : NameTableStore {
249 return $services->getNameTableStoreFactory()->getContentModels();
250 },
251
252 'ContributionsLookup' => function ( MediaWikiServices $services ) : ContributionsLookup {
253 return new ContributionsLookup( $services->getRevisionStore() );
254 },
255
256 'CryptHKDF' => function ( MediaWikiServices $services ) : CryptHKDF {
257 $config = $services->getMainConfig();
258
259 $secret = $config->get( 'HKDFSecret' ) ?: $config->get( 'SecretKey' );
260 if ( !$secret ) {
261 throw new RuntimeException( "Cannot use MWCryptHKDF without a secret." );
262 }
263
264 // In HKDF, the context can be known to the attacker, but this will
265 // keep simultaneous runs from producing the same output.
266 $context = [ microtime(), getmypid(), gethostname() ];
267
268 // Setup salt cache. Use APC, or fallback to the main cache if it isn't setup
269 $cache = $services->getLocalServerObjectCache();
270 if ( $cache instanceof EmptyBagOStuff ) {
272 }
273
274 return new CryptHKDF( $secret, $config->get( 'HKDFAlgorithm' ), $cache, $context );
275 },
276
277 'DateFormatterFactory' => function () : DateFormatterFactory {
279 },
280
281 'DBLoadBalancer' => function ( MediaWikiServices $services ) : Wikimedia\Rdbms\ILoadBalancer {
282 // just return the default LB from the DBLoadBalancerFactory service
283 return $services->getDBLoadBalancerFactory()->getMainLB();
284 },
285
286 'DBLoadBalancerFactory' =>
287 function ( MediaWikiServices $services ) : Wikimedia\Rdbms\LBFactory {
288 $mainConfig = $services->getMainConfig();
289
290 try {
291 $stash = $services->getMainObjectStash();
292 } catch ( RecursiveServiceDependencyException $e ) {
293 $stash = new EmptyBagOStuff(); // T141804: handle cases like CACHE_DB
294 }
295
296 if ( $stash instanceof EmptyBagOStuff ) {
297 // Use process cache if the main stash is disabled or there was recursion
298 $stash = new HashBagOStuff( [ 'maxKeys' => 100 ] );
299 }
300
301 try {
302 $wanCache = $services->getMainWANObjectCache();
303 } catch ( RecursiveServiceDependencyException $e ) {
304 $wanCache = WANObjectCache::newEmpty(); // T141804: handle cases like CACHE_DB
305 }
306
308 $mainConfig->get( 'LBFactoryConf' ),
309 new ServiceOptions( MWLBFactory::APPLY_DEFAULT_CONFIG_OPTIONS, $mainConfig ),
310 $services->getConfiguredReadOnlyMode(),
311 $services->getLocalServerObjectCache(),
312 $stash,
313 $wanCache
314 );
315
316 $class = MWLBFactory::getLBFactoryClass( $lbConf );
317 $instance = new $class( $lbConf );
318
320
321 return $instance;
322 },
323
324 'Emailer' => function ( MediaWikiServices $services ) : IEmailer {
325 return new Emailer();
326 },
327
328 'EventRelayerGroup' => function ( MediaWikiServices $services ) : EventRelayerGroup {
329 return new EventRelayerGroup( $services->getMainConfig()->get( 'EventRelayerConfig' ) );
330 },
331
332 'ExternalStoreAccess' => function ( MediaWikiServices $services ) : ExternalStoreAccess {
334 $services->getExternalStoreFactory(),
335 LoggerFactory::getInstance( 'ExternalStore' )
336 );
337 },
338
339 'ExternalStoreFactory' => function ( MediaWikiServices $services ) : ExternalStoreFactory {
340 $config = $services->getMainConfig();
341 $writeStores = $config->get( 'DefaultExternalStore' );
342
343 return new ExternalStoreFactory(
344 $config->get( 'ExternalStores' ),
345 ( $writeStores !== false ) ? (array)$writeStores : [],
346 $services->getDBLoadBalancer()->getLocalDomainID(),
347 LoggerFactory::getInstance( 'ExternalStore' )
348 );
349 },
350
351 'FileBackendGroup' => function ( MediaWikiServices $services ) : FileBackendGroup {
352 $mainConfig = $services->getMainConfig();
353
355 $fallbackWikiId = WikiMap::getWikiIdFromDbDomain( $ld );
356 // If the local wiki ID and local domain ID do not match, probably due to a non-default
357 // schema, issue a warning. A non-default schema indicates that it might be used to
358 // disambiguate different wikis.
359 $legacyDomainId = strlen( $ld->getTablePrefix() )
360 ? "{$ld->getDatabase()}-{$ld->getTablePrefix()}"
361 : $ld->getDatabase();
362 if ( $ld->getSchema() !== null && $legacyDomainId !== $fallbackWikiId ) {
363 wfWarn(
364 "Legacy default 'domainId' is '$legacyDomainId' but wiki ID is '$fallbackWikiId'."
365 );
366 }
367
368 $cache = $services->getLocalServerObjectCache();
369 if ( $cache instanceof EmptyBagOStuff ) {
370 $cache = new HashBagOStuff;
371 }
372
373 return new FileBackendGroup(
374 new ServiceOptions( FileBackendGroup::CONSTRUCTOR_OPTIONS, $mainConfig,
375 [ 'fallbackWikiId' => $fallbackWikiId ] ),
376 $services->getConfiguredReadOnlyMode(),
377 $cache,
378 $services->getMainWANObjectCache(),
379 $services->getMimeAnalyzer(),
380 $services->getLockManagerGroupFactory(),
381 $services->getTempFSFileFactory(),
382 $services->getObjectFactory()
383 );
384 },
385
386 'GenderCache' => function ( MediaWikiServices $services ) : GenderCache {
387 $nsInfo = $services->getNamespaceInfo();
388 // Database layer may be disabled, so processing without database connection
389 $dbLoadBalancer = $services->isServiceDisabled( 'DBLoadBalancer' )
390 ? null
391 : $services->getDBLoadBalancer();
392 return new GenderCache( $nsInfo, $dbLoadBalancer, $services->get( '_DefaultOptionsLookup' ) );
393 },
394
395 'GlobalIdGenerator' => function ( MediaWikiServices $services ) : GlobalIdGenerator {
396 $mainConfig = $services->getMainConfig();
397
398 return new GlobalIdGenerator(
399 $mainConfig->get( 'TmpDirectory' ),
400 // Ignore APC-like caches in CLI mode since there is no meaningful persistence.
401 // This avoids having counters restart with each script run. The ID generator
402 // will fallback to using the disk in those cases.
403 $mainConfig->get( 'CommandLineMode' )
404 ? new EmptyBagOStuff()
405 : $services->getLocalServerObjectCache(),
406 function ( $command ) {
407 return wfShellExec( $command );
408 }
409 );
410 },
411
412 'HookContainer' => function ( MediaWikiServices $services ) : HookContainer {
413 $extRegistry = ExtensionRegistry::getInstance();
414 $extDeprecatedHooks = $extRegistry->getAttribute( 'DeprecatedHooks' );
415 $deprecatedHooks = new DeprecatedHooks( $extDeprecatedHooks );
416 $hookRegistry = new GlobalHookRegistry( $extRegistry, $deprecatedHooks );
417 return new HookContainer(
418 $hookRegistry,
419 $services->getObjectFactory()
420 );
421 },
422
423 'HtmlCacheUpdater' => function ( MediaWikiServices $services ) : HtmlCacheUpdater {
424 $config = $services->getMainConfig();
425
426 return new HtmlCacheUpdater(
427 $services->getHookContainer(),
428 $config->get( 'CdnReboundPurgeDelay' ),
429 $config->get( 'UseFileCache' ),
430 $config->get( 'CdnMaxAge' )
431 );
432 },
433
434 'HttpRequestFactory' =>
435 function ( MediaWikiServices $services ) : HttpRequestFactory {
437 new ServiceOptions(
438 HttpRequestFactory::CONSTRUCTOR_OPTIONS,
439 $services->getMainConfig()
440 ),
441 LoggerFactory::getInstance( 'http' )
442 );
443 },
444
445 'InterwikiLookup' => function ( MediaWikiServices $services ) : InterwikiLookup {
446 $config = $services->getMainConfig();
447 return new ClassicInterwikiLookup(
448 $services->getContentLanguage(),
449 $services->getMainWANObjectCache(),
450 $services->getHookContainer(),
451 $config->get( 'InterwikiExpiry' ),
452 $config->get( 'InterwikiCache' ),
453 $config->get( 'InterwikiScopes' ),
454 $config->get( 'InterwikiFallbackSite' )
455 );
456 },
457
458 'JobRunner' => function ( MediaWikiServices $services ) : JobRunner {
459 return new JobRunner(
460 new ServiceOptions( JobRunner::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
461 $services->getDBLoadBalancerFactory(),
462 JobQueueGroup::singleton(),
463 $services->getReadOnlyMode(),
464 $services->getLinkCache(),
465 $services->getStatsdDataFactory(),
466 LoggerFactory::getInstance( 'runJobs' )
467 );
468 },
469
470 'LanguageConverterFactory' => function ( MediaWikiServices $services ) : LanguageConverterFactory {
471 $usePigLatinVariant = $services->getMainConfig()->get( 'UsePigLatinVariant' );
472 return new LanguageConverterFactory( $usePigLatinVariant, function () use ( $services ) {
473 return $services->getContentLanguage();
474 } );
475 },
476
477 'LanguageFactory' => function ( MediaWikiServices $services ) : LanguageFactory {
479 new ServiceOptions( LanguageFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
480 $services->getLocalisationCache(),
481 $services->getLanguageNameUtils(),
482 $services->getLanguageFallback(),
483 $services->getLanguageConverterFactory(),
484 $services->getHookContainer()
485 );
486 },
487
488 'LanguageFallback' => function ( MediaWikiServices $services ) : LanguageFallback {
490 $services->getMainConfig()->get( 'LanguageCode' ),
491 $services->getLocalisationCache(),
492 $services->getLanguageNameUtils()
493 );
494 },
495
496 'LanguageNameUtils' => function ( MediaWikiServices $services ) : LanguageNameUtils {
498 new ServiceOptions(
499 LanguageNameUtils::CONSTRUCTOR_OPTIONS,
500 $services->getMainConfig()
501 ),
502 $services->getHookContainer()
503 );
504 },
505
506 'LinkBatchFactory' => function ( MediaWikiServices $services ) : LinkBatchFactory {
508 $services->getLinkCache(),
509 $services->getTitleFormatter(),
510 $services->getContentLanguage(),
511 $services->getGenderCache(),
512 $services->getDBLoadBalancer()
513 );
514 },
515
516 'LinkCache' => function ( MediaWikiServices $services ) : LinkCache {
517 return new LinkCache(
518 $services->getTitleFormatter(),
519 $services->getMainWANObjectCache(),
520 $services->getNamespaceInfo()
521 );
522 },
523
524 'LinkRenderer' => function ( MediaWikiServices $services ) : LinkRenderer {
525 if ( defined( 'MW_NO_SESSION' ) ) {
526 return $services->getLinkRendererFactory()->create();
527 } else {
528 // Normally information from the current request would not be passed in here;
529 // this is an exception. (See also the class documentation.)
530 return $services->getLinkRendererFactory()->createForUser(
531 RequestContext::getMain()->getUser()
532 );
533 }
534 },
535
536 'LinkRendererFactory' => function ( MediaWikiServices $services ) : LinkRendererFactory {
538 $services->getTitleFormatter(),
539 $services->getLinkCache(),
540 $services->getNamespaceInfo(),
541 $services->getSpecialPageFactory(),
542 $services->getHookContainer()
543 );
544 },
545
546 'LocalisationCache' => function ( MediaWikiServices $services ) : LocalisationCache {
547 $conf = $services->getMainConfig()->get( 'LocalisationCacheConf' );
548
549 $logger = LoggerFactory::getInstance( 'localisation' );
550
552 $conf, $services->getMainConfig()->get( 'CacheDirectory' ) );
553 $logger->debug( 'LocalisationCache using store ' . get_class( $store ) );
554
555 return new $conf['class'](
556 new ServiceOptions(
557 LocalisationCache::CONSTRUCTOR_OPTIONS,
558 // Two of the options are stored in $wgLocalisationCacheConf
559 $conf,
560 // In case someone set that config variable and didn't reset all keys, set defaults.
561 [
562 'forceRecache' => false,
563 'manualRecache' => false,
564 ],
565 // Some other options come from config itself
566 $services->getMainConfig()
567 ),
568 $store,
569 $logger,
570 [ function () use ( $services ) {
571 // NOTE: Make sure we use the same cache object that is assigned in the
572 // constructor of the MessageBlobStore class used by ResourceLoader.
573 // T231866: Avoid circular dependency via ResourceLoader.
574 MessageBlobStore::clearGlobalCacheEntry( $services->getMainWANObjectCache() );
575 } ],
576 $services->getLanguageNameUtils(),
577 $services->getHookContainer()
578 );
579 },
580
581 'LocalServerObjectCache' => function ( MediaWikiServices $services ) : BagOStuff {
582 return ObjectCache::makeLocalServerCache();
583 },
584
585 'LockManagerGroupFactory' => function ( MediaWikiServices $services ) : LockManagerGroupFactory {
587 WikiMap::getCurrentWikiDbDomain()->getId(),
588 $services->getMainConfig()->get( 'LockManagers' ),
589 $services->getDBLoadBalancerFactory()
590 );
591 },
592
593 'MagicWordFactory' => function ( MediaWikiServices $services ) : MagicWordFactory {
595 $services->getContentLanguage(),
596 $services->getHookContainer()
597 );
598 },
599
600 'MainConfig' => function ( MediaWikiServices $services ) : Config {
601 // Use the 'main' config from the ConfigFactory service.
602 return $services->getConfigFactory()->makeConfig( 'main' );
603 },
604
605 'MainObjectStash' => function ( MediaWikiServices $services ) : BagOStuff {
606 $mainConfig = $services->getMainConfig();
607
608 $id = $mainConfig->get( 'MainStash' );
609 if ( !isset( $mainConfig->get( 'ObjectCaches' )[$id] ) ) {
610 throw new UnexpectedValueException(
611 "Cache type \"$id\" is not present in \$wgObjectCaches." );
612 }
613
614 $params = $mainConfig->get( 'ObjectCaches' )[$id];
615
616 $store = ObjectCache::newFromParams( $params, $mainConfig );
617 $store->getLogger()->debug( 'MainObjectStash using store {class}', [
618 'class' => get_class( $store )
619 ] );
620
621 return $store;
622 },
623
624 'MainWANObjectCache' => function ( MediaWikiServices $services ) : WANObjectCache {
625 $mainConfig = $services->getMainConfig();
626
627 $wanId = $mainConfig->get( 'MainWANCache' );
628 $wanParams = $mainConfig->get( 'WANObjectCaches' )[$wanId] ?? null;
629 if ( !$wanParams ) {
630 throw new UnexpectedValueException(
631 "wgWANObjectCaches must have \"$wanId\" set (via wgMainWANCache)"
632 );
633 }
634
635 $cacheId = $wanParams['cacheId'];
636 $wanClass = $wanParams['class'];
637 unset( $wanParams['cacheId'] );
638 unset( $wanParams['class'] );
639
640 $storeParams = $mainConfig->get( 'ObjectCaches' )[$cacheId] ?? null;
641 if ( !$storeParams ) {
642 throw new UnexpectedValueException(
643 "wgObjectCaches must have \"$cacheId\" set (via wgWANObjectCaches)"
644 );
645 }
646 $store = ObjectCache::newFromParams( $storeParams, $mainConfig );
647 $logger = $store->getLogger();
648 $logger->debug( 'MainWANObjectCache using store {class}', [
649 'class' => get_class( $store )
650 ] );
651
652 $wanParams['cache'] = $store;
653 $wanParams['logger'] = $logger;
654 $wanParams['secret'] = $wanParams['secret'] ?? $mainConfig->get( 'SecretKey' );
655 if ( !$mainConfig->get( 'CommandLineMode' ) ) {
656 // Send the statsd data post-send on HTTP requests; avoid in CLI mode (T181385)
657 $wanParams['stats'] = $services->getStatsdDataFactory();
658 // Let pre-emptive refreshes happen post-send on HTTP requests
659 $wanParams['asyncHandler'] = [ DeferredUpdates::class, 'addCallableUpdate' ];
660 }
661
662 $instance = new $wanClass( $wanParams );
663
664 '@phan-var WANObjectCache $instance';
665 return $instance;
666 },
667
668 'MediaHandlerFactory' => function ( MediaWikiServices $services ) : MediaHandlerFactory {
670 $services->getMainConfig()->get( 'MediaHandlers' )
671 );
672 },
673
674 'MergeHistoryFactory' => function ( MediaWikiServices $services ) : MergeHistoryFactory {
675 return $services->getService( '_PageCommandFactory' );
676 },
677
678 'MessageCache' => function ( MediaWikiServices $services ) : MessageCache {
679 $mainConfig = $services->getMainConfig();
680 $clusterCache = ObjectCache::getInstance( $mainConfig->get( 'MessageCacheType' ) );
681 $srvCache = $mainConfig->get( 'UseLocalMessageCache' )
682 ? $services->getLocalServerObjectCache()
683 : new EmptyBagOStuff();
684
685 $logger = LoggerFactory::getInstance( 'MessageCache' );
686 $logger->debug( 'MessageCache using store {class}', [
687 'class' => get_class( $clusterCache )
688 ] );
689
690 return new MessageCache(
691 $services->getMainWANObjectCache(),
692 $clusterCache,
693 $srvCache,
694 $services->getContentLanguage(),
695 $services->getLanguageConverterFactory()->getLanguageConverter(),
696 $logger,
697 [ 'useDB' => $mainConfig->get( 'UseDatabaseMessages' ) ],
698 $services->getLanguageFactory(),
699 $services->getLocalisationCache(),
700 $services->getLanguageNameUtils(),
701 $services->getLanguageFallback(),
702 $services->getHookContainer()
703 );
704 },
705
706 'MessageFormatterFactory' => function () : IMessageFormatterFactory {
708 },
709
710 'MimeAnalyzer' => function ( MediaWikiServices $services ) : MimeAnalyzer {
711 $logger = LoggerFactory::getInstance( 'Mime' );
712 $mainConfig = $services->getMainConfig();
713 $hookRunner = new HookRunner( $services->getHookContainer() );
714 $params = [
715 'typeFile' => $mainConfig->get( 'MimeTypeFile' ),
716 'infoFile' => $mainConfig->get( 'MimeInfoFile' ),
717 'xmlTypes' => $mainConfig->get( 'XMLMimeTypes' ),
718 'guessCallback' =>
719 function ( $mimeAnalyzer, &$head, &$tail, $file, &$mime )
720 use ( $logger, $hookRunner ) {
721 // Also test DjVu
722 $deja = new DjVuImage( $file );
723 if ( $deja->isValid() ) {
724 $logger->info( "Detected $file as image/vnd.djvu\n" );
725 $mime = 'image/vnd.djvu';
726
727 return;
728 }
729 // Some strings by reference for performance - assuming well-behaved hooks
730 $hookRunner->onMimeMagicGuessFromContent(
731 $mimeAnalyzer, $head, $tail, $file, $mime );
732 },
733 'extCallback' => function ( $mimeAnalyzer, $ext, &$mime ) use ( $hookRunner ) {
734 // Media handling extensions can improve the MIME detected
735 $hookRunner->onMimeMagicImproveFromExtension( $mimeAnalyzer, $ext, $mime );
736 },
737 'initCallback' => function ( $mimeAnalyzer ) use ( $hookRunner ) {
738 // Allow media handling extensions adding MIME-types and MIME-info
739 $hookRunner->onMimeMagicInit( $mimeAnalyzer );
740 },
741 'logger' => $logger
742 ];
743
744 if ( $params['infoFile'] === 'includes/mime.info' ) {
745 $params['infoFile'] = MimeAnalyzer::USE_INTERNAL;
746 }
747
748 if ( $params['typeFile'] === 'includes/mime.types' ) {
749 $params['typeFile'] = MimeAnalyzer::USE_INTERNAL;
750 }
751
752 $detectorCmd = $mainConfig->get( 'MimeDetectorCommand' );
753 if ( $detectorCmd ) {
754 $factory = $services->getShellCommandFactory();
755 $params['detectCallback'] = function ( $file ) use ( $detectorCmd, $factory ) {
756 $result = $factory->create()
757 // $wgMimeDetectorCommand can contain commands with parameters
758 ->unsafeParams( $detectorCmd )
759 ->params( $file )
760 ->execute();
761 return $result->getStdout();
762 };
763 }
764
765 return new MimeAnalyzer( $params );
766 },
767
768 'MovePageFactory' => function ( MediaWikiServices $services ) : MovePageFactory {
769 return $services->getService( '_PageCommandFactory' );
770 },
771
772 'NamespaceInfo' => function ( MediaWikiServices $services ) : NamespaceInfo {
774 new ServiceOptions( NamespaceInfo::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
775 $services->getHookContainer()
776 );
777 },
778
779 'NameTableStoreFactory' => function ( MediaWikiServices $services ) : NameTableStoreFactory {
781 $services->getDBLoadBalancerFactory(),
782 $services->getMainWANObjectCache(),
783 LoggerFactory::getInstance( 'NameTableSqlStore' )
784 );
785 },
786
787 'ObjectFactory' => function ( MediaWikiServices $services ) : ObjectFactory {
788 return new ObjectFactory( $services );
789 },
790
791 'OldRevisionImporter' => function ( MediaWikiServices $services ) : OldRevisionImporter {
793 true,
794 LoggerFactory::getInstance( 'OldRevisionImporter' ),
795 $services->getDBLoadBalancer(),
796 $services->getRevisionStore(),
797 $services->getSlotRoleRegistry()
798 );
799 },
800
801 'PageEditStash' => function ( MediaWikiServices $services ) : PageEditStash {
802 $config = $services->getMainConfig();
803
804 return new PageEditStash(
805 ObjectCache::getLocalClusterInstance(),
806 $services->getDBLoadBalancer(),
807 LoggerFactory::getInstance( 'StashEdit' ),
808 $services->getStatsdDataFactory(),
809 $services->getHookContainer(),
810 defined( 'MEDIAWIKI_JOB_RUNNER' ) || $config->get( 'CommandLineMode' )
811 ? PageEditStash::INITIATOR_JOB_OR_CLI
812 : PageEditStash::INITIATOR_USER
813 );
814 },
815
816 'Parser' => function ( MediaWikiServices $services ) : Parser {
817 return $services->getParserFactory()->create();
818 },
819
820 'ParserCache' => function ( MediaWikiServices $services ) : ParserCache {
821 $config = $services->getMainConfig();
822 $cache = ObjectCache::getInstance( $config->get( 'ParserCacheType' ) );
823 wfDebugLog( 'caches', 'parser: ' . get_class( $cache ) );
824
825 return new ParserCache(
826 $cache,
827 $config->get( 'CacheEpoch' ),
828 $services->getHookContainer(),
829 $services->getStatsdDataFactory()
830 );
831 },
832
833 'ParserFactory' => function ( MediaWikiServices $services ) : ParserFactory {
834 $options = new ServiceOptions( Parser::CONSTRUCTOR_OPTIONS,
835 // 'class'
836 // Note that this value is ignored by ParserFactory and is always
837 // Parser::class for legacy reasons; we'll introduce a new
838 // mechanism for selecting an alternate parser in the future
839 // (T236809)
840 $services->getMainConfig()->get( 'ParserConf' ),
841 // Make sure to have defaults in case someone overrode ParserConf with something silly
842 [ 'class' => Parser::class ],
843 // Plus a buch of actual config options
844 $services->getMainConfig()
845 );
846
847 return new ParserFactory(
848 $options,
849 $services->getMagicWordFactory(),
850 $services->getContentLanguage(),
852 $services->getSpecialPageFactory(),
853 $services->getLinkRendererFactory(),
854 $services->getNamespaceInfo(),
855 LoggerFactory::getInstance( 'Parser' ),
856 $services->getBadFileLookup(),
857 $services->getLanguageConverterFactory(),
858 $services->getHookContainer()
859 );
860 },
861
862 'PasswordFactory' => function ( MediaWikiServices $services ) : PasswordFactory {
863 $config = $services->getMainConfig();
864 return new PasswordFactory(
865 $config->get( 'PasswordConfig' ),
866 $config->get( 'PasswordDefault' )
867 );
868 },
869
870 'PasswordReset' => function ( MediaWikiServices $services ) : PasswordReset {
871 $options = new ServiceOptions( PasswordReset::CONSTRUCTOR_OPTIONS, $services->getMainConfig() );
872 return new PasswordReset(
873 $options,
874 $services->getAuthManager(),
875 $services->getPermissionManager(),
876 $services->getDBLoadBalancer(),
877 LoggerFactory::getInstance( 'authentication' ),
878 $services->getHookContainer()
879 );
880 },
881
882 'PerDbNameStatsdDataFactory' =>
883 function ( MediaWikiServices $services ) : StatsdDataFactoryInterface {
884 $config = $services->getMainConfig();
885 $wiki = $config->get( 'DBname' );
887 $services->getStatsdDataFactory(),
888 $wiki
889 );
890 },
891
892 'PermissionManager' => function ( MediaWikiServices $services ) : PermissionManager {
894 new ServiceOptions(
895 PermissionManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
896 ),
897 $services->getSpecialPageFactory(),
898 $services->getRevisionLookup(),
899 $services->getNamespaceInfo(),
900 $services->getBlockErrorFormatter(),
901 $services->getHookContainer()
902 );
903 },
904
905 'PreferencesFactory' => function ( MediaWikiServices $services ) : PreferencesFactory {
906 $factory = new DefaultPreferencesFactory(
907 new ServiceOptions(
908 DefaultPreferencesFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
909 $services->getContentLanguage(),
910 $services->getAuthManager(),
911 $services->getLinkRendererFactory()->create(),
912 $services->getNamespaceInfo(),
913 $services->getPermissionManager(),
914 $services->getLanguageConverterFactory()->getLanguageConverter(),
915 $services->getLanguageNameUtils(),
916 $services->getHookContainer()
917 );
918 $factory->setLogger( LoggerFactory::getInstance( 'preferences' ) );
919
920 return $factory;
921 },
922
923 'ProxyLookup' => function ( MediaWikiServices $services ) : ProxyLookup {
924 $mainConfig = $services->getMainConfig();
925 return new ProxyLookup(
926 $mainConfig->get( 'CdnServers' ),
927 $mainConfig->get( 'CdnServersNoPurge' )
928 );
929 },
930
931 'ReadOnlyMode' => function ( MediaWikiServices $services ) : ReadOnlyMode {
933 $services->getConfiguredReadOnlyMode(),
934 $services->getDBLoadBalancer()
935 );
936 },
937
938 'RepoGroup' => function ( MediaWikiServices $services ) : RepoGroup {
939 $config = $services->getMainConfig();
940 return new RepoGroup(
941 $config->get( 'LocalFileRepo' ),
942 $config->get( 'ForeignFileRepos' ),
943 $services->getMainWANObjectCache()
944 );
945 },
946
947 'ResourceLoader' => function ( MediaWikiServices $services ) : ResourceLoader {
948 // @todo This should not take a Config object, but it's not so easy to remove because it
949 // exposes it in a getter, which is actually used.
950 global $IP;
951 $config = $services->getMainConfig();
952
953 $rl = new ResourceLoader(
954 $config,
955 LoggerFactory::getInstance( 'resourceloader' ),
956 $config->get( 'ResourceLoaderUseObjectCacheForDeps' )
957 ? new KeyValueDependencyStore( $services->getMainObjectStash() )
958 : new SqlModuleDependencyStore( $services->getDBLoadBalancer() )
959 );
960
961 $extRegistry = ExtensionRegistry::getInstance();
962 // Attribute has precedence over config
963 $modules = $extRegistry->getAttribute( 'ResourceModules' )
964 + $config->get( 'ResourceModules' );
965 $moduleSkinStyles = $extRegistry->getAttribute( 'ResourceModuleSkinStyles' )
966 + $config->get( 'ResourceModuleSkinStyles' );
967
968 $rl->setModuleSkinStyles( $moduleSkinStyles );
969 $rl->addSource( $config->get( 'ResourceLoaderSources' ) );
970
971 // Core modules, then extension/skin modules
972 $rl->register( include "$IP/resources/Resources.php" );
973 $rl->register( $modules );
974 $hookRunner = new \MediaWiki\ResourceLoader\HookRunner( $services->getHookContainer() );
975 $hookRunner->onResourceLoaderRegisterModules( $rl );
976
977 $msgPosterAttrib = $extRegistry->getAttribute( 'MessagePosterModule' );
978 $rl->register( 'mediawiki.messagePoster', [
979 'localBasePath' => $IP,
980 'debugRaw' => false,
981 'scripts' => array_merge(
982 [
983 "resources/src/mediawiki.messagePoster/factory.js",
984 "resources/src/mediawiki.messagePoster/MessagePoster.js",
985 "resources/src/mediawiki.messagePoster/WikitextMessagePoster.js",
986 ],
987 $msgPosterAttrib['scripts'] ?? []
988 ),
989 'dependencies' => array_merge(
990 [
991 'oojs',
992 'mediawiki.api',
993 'mediawiki.ForeignApi',
994 ],
995 $msgPosterAttrib['dependencies'] ?? []
996 ),
997 'targets' => [ 'desktop', 'mobile' ],
998 ] );
999
1000 if ( $config->get( 'EnableJavaScriptTest' ) === true ) {
1001 $rl->registerTestModules();
1002 }
1003
1004 return $rl;
1005 },
1006
1007 'RevisionFactory' => function ( MediaWikiServices $services ) : RevisionFactory {
1008 return $services->getRevisionStore();
1009 },
1010
1011 'RevisionLookup' => function ( MediaWikiServices $services ) : RevisionLookup {
1012 return $services->getRevisionStore();
1013 },
1014
1015 'RevisionRenderer' => function ( MediaWikiServices $services ) : RevisionRenderer {
1016 $renderer = new RevisionRenderer(
1017 $services->getDBLoadBalancer(),
1018 $services->getSlotRoleRegistry()
1019 );
1020
1021 $renderer->setLogger( LoggerFactory::getInstance( 'SaveParse' ) );
1022 return $renderer;
1023 },
1024
1025 'RevisionStore' => function ( MediaWikiServices $services ) : RevisionStore {
1026 return $services->getRevisionStoreFactory()->getRevisionStore();
1027 },
1028
1029 'RevisionStoreFactory' => function ( MediaWikiServices $services ) : RevisionStoreFactory {
1030 $config = $services->getMainConfig();
1031
1032 if ( $config->has( 'MultiContentRevisionSchemaMigrationStage' ) ) {
1033 if ( $config->get( 'MultiContentRevisionSchemaMigrationStage' ) !== SCHEMA_COMPAT_NEW ) {
1034 throw new UnexpectedValueException(
1035 'The MultiContentRevisionSchemaMigrationStage setting is no longer supported!'
1036 );
1037 }
1038 }
1039
1040 $store = new RevisionStoreFactory(
1041 $services->getDBLoadBalancerFactory(),
1042 $services->getBlobStoreFactory(),
1043 $services->getNameTableStoreFactory(),
1044 $services->getSlotRoleRegistry(),
1045 $services->getMainWANObjectCache(),
1046 $services->getCommentStore(),
1047 $services->getActorMigration(),
1048 LoggerFactory::getInstance( 'RevisionStore' ),
1049 $services->getContentHandlerFactory(),
1050 $services->getHookContainer()
1051 );
1052
1053 return $store;
1054 },
1055
1056 'SearchEngineConfig' => function ( MediaWikiServices $services ) : SearchEngineConfig {
1057 // @todo This should not take a Config object, but it's not so easy to remove because it
1058 // exposes it in a getter, which is actually used.
1060 $services->getMainConfig(),
1061 $services->getContentLanguage(),
1062 $services->getHookContainer(),
1063 ExtensionRegistry::getInstance()->getAttribute( 'SearchMappings' )
1064 );
1065 },
1066
1067 'SearchEngineFactory' => function ( MediaWikiServices $services ) : SearchEngineFactory {
1069 $services->getSearchEngineConfig(),
1070 $services->getHookContainer()
1071 );
1072 },
1073
1074 'ShellCommandFactory' => function ( MediaWikiServices $services ) : CommandFactory {
1075 $config = $services->getMainConfig();
1076
1077 $limits = [
1078 'time' => $config->get( 'MaxShellTime' ),
1079 'walltime' => $config->get( 'MaxShellWallClockTime' ),
1080 'memory' => $config->get( 'MaxShellMemory' ),
1081 'filesize' => $config->get( 'MaxShellFileSize' ),
1082 ];
1083 $cgroup = $config->get( 'ShellCgroup' );
1084 $restrictionMethod = $config->get( 'ShellRestrictionMethod' );
1085
1086 $factory = new CommandFactory( $limits, $cgroup, $restrictionMethod );
1087 $factory->setLogger( LoggerFactory::getInstance( 'exec' ) );
1088 $factory->logStderr();
1089
1090 return $factory;
1091 },
1092
1093 'SiteLookup' => function ( MediaWikiServices $services ) : SiteLookup {
1094 // Use SiteStore as the SiteLookup as well. This was originally separated
1095 // to allow for a cacheable read-only interface, but this was never used.
1096 // SiteStore has caching (see below).
1097 return $services->getSiteStore();
1098 },
1099
1100 'SiteStore' => function ( MediaWikiServices $services ) : SiteStore {
1101 $rawSiteStore = new DBSiteStore( $services->getDBLoadBalancer() );
1102
1103 $cache = $services->getLocalServerObjectCache();
1104 if ( $cache instanceof EmptyBagOStuff ) {
1106 }
1107
1108 return new CachingSiteStore( $rawSiteStore, $cache );
1109 },
1110
1112 'SkinFactory' => function ( MediaWikiServices $services ) : SkinFactory {
1113 $factory = new SkinFactory( $services->getObjectFactory() );
1114
1115 $names = $services->getMainConfig()->get( 'ValidSkinNames' );
1116
1117 foreach ( $names as $name => $skin ) {
1118 if ( is_array( $skin ) ) {
1119 $spec = $skin;
1120 $displayName = $skin['displayname'] ?? $name;
1121 } else {
1122 $displayName = $skin;
1123 $spec = [
1124 'class' => "Skin$skin"
1125 ];
1126 }
1127 $factory->register( $name, $displayName, $spec );
1128 }
1129
1130 // Register a hidden "fallback" skin
1131 $factory->register( 'fallback', 'Fallback', [
1132 'class' => SkinFallback::class,
1133 'args' => [
1134 [
1135 'styles' => [ 'mediawiki.skinning.interface' ],
1136 'templateDirectory' => __DIR__ . '/skins/templates/fallback',
1137 ]
1138 ]
1139 ] );
1140 // Register a hidden skin for api output
1141 $factory->register( 'apioutput', 'ApiOutput', [
1142 'class' => SkinApi::class,
1143 'args' => [
1144 [
1145 'styles' => [ 'mediawiki.skinning.interface' ],
1146 'templateDirectory' => __DIR__ . '/skins/templates/apioutput',
1147 ]
1148 ]
1149 ] );
1150
1151 return $factory;
1152 },
1153
1154 'SlotRoleRegistry' => function ( MediaWikiServices $services ) : SlotRoleRegistry {
1155 $config = $services->getMainConfig();
1156 $contentHandlerFactory = $services->getContentHandlerFactory();
1157
1158 $registry = new SlotRoleRegistry(
1159 $services->getSlotRoleStore()
1160 );
1161
1162 $registry->defineRole( 'main', function () use ( $config, $contentHandlerFactory ) {
1163 return new MainSlotRoleHandler(
1164 $config->get( 'NamespaceContentModels' ),
1165 $contentHandlerFactory
1166 );
1167 } );
1168
1169 return $registry;
1170 },
1171
1172 'SlotRoleStore' => function ( MediaWikiServices $services ) : NameTableStore {
1173 return $services->getNameTableStoreFactory()->getSlotRoles();
1174 },
1175
1176 'SpamChecker' => function ( MediaWikiServices $services ) : SpamChecker {
1177 return new SpamChecker(
1178 (array)$services->getMainConfig()->get( 'SpamRegex' ),
1179 (array)$services->getMainConfig()->get( 'SummarySpamRegex' )
1180 );
1181 },
1182
1183 'SpecialPageFactory' => function ( MediaWikiServices $services ) : SpecialPageFactory {
1185 new ServiceOptions(
1186 SpecialPageFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1187 $services->getContentLanguage(),
1188 $services->getObjectFactory(),
1189 $services->getHookContainer()
1190 );
1191 },
1192
1193 'StatsdDataFactory' => function ( MediaWikiServices $services ) : IBufferingStatsdDataFactory {
1195 rtrim( $services->getMainConfig()->get( 'StatsdMetricPrefix' ), '.' )
1196 );
1197 },
1198
1199 'TalkPageNotificationManager' => function (
1200 MediaWikiServices $services
1203 new ServiceOptions(
1204 TalkPageNotificationManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
1205 ),
1206 $services->getDBLoadBalancer(),
1207 $services->getReadOnlyMode(),
1208 $services->getRevisionLookup()
1209 );
1210 },
1211
1212 'TempFSFileFactory' => function ( MediaWikiServices $services ) : TempFSFileFactory {
1213 return new TempFSFileFactory( $services->getMainConfig()->get( 'TmpDirectory' ) );
1214 },
1215
1216 'TitleFactory' => function () : TitleFactory {
1217 return new TitleFactory();
1218 },
1219
1220 'TitleFormatter' => function ( MediaWikiServices $services ) : TitleFormatter {
1221 return $services->getService( '_MediaWikiTitleCodec' );
1222 },
1223
1224 'TitleParser' => function ( MediaWikiServices $services ) : TitleParser {
1225 return $services->getService( '_MediaWikiTitleCodec' );
1226 },
1227
1228 'UploadRevisionImporter' => function ( MediaWikiServices $services ) : UploadRevisionImporter {
1230 $services->getMainConfig()->get( 'EnableUploads' ),
1231 LoggerFactory::getInstance( 'UploadRevisionImporter' )
1232 );
1233 },
1234
1235 'UserEditTracker' => function ( MediaWikiServices $services ) : UserEditTracker {
1237 $services->getActorMigration(),
1238 $services->getDBLoadBalancer()
1239 );
1240 },
1241
1242 'UserFactory' => function ( MediaWikiServices $services ) : UserFactory {
1243 return new UserFactory( $services->getUserNameUtils() );
1244 },
1245
1246 'UserGroupManager' => function ( MediaWikiServices $services ) : UserGroupManager {
1247 return $services->getUserGroupManagerFactory()->getUserGroupManager();
1248 },
1249
1250 'UserGroupManagerFactory' => function ( MediaWikiServices $services ) : UserGroupManagerFactory {
1252 new ServiceOptions(
1253 UserGroupManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
1254 ),
1255 $services->getConfiguredReadOnlyMode(),
1256 $services->getDBLoadBalancerFactory(),
1257 $services->getHookContainer(),
1258 $services->getUserEditTracker(),
1259 LoggerFactory::getInstance( 'UserGroupManager' ),
1260 [ function ( UserIdentity $user ) use ( $services ) {
1261 $services->getPermissionManager()->invalidateUsersRightsCache( $user );
1262 User::newFromIdentity( $user )->invalidateCache();
1263 } ]
1264 );
1265 },
1266
1267 'UserNameUtils' => function ( MediaWikiServices $services ) : UserNameUtils {
1268 $messageFormatterFactory = new MessageFormatterFactory( Message::FORMAT_PLAIN );
1269 return new UserNameUtils(
1270 new ServiceOptions(
1271 UserNameUtils::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
1272 ),
1273 $services->getContentLanguage(),
1274 LoggerFactory::getInstance( 'UserNameUtils' ),
1275 $services->getTitleParser(),
1276 $messageFormatterFactory->getTextFormatter(
1277 $services->getContentLanguage()->getCode()
1278 ),
1279 $services->getHookContainer()
1280 );
1281 },
1282
1283 'UserOptionsLookup' => function ( MediaWikiServices $services ) : UserOptionsLookup {
1284 return $services->getUserOptionsManager();
1285 },
1286
1287 'UserOptionsManager' => function ( MediaWikiServices $services ) : UserOptionsManager {
1289 new ServiceOptions( UserOptionsManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1290 $services->get( '_DefaultOptionsLookup' ),
1291 $services->getLanguageConverterFactory(),
1292 $services->getDBLoadBalancer(),
1293 LoggerFactory::getInstance( 'UserOptionsManager' ),
1294 $services->getHookContainer()
1295 );
1296 },
1297
1298 'VirtualRESTServiceClient' =>
1299 function ( MediaWikiServices $services ) : VirtualRESTServiceClient {
1300 $config = $services->getMainConfig()->get( 'VirtualRestConfig' );
1301
1302 $vrsClient = new VirtualRESTServiceClient(
1303 $services->getHttpRequestFactory()->createMultiClient() );
1304 foreach ( $config['paths'] as $prefix => $serviceConfig ) {
1305 $class = $serviceConfig['class'];
1306 // Merge in the global defaults
1307 $constructArg = $serviceConfig['options'] ?? [];
1308 $constructArg += $config['global'];
1309 // Make the VRS service available at the mount point
1310 $vrsClient->mount( $prefix, [ 'class' => $class, 'config' => $constructArg ] );
1311 }
1312
1313 return $vrsClient;
1314 },
1315
1316 'WatchedItemQueryService' =>
1317 function ( MediaWikiServices $services ) : WatchedItemQueryService {
1319 $services->getDBLoadBalancer(),
1320 $services->getCommentStore(),
1321 $services->getActorMigration(),
1322 $services->getWatchedItemStore(),
1323 $services->getPermissionManager(),
1324 $services->getHookContainer(),
1325 $services->getMainConfig()->get( 'WatchlistExpiry' ),
1326 $services->getMainConfig()->get( 'MaxExecutionTimeForExpensiveQueries' )
1327 );
1328 },
1329
1330 'WatchedItemStore' => function ( MediaWikiServices $services ) : WatchedItemStore {
1331 $store = new WatchedItemStore(
1332 new ServiceOptions( WatchedItemStore::CONSTRUCTOR_OPTIONS,
1333 $services->getMainConfig() ),
1334 $services->getDBLoadBalancerFactory(),
1335 JobQueueGroup::singleton(),
1336 $services->getMainObjectStash(),
1337 new HashBagOStuff( [ 'maxKeys' => 100 ] ),
1338 $services->getReadOnlyMode(),
1339 $services->getNamespaceInfo(),
1340 $services->getRevisionLookup(),
1341 $services->getHookContainer()
1342 );
1343 $store->setStatsdDataFactory( $services->getStatsdDataFactory() );
1344
1345 if ( $services->getMainConfig()->get( 'ReadOnlyWatchedItemStore' ) ) {
1346 $store = new NoWriteWatchedItemStore( $store );
1347 }
1348
1349 return $store;
1350 },
1351
1352 'WatchlistNotificationManager' =>
1353 function ( MediaWikiServices $services ) : WatchlistNotificationManager {
1355 new ServiceOptions(
1356 WatchlistNotificationManager::CONSTRUCTOR_OPTIONS,
1357 $services->getMainConfig()
1358 ),
1359 $services->getHookContainer(),
1360 $services->getPermissionManager(),
1361 $services->getReadOnlyMode(),
1362 $services->getRevisionLookup(),
1363 $services->getTalkPageNotificationManager(),
1364 $services->getWatchedItemStore()
1365 );
1366 },
1367
1368 'WikiRevisionOldRevisionImporterNoUpdates' =>
1369 function ( MediaWikiServices $services ) : ImportableOldRevisionImporter {
1371 false,
1372 LoggerFactory::getInstance( 'OldRevisionImporter' ),
1373 $services->getDBLoadBalancer(),
1374 $services->getRevisionStore(),
1375 $services->getSlotRoleRegistry()
1376 );
1377 },
1378
1379 '_DefaultOptionsLookup' => function ( MediaWikiServices $services ) : DefaultOptionsLookup {
1381 new ServiceOptions( DefaultOptionsLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1382 $services->getContentLanguage(),
1383 $services->getHookContainer()
1384 );
1385 },
1386
1387 '_MediaWikiTitleCodec' => function ( MediaWikiServices $services ) : MediaWikiTitleCodec {
1389 $services->getContentLanguage(),
1390 $services->getGenderCache(),
1391 $services->getMainConfig()->get( 'LocalInterwikis' ),
1392 $services->getInterwikiLookup(),
1393 $services->getNamespaceInfo()
1394 );
1395 },
1396
1397 '_PageCommandFactory' => function ( MediaWikiServices $services ) : PageCommandFactory {
1399 new ServiceOptions( PageCommandFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1400 $services->getDBLoadBalancer(),
1401 $services->getNamespaceInfo(),
1402 $services->getWatchedItemStore(),
1403 $services->getPermissionManager(),
1404 $services->getRepoGroup(),
1405 $services->getContentHandlerFactory(),
1406 $services->getRevisionStore(),
1407 $services->getSpamChecker(),
1408 $services->getHookContainer()
1409 );
1410 },
1411
1412 '_SqlBlobStore' => function ( MediaWikiServices $services ) : SqlBlobStore {
1413 return $services->getBlobStoreFactory()->newSqlBlobStore();
1414 },
1415
1417 // NOTE: When adding a service here, don't forget to add a getter function
1418 // in the MediaWikiServices class. The convenience getter should just call
1419 // $this->getService( 'FooBarService' ).
1421
1422];
getPermissionManager()
getUser()
wfWarn( $msg, $callerOffset=1, $level=E_USER_NOTICE)
Send a warning either to the debug log or in a PHP error depending on $wgDevelopmentWarnings.
wfShellExec( $cmd, &$retval=null, $environ=[], $limits=[], $options=[])
Execute a shell command, with time and memory limits mirrored from the PHP configuration if supported...
wfUrlProtocols( $includeProtocolRelative=true)
Returns a regular expression of url protocols.
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
return[ 'ActorMigration'=> function() :ActorMigration { return new ActorMigration(SCHEMA_COMPAT_NEW);}, 'AuthManager'=> function(MediaWikiServices $services) :AuthManager { $authManager=new AuthManager(RequestContext::getMain() ->getRequest(), $services->getMainConfig(), $services->getObjectFactory(), $services->getPermissionManager(), $services->getHookContainer());$authManager->setLogger(LoggerFactory::getInstance( 'authentication'));return $authManager;}, 'BadFileLookup'=> function(MediaWikiServices $services) :BadFileLookup { return new BadFileLookup(function() { return wfMessage( 'bad_image_list') ->inContentLanguage() ->plain();}, $services->getLocalServerObjectCache(), $services->getRepoGroup(), $services->getTitleParser(), $services->getHookContainer());}, 'BlobStore'=> function(MediaWikiServices $services) :BlobStore { return $services->getService( '_SqlBlobStore');}, 'BlobStoreFactory'=> function(MediaWikiServices $services) :BlobStoreFactory { return new BlobStoreFactory($services->getDBLoadBalancerFactory(), $services->getExternalStoreAccess(), $services->getMainWANObjectCache(), new ServiceOptions(BlobStoreFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig()));}, 'BlockErrorFormatter'=> function() :BlockErrorFormatter { return new BlockErrorFormatter();}, 'BlockManager'=> function(MediaWikiServices $services) :BlockManager { return new BlockManager(new ServiceOptions(BlockManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getPermissionManager(), LoggerFactory::getInstance( 'BlockManager'), $services->getHookContainer());}, 'BlockPermissionCheckerFactory'=> function(MediaWikiServices $services) :BlockPermissionCheckerFactory { return new BlockPermissionCheckerFactory($services->getPermissionManager());}, 'BlockRestrictionStore'=> function(MediaWikiServices $services) :BlockRestrictionStore { return new BlockRestrictionStore($services->getDBLoadBalancer());}, 'ChangeTagDefStore'=> function(MediaWikiServices $services) :NameTableStore { return $services->getNameTableStoreFactory() ->getChangeTagDef();}, 'CommentStore'=> function(MediaWikiServices $services) :CommentStore { return new CommentStore($services->getContentLanguage(), MIGRATION_NEW);}, 'ConfigFactory'=> function(MediaWikiServices $services) :ConfigFactory { $registry=$services->getBootstrapConfig() ->get( 'ConfigRegistry');$factory=new ConfigFactory();foreach( $registry as $name=> $callback) { $factory->register( $name, $callback);} return $factory;}, 'ConfigRepository'=> function(MediaWikiServices $services) :ConfigRepository { return new ConfigRepository( $services->getConfigFactory());}, 'ConfiguredReadOnlyMode'=> function(MediaWikiServices $services) :ConfiguredReadOnlyMode { $config=$services->getMainConfig();return new ConfiguredReadOnlyMode($config->get( 'ReadOnly'), $config->get( 'ReadOnlyFile'));}, 'ContentHandlerFactory'=> function(MediaWikiServices $services) :IContentHandlerFactory { $contentHandlerConfig=$services->getMainConfig() ->get( 'ContentHandlers');return new ContentHandlerFactory($contentHandlerConfig, $services->getObjectFactory(), $services->getHookContainer(), LoggerFactory::getInstance( 'ContentHandler'));}, 'ContentLanguage'=> function(MediaWikiServices $services) :Language { return $services->getLanguageFactory() ->getLanguage($services->getMainConfig() ->get( 'LanguageCode'));}, 'ContentModelChangeFactory'=> function(MediaWikiServices $services) :ContentModelChangeFactory { return $services->getService( '_PageCommandFactory');}, 'ContentModelStore'=> function(MediaWikiServices $services) :NameTableStore { return $services->getNameTableStoreFactory() ->getContentModels();}, 'ContributionsLookup'=> function(MediaWikiServices $services) :ContributionsLookup { return new ContributionsLookup( $services->getRevisionStore());}, 'CryptHKDF'=> function(MediaWikiServices $services) :CryptHKDF { $config=$services->getMainConfig();$secret=$config->get( 'HKDFSecret') ?:$config->get( 'SecretKey');if(! $secret) { throw new RuntimeException("Cannot use MWCryptHKDF without a secret.");} $context=[microtime(), getmypid(), gethostname()];$cache=$services->getLocalServerObjectCache();if( $cache instanceof EmptyBagOStuff) { $cache=ObjectCache::getLocalClusterInstance();} return new CryptHKDF( $secret, $config->get( 'HKDFAlgorithm'), $cache, $context);}, 'DateFormatterFactory'=> function() :DateFormatterFactory { return new DateFormatterFactory;}, 'DBLoadBalancer'=> function(MediaWikiServices $services) :Wikimedia\Rdbms\ILoadBalancer { return $services->getDBLoadBalancerFactory() ->getMainLB();}, 'DBLoadBalancerFactory'=> function(MediaWikiServices $services) :Wikimedia\Rdbms\LBFactory { $mainConfig=$services->getMainConfig();try { $stash=$services->getMainObjectStash();} catch(RecursiveServiceDependencyException $e) { $stash=new EmptyBagOStuff();} if( $stash instanceof EmptyBagOStuff) { $stash=new HashBagOStuff([ 'maxKeys'=> 100]);} try { $wanCache=$services->getMainWANObjectCache();} catch(RecursiveServiceDependencyException $e) { $wanCache=WANObjectCache::newEmpty();} $lbConf=MWLBFactory::applyDefaultConfig($mainConfig->get( 'LBFactoryConf'), new ServiceOptions(MWLBFactory::APPLY_DEFAULT_CONFIG_OPTIONS, $mainConfig), $services->getConfiguredReadOnlyMode(), $services->getLocalServerObjectCache(), $stash, $wanCache);$class=MWLBFactory::getLBFactoryClass( $lbConf);$instance=new $class( $lbConf);MWLBFactory::setDomainAliases( $instance);return $instance;}, 'Emailer'=> function(MediaWikiServices $services) :IEmailer { return new Emailer();}, 'EventRelayerGroup'=> function(MediaWikiServices $services) :EventRelayerGroup { return new EventRelayerGroup( $services->getMainConfig() ->get( 'EventRelayerConfig'));}, 'ExternalStoreAccess'=> function(MediaWikiServices $services) :ExternalStoreAccess { return new ExternalStoreAccess($services->getExternalStoreFactory(), LoggerFactory::getInstance( 'ExternalStore'));}, 'ExternalStoreFactory'=> function(MediaWikiServices $services) :ExternalStoreFactory { $config=$services->getMainConfig();$writeStores=$config->get( 'DefaultExternalStore');return new ExternalStoreFactory($config->get( 'ExternalStores'),( $writeStores !==false) ?(array) $writeStores :[], $services->getDBLoadBalancer() ->getLocalDomainID(), LoggerFactory::getInstance( 'ExternalStore'));}, 'FileBackendGroup'=> function(MediaWikiServices $services) :FileBackendGroup { $mainConfig=$services->getMainConfig();$ld=WikiMap::getCurrentWikiDbDomain();$fallbackWikiId=WikiMap::getWikiIdFromDbDomain( $ld);$legacyDomainId=strlen( $ld->getTablePrefix()) ? "{$ld->getDatabase()}-{$ld->getTablePrefix()}" :$ld->getDatabase();if( $ld->getSchema() !==null && $legacyDomainId !==$fallbackWikiId) { wfWarn("Legacy default 'domainId' is '$legacyDomainId' but wiki ID is '$fallbackWikiId'.");} $cache=$services->getLocalServerObjectCache();if( $cache instanceof EmptyBagOStuff) { $cache=new HashBagOStuff;} return new FileBackendGroup(new ServiceOptions(FileBackendGroup::CONSTRUCTOR_OPTIONS, $mainConfig, [ 'fallbackWikiId'=> $fallbackWikiId]), $services->getConfiguredReadOnlyMode(), $cache, $services->getMainWANObjectCache(), $services->getMimeAnalyzer(), $services->getLockManagerGroupFactory(), $services->getTempFSFileFactory(), $services->getObjectFactory());}, 'GenderCache'=> function(MediaWikiServices $services) :GenderCache { $nsInfo=$services->getNamespaceInfo();$dbLoadBalancer=$services->isServiceDisabled( 'DBLoadBalancer') ? null :$services->getDBLoadBalancer();return new GenderCache( $nsInfo, $dbLoadBalancer, $services->get( '_DefaultOptionsLookup'));}, 'GlobalIdGenerator'=> function(MediaWikiServices $services) :GlobalIdGenerator { $mainConfig=$services->getMainConfig();return new GlobalIdGenerator($mainConfig->get( 'TmpDirectory'), $mainConfig->get( 'CommandLineMode') ? new EmptyBagOStuff() :$services->getLocalServerObjectCache(), function( $command) { return wfShellExec( $command);});}, 'HookContainer'=> function(MediaWikiServices $services) :HookContainer { $extRegistry=ExtensionRegistry::getInstance();$extDeprecatedHooks=$extRegistry->getAttribute( 'DeprecatedHooks');$deprecatedHooks=new DeprecatedHooks( $extDeprecatedHooks);$hookRegistry=new GlobalHookRegistry( $extRegistry, $deprecatedHooks);return new HookContainer($hookRegistry, $services->getObjectFactory());}, 'HtmlCacheUpdater'=> function(MediaWikiServices $services) :HtmlCacheUpdater { $config=$services->getMainConfig();return new HtmlCacheUpdater($services->getHookContainer(), $config->get( 'CdnReboundPurgeDelay'), $config->get( 'UseFileCache'), $config->get( 'CdnMaxAge'));}, 'HttpRequestFactory'=> function(MediaWikiServices $services) :HttpRequestFactory { return new HttpRequestFactory(new ServiceOptions(HttpRequestFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), LoggerFactory::getInstance( 'http'));}, 'InterwikiLookup'=> function(MediaWikiServices $services) :InterwikiLookup { $config=$services->getMainConfig();return new ClassicInterwikiLookup($services->getContentLanguage(), $services->getMainWANObjectCache(), $services->getHookContainer(), $config->get( 'InterwikiExpiry'), $config->get( 'InterwikiCache'), $config->get( 'InterwikiScopes'), $config->get( 'InterwikiFallbackSite'));}, 'JobRunner'=> function(MediaWikiServices $services) :JobRunner { return new JobRunner(new ServiceOptions(JobRunner::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getDBLoadBalancerFactory(), JobQueueGroup::singleton(), $services->getReadOnlyMode(), $services->getLinkCache(), $services->getStatsdDataFactory(), LoggerFactory::getInstance( 'runJobs'));}, 'LanguageConverterFactory'=> function(MediaWikiServices $services) :LanguageConverterFactory { $usePigLatinVariant=$services->getMainConfig() ->get( 'UsePigLatinVariant');return new LanguageConverterFactory( $usePigLatinVariant, function() use( $services) { return $services->getContentLanguage();});}, 'LanguageFactory'=> function(MediaWikiServices $services) :LanguageFactory { return new LanguageFactory(new ServiceOptions(LanguageFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getLocalisationCache(), $services->getLanguageNameUtils(), $services->getLanguageFallback(), $services->getLanguageConverterFactory(), $services->getHookContainer());}, 'LanguageFallback'=> function(MediaWikiServices $services) :LanguageFallback { return new LanguageFallback($services->getMainConfig() ->get( 'LanguageCode'), $services->getLocalisationCache(), $services->getLanguageNameUtils());}, 'LanguageNameUtils'=> function(MediaWikiServices $services) :LanguageNameUtils { return new LanguageNameUtils(new ServiceOptions(LanguageNameUtils::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getHookContainer());}, 'LinkBatchFactory'=> function(MediaWikiServices $services) :LinkBatchFactory { return new LinkBatchFactory($services->getLinkCache(), $services->getTitleFormatter(), $services->getContentLanguage(), $services->getGenderCache(), $services->getDBLoadBalancer());}, 'LinkCache'=> function(MediaWikiServices $services) :LinkCache { return new LinkCache($services->getTitleFormatter(), $services->getMainWANObjectCache(), $services->getNamespaceInfo());}, 'LinkRenderer'=> function(MediaWikiServices $services) :LinkRenderer { if(defined( 'MW_NO_SESSION')) { return $services->getLinkRendererFactory() ->create();} else { return $services->getLinkRendererFactory() ->createForUser(RequestContext::getMain() ->getUser());} }, 'LinkRendererFactory'=> function(MediaWikiServices $services) :LinkRendererFactory { return new LinkRendererFactory($services->getTitleFormatter(), $services->getLinkCache(), $services->getNamespaceInfo(), $services->getSpecialPageFactory(), $services->getHookContainer());}, 'LocalisationCache'=> function(MediaWikiServices $services) :LocalisationCache { $conf=$services->getMainConfig() ->get( 'LocalisationCacheConf');$logger=LoggerFactory::getInstance( 'localisation');$store=LocalisationCache::getStoreFromConf($conf, $services->getMainConfig() ->get( 'CacheDirectory'));$logger->debug( 'LocalisationCache using store ' . get_class( $store));return new $conf['class'](new ServiceOptions(LocalisationCache::CONSTRUCTOR_OPTIONS, $conf, ['forceRecache'=> false, 'manualRecache'=> false,], $services->getMainConfig()), $store, $logger, [function() use( $services) { MessageBlobStore::clearGlobalCacheEntry( $services->getMainWANObjectCache());}], $services->getLanguageNameUtils(), $services->getHookContainer());}, 'LocalServerObjectCache'=> function(MediaWikiServices $services) :BagOStuff { return ObjectCache::makeLocalServerCache();}, 'LockManagerGroupFactory'=> function(MediaWikiServices $services) :LockManagerGroupFactory { return new LockManagerGroupFactory(WikiMap::getCurrentWikiDbDomain() ->getId(), $services->getMainConfig() ->get( 'LockManagers'), $services->getDBLoadBalancerFactory());}, 'MagicWordFactory'=> function(MediaWikiServices $services) :MagicWordFactory { return new MagicWordFactory($services->getContentLanguage(), $services->getHookContainer());}, 'MainConfig'=> function(MediaWikiServices $services) :Config { return $services->getConfigFactory() ->makeConfig( 'main');}, 'MainObjectStash'=> function(MediaWikiServices $services) :BagOStuff { $mainConfig=$services->getMainConfig();$id=$mainConfig->get( 'MainStash');if(!isset( $mainConfig->get( 'ObjectCaches')[$id])) { throw new UnexpectedValueException("Cache type \"$id\" is not present in \$wgObjectCaches.");} $params=$mainConfig->get( 'ObjectCaches')[$id];$store=ObjectCache::newFromParams( $params, $mainConfig);$store->getLogger() ->debug( 'MainObjectStash using store {class}', ['class'=> get_class( $store)]);return $store;}, 'MainWANObjectCache'=> function(MediaWikiServices $services) :WANObjectCache { $mainConfig=$services->getMainConfig();$wanId=$mainConfig->get( 'MainWANCache');$wanParams=$mainConfig->get( 'WANObjectCaches')[$wanId] ?? null;if(! $wanParams) { throw new UnexpectedValueException("wgWANObjectCaches must have \"$wanId\" set (via wgMainWANCache)");} $cacheId=$wanParams['cacheId'];$wanClass=$wanParams['class'];unset( $wanParams['cacheId']);unset( $wanParams['class']);$storeParams=$mainConfig->get( 'ObjectCaches')[$cacheId] ?? null;if(! $storeParams) { throw new UnexpectedValueException("wgObjectCaches must have \"$cacheId\" set (via wgWANObjectCaches)");} $store=ObjectCache::newFromParams( $storeParams, $mainConfig);$logger=$store->getLogger();$logger->debug( 'MainWANObjectCache using store {class}', ['class'=> get_class( $store)]);$wanParams['cache']=$store;$wanParams['logger']=$logger;$wanParams['secret']=$wanParams['secret'] ?? $mainConfig->get( 'SecretKey');if(! $mainConfig->get( 'CommandLineMode')) { $wanParams['stats']=$services->getStatsdDataFactory();$wanParams['asyncHandler']=[DeferredUpdates::class, 'addCallableUpdate'];} $instance=new $wanClass( $wanParams);' @phan-var WANObjectCache $instance';return $instance;}, 'MediaHandlerFactory'=> function(MediaWikiServices $services) :MediaHandlerFactory { return new MediaHandlerFactory($services->getMainConfig() ->get( 'MediaHandlers'));}, 'MergeHistoryFactory'=> function(MediaWikiServices $services) :MergeHistoryFactory { return $services->getService( '_PageCommandFactory');}, 'MessageCache'=> function(MediaWikiServices $services) :MessageCache { $mainConfig=$services->getMainConfig();$clusterCache=ObjectCache::getInstance( $mainConfig->get( 'MessageCacheType'));$srvCache=$mainConfig->get( 'UseLocalMessageCache') ? $services->getLocalServerObjectCache() :new EmptyBagOStuff();$logger=LoggerFactory::getInstance( 'MessageCache');$logger->debug( 'MessageCache using store {class}', ['class'=> get_class( $clusterCache)]);return new MessageCache($services->getMainWANObjectCache(), $clusterCache, $srvCache, $services->getContentLanguage(), $services->getLanguageConverterFactory() ->getLanguageConverter(), $logger, [ 'useDB'=> $mainConfig->get( 'UseDatabaseMessages')], $services->getLanguageFactory(), $services->getLocalisationCache(), $services->getLanguageNameUtils(), $services->getLanguageFallback(), $services->getHookContainer());}, 'MessageFormatterFactory'=> function() :IMessageFormatterFactory { return new MessageFormatterFactory();}, 'MimeAnalyzer'=> function(MediaWikiServices $services) :MimeAnalyzer { $logger=LoggerFactory::getInstance( 'Mime');$mainConfig=$services->getMainConfig();$hookRunner=new HookRunner( $services->getHookContainer());$params=['typeFile'=> $mainConfig->get( 'MimeTypeFile'), 'infoFile'=> $mainConfig->get( 'MimeInfoFile'), 'xmlTypes'=> $mainConfig->get( 'XMLMimeTypes'), 'guessCallback'=> function( $mimeAnalyzer, &$head, &$tail, $file, &$mime) use( $logger, $hookRunner) { $deja=new DjVuImage( $file);if( $deja->isValid()) { $logger->info("Detected $file as image/vnd.djvu\n");$mime='image/vnd.djvu';return;} $hookRunner->onMimeMagicGuessFromContent($mimeAnalyzer, $head, $tail, $file, $mime);}, 'extCallback'=> function( $mimeAnalyzer, $ext, &$mime) use( $hookRunner) { $hookRunner->onMimeMagicImproveFromExtension( $mimeAnalyzer, $ext, $mime);}, 'initCallback'=> function( $mimeAnalyzer) use( $hookRunner) { $hookRunner->onMimeMagicInit( $mimeAnalyzer);}, 'logger'=> $logger];if( $params['infoFile']==='includes/mime.info') { $params['infoFile']=MimeAnalyzer::USE_INTERNAL;} if( $params['typeFile']==='includes/mime.types') { $params['typeFile']=MimeAnalyzer::USE_INTERNAL;} $detectorCmd=$mainConfig->get( 'MimeDetectorCommand');if( $detectorCmd) { $factory=$services->getShellCommandFactory();$params['detectCallback']=function( $file) use( $detectorCmd, $factory) { $result=$factory->create() ->unsafeParams( $detectorCmd) ->params( $file) ->execute();return $result->getStdout();};} return new MimeAnalyzer( $params);}, 'MovePageFactory'=> function(MediaWikiServices $services) :MovePageFactory { return $services->getService( '_PageCommandFactory');}, 'NamespaceInfo'=> function(MediaWikiServices $services) :NamespaceInfo { return new NamespaceInfo(new ServiceOptions(NamespaceInfo::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getHookContainer());}, 'NameTableStoreFactory'=> function(MediaWikiServices $services) :NameTableStoreFactory { return new NameTableStoreFactory($services->getDBLoadBalancerFactory(), $services->getMainWANObjectCache(), LoggerFactory::getInstance( 'NameTableSqlStore'));}, 'ObjectFactory'=> function(MediaWikiServices $services) :ObjectFactory { return new ObjectFactory( $services);}, 'OldRevisionImporter'=> function(MediaWikiServices $services) :OldRevisionImporter { return new ImportableOldRevisionImporter(true, LoggerFactory::getInstance( 'OldRevisionImporter'), $services->getDBLoadBalancer(), $services->getRevisionStore(), $services->getSlotRoleRegistry());}, 'PageEditStash'=> function(MediaWikiServices $services) :PageEditStash { $config=$services->getMainConfig();return new PageEditStash(ObjectCache::getLocalClusterInstance(), $services->getDBLoadBalancer(), LoggerFactory::getInstance( 'StashEdit'), $services->getStatsdDataFactory(), $services->getHookContainer(), defined( 'MEDIAWIKI_JOB_RUNNER')|| $config->get( 'CommandLineMode') ? PageEditStash::INITIATOR_JOB_OR_CLI :PageEditStash::INITIATOR_USER);}, 'Parser'=> function(MediaWikiServices $services) :Parser { return $services->getParserFactory() ->create();}, 'ParserCache'=> function(MediaWikiServices $services) :ParserCache { $config=$services->getMainConfig();$cache=ObjectCache::getInstance( $config->get( 'ParserCacheType'));wfDebugLog( 'caches', 'parser:' . get_class( $cache));return new ParserCache($cache, $config->get( 'CacheEpoch'), $services->getHookContainer(), $services->getStatsdDataFactory());}, 'ParserFactory'=> function(MediaWikiServices $services) :ParserFactory { $options=new ServiceOptions(Parser::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ->get( 'ParserConf'), [ 'class'=> Parser::class], $services->getMainConfig());return new ParserFactory($options, $services->getMagicWordFactory(), $services->getContentLanguage(), wfUrlProtocols(), $services->getSpecialPageFactory(), $services->getLinkRendererFactory(), $services->getNamespaceInfo(), LoggerFactory::getInstance( 'Parser'), $services->getBadFileLookup(), $services->getLanguageConverterFactory(), $services->getHookContainer());}, 'PasswordFactory'=> function(MediaWikiServices $services) :PasswordFactory { $config=$services->getMainConfig();return new PasswordFactory($config->get( 'PasswordConfig'), $config->get( 'PasswordDefault'));}, 'PasswordReset'=> function(MediaWikiServices $services) :PasswordReset { $options=new ServiceOptions(PasswordReset::CONSTRUCTOR_OPTIONS, $services->getMainConfig());return new PasswordReset($options, $services->getAuthManager(), $services->getPermissionManager(), $services->getDBLoadBalancer(), LoggerFactory::getInstance( 'authentication'), $services->getHookContainer());}, 'PerDbNameStatsdDataFactory'=> function(MediaWikiServices $services) :StatsdDataFactoryInterface { $config=$services->getMainConfig();$wiki=$config->get( 'DBname');return new PrefixingStatsdDataFactoryProxy($services->getStatsdDataFactory(), $wiki);}, 'PermissionManager'=> function(MediaWikiServices $services) :PermissionManager { return new PermissionManager(new ServiceOptions(PermissionManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getSpecialPageFactory(), $services->getRevisionLookup(), $services->getNamespaceInfo(), $services->getBlockErrorFormatter(), $services->getHookContainer());}, 'PreferencesFactory'=> function(MediaWikiServices $services) :PreferencesFactory { $factory=new DefaultPreferencesFactory(new ServiceOptions(DefaultPreferencesFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getContentLanguage(), $services->getAuthManager(), $services->getLinkRendererFactory() ->create(), $services->getNamespaceInfo(), $services->getPermissionManager(), $services->getLanguageConverterFactory() ->getLanguageConverter(), $services->getLanguageNameUtils(), $services->getHookContainer());$factory->setLogger(LoggerFactory::getInstance( 'preferences'));return $factory;}, 'ProxyLookup'=> function(MediaWikiServices $services) :ProxyLookup { $mainConfig=$services->getMainConfig();return new ProxyLookup($mainConfig->get( 'CdnServers'), $mainConfig->get( 'CdnServersNoPurge'));}, 'ReadOnlyMode'=> function(MediaWikiServices $services) :ReadOnlyMode { return new ReadOnlyMode($services->getConfiguredReadOnlyMode(), $services->getDBLoadBalancer());}, 'RepoGroup'=> function(MediaWikiServices $services) :RepoGroup { $config=$services->getMainConfig();return new RepoGroup($config->get( 'LocalFileRepo'), $config->get( 'ForeignFileRepos'), $services->getMainWANObjectCache());}, 'ResourceLoader'=> function(MediaWikiServices $services) :ResourceLoader { global $IP;$config=$services->getMainConfig();$rl=new ResourceLoader($config, LoggerFactory::getInstance( 'resourceloader'), $config->get( 'ResourceLoaderUseObjectCacheForDeps') ? new KeyValueDependencyStore( $services->getMainObjectStash()) :new SqlModuleDependencyStore( $services->getDBLoadBalancer()));$extRegistry=ExtensionRegistry::getInstance();$modules=$extRegistry->getAttribute( 'ResourceModules')+ $config->get( 'ResourceModules');$moduleSkinStyles=$extRegistry->getAttribute( 'ResourceModuleSkinStyles')+ $config->get( 'ResourceModuleSkinStyles');$rl->setModuleSkinStyles( $moduleSkinStyles);$rl->addSource( $config->get( 'ResourceLoaderSources'));$rl->register(include "$IP/resources/Resources.php");$rl->register( $modules);$hookRunner=new \MediaWiki\ResourceLoader\HookRunner( $services->getHookContainer());$hookRunner->onResourceLoaderRegisterModules( $rl);$msgPosterAttrib=$extRegistry->getAttribute( 'MessagePosterModule');$rl->register( 'mediawiki.messagePoster', ['localBasePath'=> $IP, 'debugRaw'=> false, 'scripts'=> array_merge(["resources/src/mediawiki.messagePoster/factory.js", "resources/src/mediawiki.messagePoster/MessagePoster.js", "resources/src/mediawiki.messagePoster/WikitextMessagePoster.js",], $msgPosterAttrib['scripts'] ??[]), 'dependencies'=> array_merge(['oojs', 'mediawiki.api', 'mediawiki.ForeignApi',], $msgPosterAttrib['dependencies'] ??[]), 'targets'=>[ 'desktop', 'mobile'],]);if( $config->get( 'EnableJavaScriptTest')===true) { $rl->registerTestModules();} return $rl;}, 'RevisionFactory'=> function(MediaWikiServices $services) :RevisionFactory { return $services->getRevisionStore();}, 'RevisionLookup'=> function(MediaWikiServices $services) :RevisionLookup { return $services->getRevisionStore();}, 'RevisionRenderer'=> function(MediaWikiServices $services) :RevisionRenderer { $renderer=new RevisionRenderer($services->getDBLoadBalancer(), $services->getSlotRoleRegistry());$renderer->setLogger(LoggerFactory::getInstance( 'SaveParse'));return $renderer;}, 'RevisionStore'=> function(MediaWikiServices $services) :RevisionStore { return $services->getRevisionStoreFactory() ->getRevisionStore();}, 'RevisionStoreFactory'=> function(MediaWikiServices $services) :RevisionStoreFactory { $config=$services->getMainConfig();if( $config->has( 'MultiContentRevisionSchemaMigrationStage')) { if( $config->get( 'MultiContentRevisionSchemaMigrationStage') !==SCHEMA_COMPAT_NEW) { throw new UnexpectedValueException('The MultiContentRevisionSchemaMigrationStage setting is no longer supported!');} } $store=new RevisionStoreFactory($services->getDBLoadBalancerFactory(), $services->getBlobStoreFactory(), $services->getNameTableStoreFactory(), $services->getSlotRoleRegistry(), $services->getMainWANObjectCache(), $services->getCommentStore(), $services->getActorMigration(), LoggerFactory::getInstance( 'RevisionStore'), $services->getContentHandlerFactory(), $services->getHookContainer());return $store;}, 'SearchEngineConfig'=> function(MediaWikiServices $services) :SearchEngineConfig { return new SearchEngineConfig($services->getMainConfig(), $services->getContentLanguage(), $services->getHookContainer(), ExtensionRegistry::getInstance() ->getAttribute( 'SearchMappings'));}, 'SearchEngineFactory'=> function(MediaWikiServices $services) :SearchEngineFactory { return new SearchEngineFactory($services->getSearchEngineConfig(), $services->getHookContainer());}, 'ShellCommandFactory'=> function(MediaWikiServices $services) :CommandFactory { $config=$services->getMainConfig();$limits=['time'=> $config->get( 'MaxShellTime'), 'walltime'=> $config->get( 'MaxShellWallClockTime'), 'memory'=> $config->get( 'MaxShellMemory'), 'filesize'=> $config->get( 'MaxShellFileSize'),];$cgroup=$config->get( 'ShellCgroup');$restrictionMethod=$config->get( 'ShellRestrictionMethod');$factory=new CommandFactory( $limits, $cgroup, $restrictionMethod);$factory->setLogger(LoggerFactory::getInstance( 'exec'));$factory->logStderr();return $factory;}, 'SiteLookup'=> function(MediaWikiServices $services) :SiteLookup { return $services->getSiteStore();}, 'SiteStore'=> function(MediaWikiServices $services) :SiteStore { $rawSiteStore=new DBSiteStore( $services->getDBLoadBalancer());$cache=$services->getLocalServerObjectCache();if( $cache instanceof EmptyBagOStuff) { $cache=ObjectCache::getLocalClusterInstance();} return new CachingSiteStore( $rawSiteStore, $cache);}, 'SkinFactory'=> function(MediaWikiServices $services) :SkinFactory { $factory=new SkinFactory( $services->getObjectFactory());$names=$services->getMainConfig() ->get( 'ValidSkinNames');foreach( $names as $name=> $skin) { if(is_array( $skin)) { $spec=$skin;$displayName=$skin['displayname'] ?? $name;} else { $displayName=$skin;$spec=['class'=> "Skin$skin"];} $factory->register( $name, $displayName, $spec);} $factory->register( 'fallback', 'Fallback', ['class'=> SkinFallback::class, 'args'=>[['styles'=>[ 'mediawiki.skinning.interface'], 'templateDirectory'=> __DIR__ . '/skins/templates/fallback',]]]);$factory->register( 'apioutput', 'ApiOutput', ['class'=> SkinApi::class, 'args'=>[['styles'=>[ 'mediawiki.skinning.interface'], 'templateDirectory'=> __DIR__ . '/skins/templates/apioutput',]]]);return $factory;}, 'SlotRoleRegistry'=> function(MediaWikiServices $services) :SlotRoleRegistry { $config=$services->getMainConfig();$contentHandlerFactory=$services->getContentHandlerFactory();$registry=new SlotRoleRegistry($services->getSlotRoleStore());$registry->defineRole( 'main', function() use( $config, $contentHandlerFactory) { return new MainSlotRoleHandler($config->get( 'NamespaceContentModels'), $contentHandlerFactory);});return $registry;}, 'SlotRoleStore'=> function(MediaWikiServices $services) :NameTableStore { return $services->getNameTableStoreFactory() ->getSlotRoles();}, 'SpamChecker'=> function(MediaWikiServices $services) :SpamChecker { return new SpamChecker((array) $services->getMainConfig() ->get( 'SpamRegex'),(array) $services->getMainConfig() ->get( 'SummarySpamRegex'));}, 'SpecialPageFactory'=> function(MediaWikiServices $services) :SpecialPageFactory { return new SpecialPageFactory(new ServiceOptions(SpecialPageFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getContentLanguage(), $services->getObjectFactory(), $services->getHookContainer());}, 'StatsdDataFactory'=> function(MediaWikiServices $services) :IBufferingStatsdDataFactory { return new BufferingStatsdDataFactory(rtrim( $services->getMainConfig() ->get( 'StatsdMetricPrefix'), '.'));}, 'TalkPageNotificationManager'=> function(MediaWikiServices $services) :TalkPageNotificationManager { return new TalkPageNotificationManager(new ServiceOptions(TalkPageNotificationManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getDBLoadBalancer(), $services->getReadOnlyMode(), $services->getRevisionLookup());}, 'TempFSFileFactory'=> function(MediaWikiServices $services) :TempFSFileFactory { return new TempFSFileFactory( $services->getMainConfig() ->get( 'TmpDirectory'));}, 'TitleFactory'=> function() :TitleFactory { return new TitleFactory();}, 'TitleFormatter'=> function(MediaWikiServices $services) :TitleFormatter { return $services->getService( '_MediaWikiTitleCodec');}, 'TitleParser'=> function(MediaWikiServices $services) :TitleParser { return $services->getService( '_MediaWikiTitleCodec');}, 'UploadRevisionImporter'=> function(MediaWikiServices $services) :UploadRevisionImporter { return new ImportableUploadRevisionImporter($services->getMainConfig() ->get( 'EnableUploads'), LoggerFactory::getInstance( 'UploadRevisionImporter'));}, 'UserEditTracker'=> function(MediaWikiServices $services) :UserEditTracker { return new UserEditTracker($services->getActorMigration(), $services->getDBLoadBalancer());}, 'UserFactory'=> function(MediaWikiServices $services) :UserFactory { return new UserFactory( $services->getUserNameUtils());}, 'UserGroupManager'=> function(MediaWikiServices $services) :UserGroupManager { return $services->getUserGroupManagerFactory() ->getUserGroupManager();}, 'UserGroupManagerFactory'=> function(MediaWikiServices $services) :UserGroupManagerFactory { return new UserGroupManagerFactory(new ServiceOptions(UserGroupManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getConfiguredReadOnlyMode(), $services->getDBLoadBalancerFactory(), $services->getHookContainer(), $services->getUserEditTracker(), LoggerFactory::getInstance( 'UserGroupManager'), [function(UserIdentity $user) use( $services) { $services->getPermissionManager() ->invalidateUsersRightsCache( $user);User::newFromIdentity( $user) ->invalidateCache();}]);}, 'UserNameUtils'=> function(MediaWikiServices $services) :UserNameUtils { $messageFormatterFactory=new MessageFormatterFactory(Message::FORMAT_PLAIN);return new UserNameUtils(new ServiceOptions(UserNameUtils::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getContentLanguage(), LoggerFactory::getInstance( 'UserNameUtils'), $services->getTitleParser(), $messageFormatterFactory->getTextFormatter($services->getContentLanguage() ->getCode()), $services->getHookContainer());}, 'UserOptionsLookup'=> function(MediaWikiServices $services) :UserOptionsLookup { return $services->getUserOptionsManager();}, 'UserOptionsManager'=> function(MediaWikiServices $services) :UserOptionsManager { return new UserOptionsManager(new ServiceOptions(UserOptionsManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->get( '_DefaultOptionsLookup'), $services->getLanguageConverterFactory(), $services->getDBLoadBalancer(), LoggerFactory::getInstance( 'UserOptionsManager'), $services->getHookContainer());}, 'VirtualRESTServiceClient'=> function(MediaWikiServices $services) :VirtualRESTServiceClient { $config=$services->getMainConfig() ->get( 'VirtualRestConfig');$vrsClient=new VirtualRESTServiceClient($services->getHttpRequestFactory() ->createMultiClient());foreach( $config['paths'] as $prefix=> $serviceConfig) { $class=$serviceConfig['class'];$constructArg=$serviceConfig['options'] ??[];$constructArg+=$config['global'];$vrsClient->mount( $prefix, [ 'class'=> $class, 'config'=> $constructArg]);} return $vrsClient;}, 'WatchedItemQueryService'=> function(MediaWikiServices $services) :WatchedItemQueryService { return new WatchedItemQueryService($services->getDBLoadBalancer(), $services->getCommentStore(), $services->getActorMigration(), $services->getWatchedItemStore(), $services->getPermissionManager(), $services->getHookContainer(), $services->getMainConfig() ->get( 'WatchlistExpiry'), $services->getMainConfig() ->get( 'MaxExecutionTimeForExpensiveQueries'));}, 'WatchedItemStore'=> function(MediaWikiServices $services) :WatchedItemStore { $store=new WatchedItemStore(new ServiceOptions(WatchedItemStore::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getDBLoadBalancerFactory(), JobQueueGroup::singleton(), $services->getMainObjectStash(), new HashBagOStuff([ 'maxKeys'=> 100]), $services->getReadOnlyMode(), $services->getNamespaceInfo(), $services->getRevisionLookup(), $services->getHookContainer());$store->setStatsdDataFactory( $services->getStatsdDataFactory());if( $services->getMainConfig() ->get( 'ReadOnlyWatchedItemStore')) { $store=new NoWriteWatchedItemStore( $store);} return $store;}, 'WatchlistNotificationManager'=> function(MediaWikiServices $services) :WatchlistNotificationManager { return new WatchlistNotificationManager(new ServiceOptions(WatchlistNotificationManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getHookContainer(), $services->getPermissionManager(), $services->getReadOnlyMode(), $services->getRevisionLookup(), $services->getTalkPageNotificationManager(), $services->getWatchedItemStore());}, 'WikiRevisionOldRevisionImporterNoUpdates'=> function(MediaWikiServices $services) :ImportableOldRevisionImporter { return new ImportableOldRevisionImporter(false, LoggerFactory::getInstance( 'OldRevisionImporter'), $services->getDBLoadBalancer(), $services->getRevisionStore(), $services->getSlotRoleRegistry());}, '_DefaultOptionsLookup'=> function(MediaWikiServices $services) :DefaultOptionsLookup { return new DefaultOptionsLookup(new ServiceOptions(DefaultOptionsLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getContentLanguage(), $services->getHookContainer());}, '_MediaWikiTitleCodec'=> function(MediaWikiServices $services) :MediaWikiTitleCodec { return new MediaWikiTitleCodec($services->getContentLanguage(), $services->getGenderCache(), $services->getMainConfig() ->get( 'LocalInterwikis'), $services->getInterwikiLookup(), $services->getNamespaceInfo());}, '_PageCommandFactory'=> function(MediaWikiServices $services) :PageCommandFactory { return new PageCommandFactory(new ServiceOptions(PageCommandFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getDBLoadBalancer(), $services->getNamespaceInfo(), $services->getWatchedItemStore(), $services->getPermissionManager(), $services->getRepoGroup(), $services->getContentHandlerFactory(), $services->getRevisionStore(), $services->getSpamChecker(), $services->getHookContainer());}, '_SqlBlobStore'=> function(MediaWikiServices $services) :SqlBlobStore { return $services->getBlobStoreFactory() ->newSqlBlobStore();},]
if(ini_get('mbstring.func_overload')) if(!defined('MW_ENTRY_POINT'))
Pre-config setup: Before loading LocalSettings.php.
Definition Setup.php:85
$IP
Definition WebStart.php:49
This class handles the logic for the actor table migration and should always be used in lieu of direc...
Class representing a cache/ephemeral data store.
Definition BagOStuff.php:71
get( $key, $flags=0)
Get an item with the given key.
A factory for application metric data.
CommentStore handles storage of comments (edit summaries, log reasons, etc) in the database.
Factory class to create Config objects.
A read-only mode service which does not depend on LoadBalancer.
Support for detecting/validating DjVu image files and getting some basic file metadata (resolution et...
Definition DjVuImage.php:38
A BagOStuff object with no objects in it.
Factory class for spawning EventRelayer objects using configuration.
ExtensionRegistry class.
Key/value blob storage for a collection of storage medium types (e.g.
Class to handle file backend registration.
Caches user genders when needed to use correct namespace aliases.
Simple store for keeping values in an associative array for the current process.
Class to invalidate the CDN and HTMLFileCache entries associated with URLs/titles.
Class to handle enqueueing of background jobs.
Job queue runner utility methods.
Definition JobRunner.php:41
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition Language.php:41
Cache for article titles (prefixed DB keys) and ids linked from one source.
Definition LinkCache.php:34
Class for caching the contents of localisation files, Messages*.php and *.i18n.php.
static getStoreFromConf(array $conf, $fallbackCacheDir)
Return a suitable LCStore as specified by the given configuration.
static setDomainAliases(ILBFactory $lbFactory)
static getLBFactoryClass(array $config)
Decide which LBFactory class to use.
static applyDefaultConfig(array $lbConf, ServiceOptions $options, ConfiguredReadOnlyMode $readOnlyMode, BagOStuff $srvCache, BagOStuff $mainStash, WANObjectCache $wanCache)
A factory that stores information about MagicWords, and creates them on demand with caching.
Class to construct MediaHandler objects.
A codec for MediaWiki page titles.
This serves as the entry point to the authentication system.
setLogger(LoggerInterface $logger)
A service class for getting formatted information about a block.
A service class for checking blocks.
Object which holds currently registered configuration options.
A class for passing options to services.
Service to check if text (either content or a summary) qualifies as spam.
A HookRegistry which sources its data from dynamically changing sources: $wgHooks and an ExtensionReg...
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Factory creating MWHttpRequest objects.
InterwikiLookup implementing the "classic" interwiki storage (hardcoded up to MW 1....
An interface for creating language converters.
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
A service that provides utilities to do with language names and codes.
Factory to create LinkRender objects.
Class that generates HTML links for pages.
PSR-3 logger instance factory.
MediaWikiServices is the service locator for the application scope of MediaWiki.
The MediaWiki-specific implementation of IMessageFormatterFactory.
Common factory to construct page handling classes.
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...
This is the default implementation of PreferencesFactory.
A SlotRoleHandler for the main slot.
The RevisionRenderer service provides access to rendered output for revisions.
setLogger(LoggerInterface $saveParseLogger)
Factory service for RevisionStore instances.
Service for looking up page revisions.
A registry service for SlotRoleHandlers, used to define which slot roles are available on which page.
Factory facilitating dependency injection for Command.
Factory for handling the special page list and generating SpecialPage objects.
Service for instantiating BlobStores.
Class for managing stashed edits used by the page updater classes.
Service for storing and loading Content objects.
A service class to control default user options.
Track info about user edit counts and timings.
Creates User objects.
Factory service for UserGroupManager instances.
UserNameUtils service.
Provides access to user options.
A service class to control user options.
static clearGlobalCacheEntry(WANObjectCache $cache)
Invalidate cache keys for all known modules.
Cache of messages that are defined by MediaWiki namespace pages or by hooks.
The Message class deals with fetching and processing of interface message into a variety of formats.
Definition Message.php:161
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
Functions to get cache objects.
static newFromParams(array $params, Config $conf=null)
Create a new cache object from parameters.
static getInstance( $id)
Get a cached instance of the specified type of cache object.
static getLocalClusterInstance()
Get the main cluster-local cache object.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:85
Factory class for creating and checking Password objects.
Helper class for the password reset functionality shared by the web UI and the API.
Proxy to prefix metric keys sent to a StatsdDataFactoryInterface.
A service class for fetching the wiki's current read-only mode.
Prioritized list of file repositories.
Definition RepoGroup.php:31
Group all the pieces relevant to the context of a request into one instance @newable.
ResourceLoader is a loading system for JavaScript and CSS resources.
Configuration handling class for SearchEngine.
Factory class for SearchEngine.
Factory class to create Skin objects.
register( $name, $displayName, $spec)
Register a new Skin factory function.
Creates Title objects.
static newFromIdentity(UserIdentity $identity)
Returns a User object corresponding to the given UserIdentity.
Definition User.php:597
Virtual HTTP service client loosely styled after a Virtual File System.
Multi-datacenter aware caching interface.
static newEmpty()
Get an instance that wraps EmptyBagOStuff.
get( $key, &$curTTL=null, array $checkKeys=[], &$info=null)
Fetch the value of a key from cache.
Storage layer class for WatchedItems.
setStatsdDataFactory(StatsdDataFactoryInterface $stats)
Helper tools for dealing with other locally-hosted wikis.
Definition WikiMap.php:29
static getWikiIdFromDbDomain( $domain)
Get the wiki ID of a database domain.
Definition WikiMap.php:269
static getCurrentWikiDbDomain()
Definition WikiMap.php:293
Lightweight class for tracking path dependencies lists via an object cache instance.
Class for tracking per-entity dependency path lists in the module_deps table.
Class for getting statistically unique IDs without a central coordinator.
const MIGRATION_NEW
Definition Defines.php:308
const SCHEMA_COMPAT_NEW
Definition Defines.php:281
Interface for configuration instances.
Definition Config.php:30
MediaWiki adaptation of StatsdDataFactory that provides buffering functionality.
Service interface for looking up Interwiki records.
Interface for sending emails.
Definition IEmailer.php:34
A PreferencesFactory is a MediaWiki service that provides the definitions of preferences for a given ...
Service for constructing revision objects.
Service for looking up page revisions.
Service for loading and storing data blobs.
Definition BlobStore.php:35
Interface for objects representing user identity.
A title formatter service for MediaWiki.
A title parser service for MediaWiki.
A simple factory providing a message formatter for a given language code.
$command
Definition mcc.php:125
$cache
Definition mcc.php:33
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...
return true
Definition router.php:92
$mime
Definition router.php:60
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition router.php:42
if(!is_readable( $file)) $ext
Definition router.php:48