MediaWiki  master
ServiceWiring.php
Go to the documentation of this file.
1 <?php
44 use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
120 use MediaWiki\Parser\Parsoid\Config\PageConfigFactory as MWPageConfigFactory;
182 use Wikimedia\ObjectFactory\ObjectFactory;
183 use Wikimedia\Parsoid\Config\Api\DataAccess as ApiDataAccess;
184 use Wikimedia\Parsoid\Config\Api\SiteConfig as ApiSiteConfig;
185 use Wikimedia\Parsoid\Config\DataAccess;
186 use Wikimedia\Parsoid\Config\SiteConfig;
187 use Wikimedia\RequestTimeout\CriticalSectionProvider;
188 use Wikimedia\RequestTimeout\RequestTimeout;
189 use Wikimedia\Services\RecursiveServiceDependencyException;
191 
193 return [
194  'ActionFactory' => static function ( MediaWikiServices $services ): ActionFactory {
195  return new ActionFactory(
196  $services->getMainConfig()->get( MainConfigNames::Actions ),
197  LoggerFactory::getInstance( 'ActionFactory' ),
198  $services->getObjectFactory(),
199  $services->getHookContainer()
200  );
201  },
202 
203  'ActorMigration' => static function ( MediaWikiServices $services ): ActorMigration {
204  return new ActorMigration(
206  $services->getActorStoreFactory()
207  );
208  },
209 
210  'ActorNormalization' => static function ( MediaWikiServices $services ): ActorNormalization {
211  return $services->getActorStoreFactory()->getActorNormalization();
212  },
213 
214  'ActorStore' => static function ( MediaWikiServices $services ): ActorStore {
215  return $services->getActorStoreFactory()->getActorStore();
216  },
217 
218  'ActorStoreFactory' => static function ( MediaWikiServices $services ): ActorStoreFactory {
219  return new ActorStoreFactory(
220  new ServiceOptions( ActorStoreFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
221  $services->getDBLoadBalancerFactory(),
222  $services->getUserNameUtils(),
223  LoggerFactory::getInstance( 'ActorStore' )
224  );
225  },
226 
227  'ArchivedRevisionLookup' => static function ( MediaWikiServices $services ): ArchivedRevisionLookup {
228  return new ArchivedRevisionLookup(
229  $services->getDBLoadBalancer(),
230  $services->getRevisionStore()
231  );
232  },
233 
234  'AuthManager' => static function ( MediaWikiServices $services ): AuthManager {
235  $authManager = new AuthManager(
236  RequestContext::getMain()->getRequest(),
237  $services->getMainConfig(),
238  $services->getObjectFactory(),
239  $services->getHookContainer(),
240  $services->getReadOnlyMode(),
241  $services->getUserNameUtils(),
242  $services->getBlockManager(),
243  $services->getWatchlistManager(),
244  $services->getDBLoadBalancer(),
245  $services->getContentLanguage(),
246  $services->getLanguageConverterFactory(),
247  $services->getBotPasswordStore(),
248  $services->getUserFactory(),
249  $services->getUserIdentityLookup(),
250  $services->getUserOptionsManager()
251  );
252  $authManager->setLogger( LoggerFactory::getInstance( 'authentication' ) );
253  return $authManager;
254  },
255 
256  'BacklinkCacheFactory' => static function ( MediaWikiServices $services ): BacklinkCacheFactory {
257  return new BacklinkCacheFactory( $services->getMainWANObjectCache() );
258  },
259 
260  'BadFileLookup' => static function ( MediaWikiServices $services ): BadFileLookup {
261  return new BadFileLookup(
262  static function () {
263  return wfMessage( 'bad_image_list' )->inContentLanguage()->plain();
264  },
265  $services->getLocalServerObjectCache(),
266  $services->getRepoGroup(),
267  $services->getTitleParser(),
268  $services->getHookContainer()
269  );
270  },
271 
272  'BlobStore' => static function ( MediaWikiServices $services ): BlobStore {
273  return $services->getService( '_SqlBlobStore' );
274  },
275 
276  'BlobStoreFactory' => static function ( MediaWikiServices $services ): BlobStoreFactory {
277  return new BlobStoreFactory(
278  $services->getDBLoadBalancerFactory(),
279  $services->getExternalStoreAccess(),
280  $services->getMainWANObjectCache(),
281  new ServiceOptions( BlobStoreFactory::CONSTRUCTOR_OPTIONS,
282  $services->getMainConfig() )
283  );
284  },
285 
286  'BlockActionInfo' => static function ( MediaWikiServices $services ): BlockActionInfo {
287  return new BlockActionInfo( $services->getHookContainer() );
288  },
289 
290  'BlockErrorFormatter' => static function ( MediaWikiServices $services ): BlockErrorFormatter {
291  return new BlockErrorFormatter(
292  $services->getTitleFormatter()
293  );
294  },
295 
296  'BlockManager' => static function ( MediaWikiServices $services ): BlockManager {
297  return new BlockManager(
298  new ServiceOptions(
299  BlockManager::CONSTRUCTOR_OPTIONS,
300  $services->getMainConfig()
301  ),
302  $services->getPermissionManager(),
303  $services->getUserFactory(),
304  LoggerFactory::getInstance( 'BlockManager' ),
305  $services->getHookContainer()
306  );
307  },
308 
309  'BlockPermissionCheckerFactory' => static function (
310  MediaWikiServices $services
313  new ServiceOptions(
314  BlockPermissionCheckerFactory::CONSTRUCTOR_OPTIONS,
315  $services->getMainConfig()
316  ),
317  $services->getBlockUtils()
318  );
319  },
320 
321  'BlockRestrictionStore' => static function ( MediaWikiServices $services ): BlockRestrictionStore {
322  return $services->getBlockRestrictionStoreFactory()->getBlockRestrictionStore( WikiAwareEntity::LOCAL );
323  },
324 
325  'BlockRestrictionStoreFactory' => static function ( MediaWikiServices $services ): BlockRestrictionStoreFactory {
326  return new BlockRestrictionStoreFactory(
327  $services->getDBLoadBalancerFactory()
328  );
329  },
330 
331  'BlockUserFactory' => static function ( MediaWikiServices $services ): BlockUserFactory {
332  return $services->getService( '_UserBlockCommandFactory' );
333  },
334 
335  'BlockUtils' => static function ( MediaWikiServices $services ): BlockUtils {
336  return new BlockUtils(
337  new ServiceOptions(
338  BlockUtils::CONSTRUCTOR_OPTIONS,
339  $services->getMainConfig()
340  ),
341  $services->getUserIdentityLookup(),
342  $services->getUserNameUtils()
343  );
344  },
345 
346  'BotPasswordStore' => static function ( MediaWikiServices $services ): BotPasswordStore {
347  return new BotPasswordStore(
348  new ServiceOptions(
349  BotPasswordStore::CONSTRUCTOR_OPTIONS,
350  $services->getMainConfig()
351  ),
352  $services->getCentralIdLookup(),
353  $services->getDBLoadBalancerFactory()
354  );
355  },
356 
357  'CentralIdLookup' => static function ( MediaWikiServices $services ): CentralIdLookup {
358  return $services->getCentralIdLookupFactory()->getLookup();
359  },
360 
361  'CentralIdLookupFactory' => static function ( MediaWikiServices $services ): CentralIdLookupFactory {
362  return new CentralIdLookupFactory(
363  new ServiceOptions( CentralIdLookupFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
364  $services->getObjectFactory(),
365  $services->getUserIdentityLookup()
366  );
367  },
368 
369  'ChangeTagDefStore' => static function ( MediaWikiServices $services ): NameTableStore {
370  return $services->getNameTableStoreFactory()->getChangeTagDef();
371  },
372 
373  'CollationFactory' => static function ( MediaWikiServices $services ): CollationFactory {
374  return new CollationFactory(
375  new ServiceOptions(
376  CollationFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
377  $services->getObjectFactory(),
378  $services->getHookContainer()
379  );
380  },
381 
382  'CommentFormatter' => static function ( MediaWikiServices $services ): CommentFormatter {
383  $linkRenderer = $services->getLinkRendererFactory()->create( [ 'renderForComment' => true ] );
384  $parserFactory = new CommentParserFactory(
385  $linkRenderer,
386  $services->getLinkBatchFactory(),
387  $services->getLinkCache(),
388  $services->getRepoGroup(),
389  RequestContext::getMain()->getLanguage(),
390  $services->getContentLanguage(),
391  $services->getTitleParser(),
392  $services->getNamespaceInfo(),
393  $services->getHookContainer()
394  );
395  return new CommentFormatter( $parserFactory );
396  },
397 
398  'CommentStore' => static function ( MediaWikiServices $services ): CommentStore {
399  return new CommentStore(
400  $services->getContentLanguage(),
402  );
403  },
404 
405  'ConfigFactory' => static function ( MediaWikiServices $services ): ConfigFactory {
406  // Use the bootstrap config to initialize the ConfigFactory.
407  $registry = $services->getBootstrapConfig()->get( MainConfigNames::ConfigRegistry );
408  $factory = new ConfigFactory();
409 
410  foreach ( $registry as $name => $callback ) {
411  $factory->register( $name, $callback );
412  }
413  return $factory;
414  },
415 
416  'ConfigRepository' => static function ( MediaWikiServices $services ): ConfigRepository {
417  return new ConfigRepository( $services->getConfigFactory() );
418  },
419 
420  'ConfigSchema' => static function ( MediaWikiServices $services ): ConfigSchema {
421  global $wgSettings; // TODO: have Setup.php declare this service
422  return $wgSettings->getConfigSchema();
423  },
424 
425  'ConfiguredReadOnlyMode' => static function ( MediaWikiServices $services ): ConfiguredReadOnlyMode {
426  $config = $services->getMainConfig();
427  return new ConfiguredReadOnlyMode(
428  $config->get( MainConfigNames::ReadOnly ),
429  $config->get( MainConfigNames::ReadOnlyFile )
430  );
431  },
432 
433  'ContentHandlerFactory' => static function ( MediaWikiServices $services ): IContentHandlerFactory {
434  $contentHandlerConfig = $services->getMainConfig()->get( MainConfigNames::ContentHandlers );
435 
436  return new ContentHandlerFactory(
437  $contentHandlerConfig,
438  $services->getObjectFactory(),
439  $services->getHookContainer(),
440  LoggerFactory::getInstance( 'ContentHandler' )
441  );
442  },
443 
444  'ContentLanguage' => static function ( MediaWikiServices $services ): Language {
445  return $services->getLanguageFactory()->getLanguage(
446  $services->getMainConfig()->get( MainConfigNames::LanguageCode ) );
447  },
448 
449  'ContentModelChangeFactory' => static function ( MediaWikiServices $services ): ContentModelChangeFactory {
450  return $services->getService( '_PageCommandFactory' );
451  },
452 
453  'ContentModelStore' => static function ( MediaWikiServices $services ): NameTableStore {
454  return $services->getNameTableStoreFactory()->getContentModels();
455  },
456 
457  'ContentRenderer' => static function ( MediaWikiServices $services ): ContentRenderer {
458  return new ContentRenderer( $services->getContentHandlerFactory() );
459  },
460 
461  'ContentTransformer' => static function ( MediaWikiServices $services ): ContentTransformer {
462  return new ContentTransformer( $services->getContentHandlerFactory() );
463  },
464 
465  'ContributionsLookup' => static function ( MediaWikiServices $services ): ContributionsLookup {
466  return new ContributionsLookup(
467  $services->getRevisionStore(),
468  $services->getLinkRendererFactory(),
469  $services->getLinkBatchFactory(),
470  $services->getHookContainer(),
471  $services->getDBLoadBalancer(),
472  $services->getActorMigration(),
473  $services->getNamespaceInfo(),
474  $services->getCommentFormatter()
475  );
476  },
477 
478  'CriticalSectionProvider' => static function ( MediaWikiServices $services ): CriticalSectionProvider {
479  $config = $services->getMainConfig();
480  $limit = $GLOBALS[ 'wgCommandLineMode' ] ? INF : $config->get( MainConfigNames::CriticalSectionTimeLimit );
481  return RequestTimeout::singleton()->createCriticalSectionProvider( $limit );
482  },
483 
484  'CryptHKDF' => static function ( MediaWikiServices $services ): CryptHKDF {
485  $config = $services->getMainConfig();
486 
487  $secret = $config->get( MainConfigNames::HKDFSecret ) ?: $config->get( MainConfigNames::SecretKey );
488  if ( !$secret ) {
489  throw new RuntimeException( "Cannot use MWCryptHKDF without a secret." );
490  }
491 
492  // In HKDF, the context can be known to the attacker, but this will
493  // keep simultaneous runs from producing the same output.
494  $context = [ microtime(), getmypid(), gethostname() ];
495 
496  // Setup salt cache. Use APC, or fallback to the main cache if it isn't setup
497  $cache = $services->getLocalServerObjectCache();
498  if ( $cache instanceof EmptyBagOStuff ) {
500  }
501 
502  return new CryptHKDF( $secret, $config->get( MainConfigNames::HKDFAlgorithm ), $cache, $context );
503  },
504 
505  'DatabaseBlockStore' => static function ( MediaWikiServices $services ): DatabaseBlockStore {
506  return new DatabaseBlockStore(
507  new ServiceOptions(
508  DatabaseBlockStore::CONSTRUCTOR_OPTIONS,
509  $services->getMainConfig()
510  ),
511  LoggerFactory::getInstance( 'DatabaseBlockStore' ),
512  $services->getActorStoreFactory(),
513  $services->getBlockRestrictionStore(),
514  $services->getCommentStore(),
515  $services->getHookContainer(),
516  $services->getDBLoadBalancer(),
517  $services->getReadOnlyMode(),
518  $services->getUserFactory()
519  );
520  },
521 
522  'DateFormatterFactory' => static function ( MediaWikiServices $services ): DateFormatterFactory {
523  return new DateFormatterFactory();
524  },
525 
526  'DBLoadBalancer' => static function ( MediaWikiServices $services ): Wikimedia\Rdbms\ILoadBalancer {
527  // just return the default LB from the DBLoadBalancerFactory service
528  return $services->getDBLoadBalancerFactory()->getMainLB();
529  },
530 
531  'DBLoadBalancerFactory' =>
532  static function ( MediaWikiServices $services ): Wikimedia\Rdbms\LBFactory {
533  $mainConfig = $services->getMainConfig();
534 
535  $cpStashType = $mainConfig->get( MainConfigNames::ChronologyProtectorStash );
536  if ( is_string( $cpStashType ) ) {
537  $cpStash = ObjectCache::getInstance( $cpStashType );
538  } else {
539  try {
541  } catch ( RecursiveServiceDependencyException $e ) {
542  $cpStash = new EmptyBagOStuff(); // T141804: handle cases like CACHE_DB
543  }
544  }
545 
546  try {
547  $wanCache = $services->getMainWANObjectCache();
548  } catch ( RecursiveServiceDependencyException $e ) {
549  $wanCache = WANObjectCache::newEmpty(); // T141804: handle cases like CACHE_DB
550  }
551 
552  $srvCache = $services->getLocalServerObjectCache();
553  if ( $srvCache instanceof EmptyBagOStuff ) {
554  // Use process cache if no APCU or other local-server cache (e.g. on CLI)
555  $srvCache = new HashBagOStuff( [ 'maxKeys' => 100 ] );
556  }
557 
559  $mainConfig->get( MainConfigNames::LBFactoryConf ),
561  $services->getConfiguredReadOnlyMode(),
562  $cpStash,
563  $srvCache,
564  $wanCache,
565  $services->getCriticalSectionProvider()
566  );
567 
568  $class = MWLBFactory::getLBFactoryClass( $lbConf );
569  $instance = new $class( $lbConf );
570 
571  MWLBFactory::setDomainAliases( $instance );
572 
573  // NOTE: This accesses ProxyLookup from the MediaWikiServices singleton
574  // for non-essential non-nonimal purposes (via WebRequest::getIP).
575  // This state is fine (and meant) to be consistent for a given PHP process,
576  // even if applied to the service container for a different wiki.
578  $instance,
579  $mainConfig,
580  $services->getStatsdDataFactory()
581  );
582 
583  return $instance;
584  },
585 
586  'DeletePageFactory' => static function ( MediaWikiServices $services ): DeletePageFactory {
587  return $services->getService( '_PageCommandFactory' );
588  },
589 
590  'Emailer' => static function ( MediaWikiServices $services ): IEmailer {
591  return new Emailer();
592  },
593 
594  'EventRelayerGroup' => static function ( MediaWikiServices $services ): EventRelayerGroup {
595  return new EventRelayerGroup( $services->getMainConfig()->get( MainConfigNames::EventRelayerConfig ) );
596  },
597 
598  'ExternalStoreAccess' => static function ( MediaWikiServices $services ): ExternalStoreAccess {
599  return new ExternalStoreAccess(
600  $services->getExternalStoreFactory(),
601  LoggerFactory::getInstance( 'ExternalStore' )
602  );
603  },
604 
605  'ExternalStoreFactory' => static function ( MediaWikiServices $services ): ExternalStoreFactory {
606  $config = $services->getMainConfig();
607  $writeStores = $config->get( MainConfigNames::DefaultExternalStore );
608 
609  return new ExternalStoreFactory(
610  $config->get( MainConfigNames::ExternalStores ),
611  ( $writeStores !== false ) ? (array)$writeStores : [],
612  $services->getDBLoadBalancer()->getLocalDomainID(),
613  LoggerFactory::getInstance( 'ExternalStore' )
614  );
615  },
616 
617  'FileBackendGroup' => static function ( MediaWikiServices $services ): FileBackendGroup {
618  $mainConfig = $services->getMainConfig();
619 
621  $fallbackWikiId = WikiMap::getWikiIdFromDbDomain( $ld );
622  // If the local wiki ID and local domain ID do not match, probably due to a non-default
623  // schema, issue a warning. A non-default schema indicates that it might be used to
624  // disambiguate different wikis.
625  $legacyDomainId = strlen( $ld->getTablePrefix() )
626  ? "{$ld->getDatabase()}-{$ld->getTablePrefix()}"
627  : $ld->getDatabase();
628  if ( $ld->getSchema() !== null && $legacyDomainId !== $fallbackWikiId ) {
629  wfWarn(
630  "Legacy default 'domainId' is '$legacyDomainId' but wiki ID is '$fallbackWikiId'."
631  );
632  }
633 
634  $cache = $services->getLocalServerObjectCache();
635  if ( $cache instanceof EmptyBagOStuff ) {
636  $cache = new HashBagOStuff();
637  }
638 
639  return new FileBackendGroup(
641  [ 'fallbackWikiId' => $fallbackWikiId ] ),
642  $services->getConfiguredReadOnlyMode(),
643  $cache,
644  $services->getMainWANObjectCache(),
645  $services->getMimeAnalyzer(),
646  $services->getLockManagerGroupFactory(),
647  $services->getTempFSFileFactory(),
648  $services->getObjectFactory()
649  );
650  },
651 
652  'GenderCache' => static function ( MediaWikiServices $services ): GenderCache {
653  $nsInfo = $services->getNamespaceInfo();
654  // Database layer may be disabled, so processing without database connection
655  $dbLoadBalancer = $services->isServiceDisabled( 'DBLoadBalancer' )
656  ? null
657  : $services->getDBLoadBalancer();
658  return new GenderCache( $nsInfo, $dbLoadBalancer, $services->get( '_DefaultOptionsLookup' ) );
659  },
660 
661  'GlobalIdGenerator' => static function ( MediaWikiServices $services ): GlobalIdGenerator {
662  $mainConfig = $services->getMainConfig();
663 
664  return new GlobalIdGenerator(
665  $mainConfig->get( MainConfigNames::TmpDirectory ),
666  static function ( $command ) {
667  return wfShellExec( $command );
668  }
669  );
670  },
671 
672  'GrantsInfo' => static function ( MediaWikiServices $services ): GrantsInfo {
673  return new GrantsInfo(
674  new ServiceOptions(
675  GrantsInfo::CONSTRUCTOR_OPTIONS,
676  $services->getMainConfig()
677  )
678  );
679  },
680 
681  'GrantsLocalization' => static function ( MediaWikiServices $services ): GrantsLocalization {
682  return new GrantsLocalization(
683  $services->getGrantsInfo(),
684  $services->getLinkRenderer(),
685  $services->getLanguageFactory(),
686  $services->getContentLanguage()
687  );
688  },
689 
690  'GroupPermissionsLookup' => static function ( MediaWikiServices $services ): GroupPermissionsLookup {
691  return new GroupPermissionsLookup(
692  new ServiceOptions( GroupPermissionsLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig() )
693  );
694  },
695 
696  'HookContainer' => static function ( MediaWikiServices $services ): HookContainer {
697  $extRegistry = ExtensionRegistry::getInstance();
698  $extDeprecatedHooks = $extRegistry->getAttribute( 'DeprecatedHooks' );
699  $deprecatedHooks = new DeprecatedHooks( $extDeprecatedHooks );
700  $hookRegistry = new GlobalHookRegistry( $extRegistry, $deprecatedHooks );
701  return new HookContainer(
702  $hookRegistry,
703  $services->getObjectFactory()
704  );
705  },
706 
707  'HtmlCacheUpdater' => static function ( MediaWikiServices $services ): HtmlCacheUpdater {
708  $config = $services->getMainConfig();
709 
710  return new HtmlCacheUpdater(
711  $services->getHookContainer(),
712  $services->getTitleFactory(),
713  $config->get( MainConfigNames::CdnReboundPurgeDelay ),
714  $config->get( MainConfigNames::UseFileCache ),
715  $config->get( MainConfigNames::CdnMaxAge )
716  );
717  },
718 
719  'HttpRequestFactory' =>
720  static function ( MediaWikiServices $services ): HttpRequestFactory {
721  return new HttpRequestFactory(
722  new ServiceOptions(
723  HttpRequestFactory::CONSTRUCTOR_OPTIONS,
724  $services->getMainConfig()
725  ),
726  LoggerFactory::getInstance( 'http' )
727  );
728  },
729 
730  'InterwikiLookup' => static function ( MediaWikiServices $services ): InterwikiLookup {
731  $config = $services->getMainConfig();
732  return new ClassicInterwikiLookup(
733  $services->getContentLanguage(),
734  $services->getMainWANObjectCache(),
735  $services->getHookContainer(),
736  $services->getDBLoadBalancer(),
737  $config->get( MainConfigNames::InterwikiExpiry ),
738  $config->get( MainConfigNames::InterwikiCache ),
739  $config->get( MainConfigNames::InterwikiScopes ),
740  $config->get( MainConfigNames::InterwikiFallbackSite )
741  );
742  },
743 
744  'JobQueueGroup' => static function ( MediaWikiServices $services ): JobQueueGroup {
745  return $services->getJobQueueGroupFactory()->makeJobQueueGroup();
746  },
747 
748  'JobQueueGroupFactory' => static function ( MediaWikiServices $services ): JobQueueGroupFactory {
749  return new JobQueueGroupFactory(
750  new ServiceOptions( JobQueueGroupFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
751  $services->getConfiguredReadOnlyMode(),
752  $services->getStatsdDataFactory(),
753  $services->getMainWANObjectCache(),
754  $services->getGlobalIdGenerator()
755  );
756  },
757 
758  'JobRunner' => static function ( MediaWikiServices $services ): JobRunner {
759  return new JobRunner(
760  new ServiceOptions( JobRunner::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
761  $services->getDBLoadBalancerFactory(),
762  $services->getJobQueueGroup(),
763  $services->getReadOnlyMode(),
764  $services->getLinkCache(),
765  $services->getStatsdDataFactory(),
766  LoggerFactory::getInstance( 'runJobs' )
767  );
768  },
769 
770  'JsonCodec' => static function ( MediaWikiServices $services ): JsonCodec {
771  return new JsonCodec();
772  },
773 
774  'LanguageConverterFactory' => static function ( MediaWikiServices $services ): LanguageConverterFactory {
775  $usePigLatinVariant = $services->getMainConfig()->get( MainConfigNames::UsePigLatinVariant );
776  $isConversionDisabled = $services->getMainConfig()->get( MainConfigNames::DisableLangConversion );
777  $isTitleConversionDisabled = $services->getMainConfig()->get( MainConfigNames::DisableTitleConversion );
778  return new LanguageConverterFactory(
779  $services->getObjectFactory(),
780  $usePigLatinVariant,
781  $isConversionDisabled,
782  $isTitleConversionDisabled,
783  static function () use ( $services ) {
784  return $services->getContentLanguage();
785  }
786  );
787  },
788 
789  'LanguageFactory' => static function ( MediaWikiServices $services ): LanguageFactory {
790  return new LanguageFactory(
791  new ServiceOptions( LanguageFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
792  $services->getNamespaceInfo(),
793  $services->getLocalisationCache(),
794  $services->getLanguageNameUtils(),
795  $services->getLanguageFallback(),
796  $services->getLanguageConverterFactory(),
797  $services->getHookContainer(),
798  $services->getMainConfig()
799  );
800  },
801 
802  'LanguageFallback' => static function ( MediaWikiServices $services ): LanguageFallback {
803  return new LanguageFallback(
804  $services->getMainConfig()->get( MainConfigNames::LanguageCode ),
805  $services->getLocalisationCache(),
806  $services->getLanguageNameUtils()
807  );
808  },
809 
810  'LanguageNameUtils' => static function ( MediaWikiServices $services ): LanguageNameUtils {
811  return new LanguageNameUtils(
812  new ServiceOptions(
813  LanguageNameUtils::CONSTRUCTOR_OPTIONS,
814  $services->getMainConfig()
815  ),
816  $services->getHookContainer()
817  );
818  },
819 
820  'LinkBatchFactory' => static function ( MediaWikiServices $services ): LinkBatchFactory {
821  return new LinkBatchFactory(
822  $services->getLinkCache(),
823  $services->getTitleFormatter(),
824  $services->getContentLanguage(),
825  $services->getGenderCache(),
826  $services->getDBLoadBalancer(),
827  $services->getLinksMigration(),
828  LoggerFactory::getInstance( 'LinkBatch' )
829  );
830  },
831 
832  'LinkCache' => static function ( MediaWikiServices $services ): LinkCache {
833  // Database layer may be disabled, so processing without database connection
834  $dbLoadBalancer = $services->isServiceDisabled( 'DBLoadBalancer' )
835  ? null
836  : $services->getDBLoadBalancer();
837  $linkCache = new LinkCache(
838  $services->getTitleFormatter(),
839  $services->getMainWANObjectCache(),
840  $services->getNamespaceInfo(),
841  $dbLoadBalancer
842  );
843  $linkCache->setLogger( LoggerFactory::getInstance( 'LinkCache' ) );
844  return $linkCache;
845  },
846 
847  'LinkRenderer' => static function ( MediaWikiServices $services ): LinkRenderer {
848  return $services->getLinkRendererFactory()->create();
849  },
850 
851  'LinkRendererFactory' => static function ( MediaWikiServices $services ): LinkRendererFactory {
852  return new LinkRendererFactory(
853  $services->getTitleFormatter(),
854  $services->getLinkCache(),
855  $services->getSpecialPageFactory(),
856  $services->getHookContainer()
857  );
858  },
859 
860  'LinksMigration' => static function ( MediaWikiServices $services ): LinksMigration {
861  return new LinksMigration(
862  $services->getMainConfig(),
863  $services->getLinkTargetLookup()
864  );
865  },
866 
867  'LinkTargetLookup' => static function ( MediaWikiServices $services ): LinkTargetLookup {
868  return new LinkTargetStore(
869  $services->getDBLoadBalancer(),
870  $services->getLocalServerObjectCache(),
871  $services->getMainWANObjectCache()
872  );
873  },
874 
875  'LocalisationCache' => static function ( MediaWikiServices $services ): LocalisationCache {
876  $conf = $services->getMainConfig()->get( MainConfigNames::LocalisationCacheConf );
877 
878  $logger = LoggerFactory::getInstance( 'localisation' );
879 
881  $conf, $services->getMainConfig()->get( MainConfigNames::CacheDirectory ) );
882  $logger->debug( 'LocalisationCache using store ' . get_class( $store ) );
883 
884  return new $conf['class'](
885  new ServiceOptions(
887  // Two of the options are stored in $wgLocalisationCacheConf
888  $conf,
889  // In case someone set that config variable and didn't reset all keys, set defaults.
890  [
891  'forceRecache' => false,
892  'manualRecache' => false,
893  ],
894  // Some other options come from config itself
895  $services->getMainConfig()
896  ),
897  $store,
898  $logger,
899  [ static function () use ( $services ) {
900  // NOTE: Make sure we use the same cache object that is assigned in the
901  // constructor of the MessageBlobStore class used by ResourceLoader.
902  // T231866: Avoid circular dependency via ResourceLoader.
903  MessageBlobStore::clearGlobalCacheEntry( $services->getMainWANObjectCache() );
904  } ],
905  $services->getLanguageNameUtils(),
906  $services->getHookContainer()
907  );
908  },
909 
910  'LocalServerObjectCache' => static function ( MediaWikiServices $services ): BagOStuff {
912  },
913 
914  'LockManagerGroupFactory' => static function ( MediaWikiServices $services ): LockManagerGroupFactory {
915  return new LockManagerGroupFactory(
917  $services->getMainConfig()->get( MainConfigNames::LockManagers ),
918  $services->getDBLoadBalancerFactory()
919  );
920  },
921 
922  'MagicWordFactory' => static function ( MediaWikiServices $services ): MagicWordFactory {
923  return new MagicWordFactory(
924  $services->getContentLanguage(),
925  $services->getHookContainer()
926  );
927  },
928 
929  'MainConfig' => static function ( MediaWikiServices $services ): Config {
930  // Use the 'main' config from the ConfigFactory service.
931  return $services->getConfigFactory()->makeConfig( 'main' );
932  },
933 
934  'MainObjectStash' => static function ( MediaWikiServices $services ): BagOStuff {
935  $mainConfig = $services->getMainConfig();
936 
937  $id = $mainConfig->get( MainConfigNames::MainStash );
938  $params = $mainConfig->get( MainConfigNames::ObjectCaches )[$id] ?? null;
939  if ( !$params ) {
940  throw new UnexpectedValueException(
941  "\$wgObjectCaches must have \"$id\" set (via \$wgMainStash)"
942  );
943  }
944 
945  $params['stats'] = $services->getStatsdDataFactory();
946 
947  $store = ObjectCache::newFromParams( $params, $mainConfig );
948  $store->getLogger()->debug( 'MainObjectStash using store {class}', [
949  'class' => get_class( $store )
950  ] );
951 
952  return $store;
953  },
954 
955  'MainWANObjectCache' => static function ( MediaWikiServices $services ): WANObjectCache {
956  $mainConfig = $services->getMainConfig();
957 
958  $wanId = $mainConfig->get( MainConfigNames::MainWANCache );
959  $wanParams = $mainConfig->get( MainConfigNames::WANObjectCaches )[$wanId] ?? null;
960  if ( !$wanParams ) {
961  throw new UnexpectedValueException(
962  "wgWANObjectCaches must have \"$wanId\" set (via wgMainWANCache)"
963  );
964  }
965 
966  $cacheId = $wanParams['cacheId'];
967  $wanClass = $wanParams['class'];
968  unset( $wanParams['cacheId'] );
969  unset( $wanParams['class'] );
970 
971  $storeParams = $mainConfig->get( MainConfigNames::ObjectCaches )[$cacheId] ?? null;
972  if ( !$storeParams ) {
973  throw new UnexpectedValueException(
974  "wgObjectCaches must have \"$cacheId\" set (via wgWANObjectCaches)"
975  );
976  }
977  $storeParams['stats'] = $services->getStatsdDataFactory();
978  $store = ObjectCache::newFromParams( $storeParams, $mainConfig );
979  $logger = $store->getLogger();
980  $logger->debug( 'MainWANObjectCache using store {class}', [
981  'class' => get_class( $store )
982  ] );
983 
984  $wanParams['cache'] = $store;
985  $wanParams['logger'] = $logger;
986  $wanParams['secret'] = $wanParams['secret'] ?? $mainConfig->get( MainConfigNames::SecretKey );
987  if ( !$GLOBALS[ 'wgCommandLineMode' ] ) {
988  // Send the statsd data post-send on HTTP requests; avoid in CLI mode (T181385)
989  $wanParams['stats'] = $services->getStatsdDataFactory();
990  // Let pre-emptive refreshes happen post-send on HTTP requests
991  $wanParams['asyncHandler'] = [ DeferredUpdates::class, 'addCallableUpdate' ];
992  }
993 
994  $instance = new $wanClass( $wanParams );
995 
996  '@phan-var WANObjectCache $instance';
997  return $instance;
998  },
999 
1000  'MediaHandlerFactory' => static function ( MediaWikiServices $services ): MediaHandlerFactory {
1001  return new MediaHandlerFactory(
1002  LoggerFactory::getInstance( 'MediaHandlerFactory' ),
1003  $services->getMainConfig()->get( MainConfigNames::MediaHandlers )
1004  );
1005  },
1006 
1007  'MergeHistoryFactory' => static function ( MediaWikiServices $services ): MergeHistoryFactory {
1008  return $services->getService( '_PageCommandFactory' );
1009  },
1010 
1011  'MessageCache' => static function ( MediaWikiServices $services ): MessageCache {
1012  $mainConfig = $services->getMainConfig();
1013  $clusterCache = ObjectCache::getInstance( $mainConfig->get( MainConfigNames::MessageCacheType ) );
1014  $srvCache = $mainConfig->get( MainConfigNames::UseLocalMessageCache )
1015  ? $services->getLocalServerObjectCache()
1016  : new EmptyBagOStuff();
1017 
1018  $logger = LoggerFactory::getInstance( 'MessageCache' );
1019  $logger->debug( 'MessageCache using store {class}', [
1020  'class' => get_class( $clusterCache )
1021  ] );
1022 
1023  return new MessageCache(
1024  $services->getMainWANObjectCache(),
1025  $clusterCache,
1026  $srvCache,
1027  $services->getContentLanguage(),
1028  $services->getLanguageConverterFactory(),
1029  $logger,
1030  [ 'useDB' => $mainConfig->get( MainConfigNames::UseDatabaseMessages ) ],
1031  $services->getLanguageFactory(),
1032  $services->getLocalisationCache(),
1033  $services->getLanguageNameUtils(),
1034  $services->getLanguageFallback(),
1035  $services->getHookContainer()
1036  );
1037  },
1038 
1039  'MessageFormatterFactory' => static function ( MediaWikiServices $services ): IMessageFormatterFactory {
1040  return new MessageFormatterFactory();
1041  },
1042 
1043  'MetricsFactory' => static function ( MediaWikiServices $services ): MetricsFactory {
1044  $config = $services->getMainConfig();
1045  return new MetricsFactory(
1046  [
1047  'target' => $config->get( MainConfigNames::MetricsTarget ),
1048  'format' => $config->get( MainConfigNames::MetricsFormat ),
1049  'prefix' => $config->get( MainConfigNames::MetricsPrefix ),
1050  ],
1051  LoggerFactory::getInstance( 'Metrics' )
1052  );
1053  },
1054 
1055  'MimeAnalyzer' => static function ( MediaWikiServices $services ): MimeAnalyzer {
1056  $logger = LoggerFactory::getInstance( 'Mime' );
1057  $mainConfig = $services->getMainConfig();
1058  $hookRunner = new HookRunner( $services->getHookContainer() );
1059  $params = [
1060  'typeFile' => $mainConfig->get( MainConfigNames::MimeTypeFile ),
1061  'infoFile' => $mainConfig->get( MainConfigNames::MimeInfoFile ),
1062  'xmlTypes' => $mainConfig->get( MainConfigNames::XMLMimeTypes ),
1063  'guessCallback' =>
1064  static function ( $mimeAnalyzer, &$head, &$tail, $file, &$mime )
1065  use ( $logger, $hookRunner ) {
1066  // Also test DjVu
1067  $deja = new DjVuImage( $file );
1068  if ( $deja->isValid() ) {
1069  $logger->info( "Detected $file as image/vnd.djvu\n" );
1070  $mime = 'image/vnd.djvu';
1071 
1072  return;
1073  }
1074  // Some strings by reference for performance - assuming well-behaved hooks
1075  $hookRunner->onMimeMagicGuessFromContent(
1076  $mimeAnalyzer, $head, $tail, $file, $mime );
1077  },
1078  'extCallback' => static function ( $mimeAnalyzer, $ext, &$mime ) use ( $hookRunner ) {
1079  // Media handling extensions can improve the MIME detected
1080  $hookRunner->onMimeMagicImproveFromExtension( $mimeAnalyzer, $ext, $mime );
1081  },
1082  'initCallback' => static function ( $mimeAnalyzer ) use ( $hookRunner ) {
1083  // Allow media handling extensions adding MIME-types and MIME-info
1084  $hookRunner->onMimeMagicInit( $mimeAnalyzer );
1085  },
1086  'logger' => $logger
1087  ];
1088 
1089  if ( $params['infoFile'] === 'includes/mime.info' ) {
1090  $params['infoFile'] = MimeAnalyzer::USE_INTERNAL;
1091  }
1092 
1093  if ( $params['typeFile'] === 'includes/mime.types' ) {
1094  $params['typeFile'] = MimeAnalyzer::USE_INTERNAL;
1095  }
1096 
1097  $detectorCmd = $mainConfig->get( MainConfigNames::MimeDetectorCommand );
1098  if ( $detectorCmd ) {
1099  $factory = $services->getShellCommandFactory();
1100  $params['detectCallback'] = static function ( $file ) use ( $detectorCmd, $factory ) {
1101  $result = $factory->create()
1102  // $wgMimeDetectorCommand can contain commands with parameters
1103  ->unsafeParams( $detectorCmd )
1104  ->params( $file )
1105  ->execute();
1106  return $result->getStdout();
1107  };
1108  }
1109 
1110  return new MimeAnalyzer( $params );
1111  },
1112 
1113  'MovePageFactory' => static function ( MediaWikiServices $services ): MovePageFactory {
1114  return $services->getService( '_PageCommandFactory' );
1115  },
1116 
1117  'NamespaceInfo' => static function ( MediaWikiServices $services ): NamespaceInfo {
1118  return new NamespaceInfo(
1119  new ServiceOptions( NamespaceInfo::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1120  $services->getHookContainer()
1121  );
1122  },
1123 
1124  'NameTableStoreFactory' => static function ( MediaWikiServices $services ): NameTableStoreFactory {
1125  return new NameTableStoreFactory(
1126  $services->getDBLoadBalancerFactory(),
1127  $services->getMainWANObjectCache(),
1128  LoggerFactory::getInstance( 'NameTableSqlStore' )
1129  );
1130  },
1131 
1132  'ObjectFactory' => static function ( MediaWikiServices $services ): ObjectFactory {
1133  return new ObjectFactory( $services );
1134  },
1135 
1136  'OldRevisionImporter' => static function ( MediaWikiServices $services ): OldRevisionImporter {
1137  return new ImportableOldRevisionImporter(
1138  true,
1139  LoggerFactory::getInstance( 'OldRevisionImporter' ),
1140  $services->getDBLoadBalancer(),
1141  $services->getRevisionStore(),
1142  $services->getSlotRoleRegistry(),
1143  $services->getWikiPageFactory(),
1144  $services->getPageUpdaterFactory(),
1145  $services->getUserFactory()
1146  );
1147  },
1148 
1149  'PageEditStash' => static function ( MediaWikiServices $services ): PageEditStash {
1150  $config = $services->getMainConfig();
1151 
1152  return new PageEditStash(
1154  $services->getDBLoadBalancer(),
1155  LoggerFactory::getInstance( 'StashEdit' ),
1156  $services->getStatsdDataFactory(),
1157  $services->getUserEditTracker(),
1158  $services->getUserFactory(),
1159  $services->getWikiPageFactory(),
1160  $services->getHookContainer(),
1161  defined( 'MEDIAWIKI_JOB_RUNNER' ) || $GLOBALS[ 'wgCommandLineMode' ]
1162  ? PageEditStash::INITIATOR_JOB_OR_CLI
1163  : PageEditStash::INITIATOR_USER
1164  );
1165  },
1166 
1167  'PageProps' => static function ( MediaWikiServices $services ): PageProps {
1168  return new PageProps(
1169  $services->getLinkBatchFactory(),
1170  $services->getDBLoadBalancer()
1171  );
1172  },
1173 
1174  'PageStore' => static function ( MediaWikiServices $services ): PageStore {
1175  return $services->getPageStoreFactory()->getPageStore();
1176  },
1177 
1178  'PageStoreFactory' => static function ( MediaWikiServices $services ): PageStoreFactory {
1179  $options = new ServiceOptions(
1180  PageStoreFactory::CONSTRUCTOR_OPTIONS,
1181  $services->getMainConfig()
1182  );
1183 
1184  return new PageStoreFactory(
1185  $options,
1186  $services->getDBLoadBalancerFactory(),
1187  $services->getNamespaceInfo(),
1188  $services->getTitleParser(),
1189  $services->getLinkCache(),
1190  $services->getStatsdDataFactory()
1191  );
1192  },
1193 
1194  'PageUpdaterFactory' => static function (
1195  MediaWikiServices $services
1196  ): PageUpdaterFactory {
1197  $editResultCache = new EditResultCache(
1198  $services->getMainObjectStash(),
1199  $services->getDBLoadBalancer(),
1200  new ServiceOptions(
1201  EditResultCache::CONSTRUCTOR_OPTIONS,
1202  $services->getMainConfig()
1203  )
1204  );
1205 
1206  return new PageUpdaterFactory(
1207  $services->getRevisionStore(),
1208  $services->getRevisionRenderer(),
1209  $services->getSlotRoleRegistry(),
1210  $services->getParserCache(),
1211  $services->getJobQueueGroup(),
1212  $services->getMessageCache(),
1213  $services->getContentLanguage(),
1214  $services->getDBLoadBalancerFactory(),
1215  $services->getContentHandlerFactory(),
1216  $services->getHookContainer(),
1217  $editResultCache,
1218  $services->getUserNameUtils(),
1219  LoggerFactory::getInstance( 'SavePage' ),
1220  new ServiceOptions(
1221  PageUpdaterFactory::CONSTRUCTOR_OPTIONS,
1222  $services->getMainConfig()
1223  ),
1224  $services->getUserEditTracker(),
1225  $services->getUserGroupManager(),
1226  $services->getTitleFormatter(),
1227  $services->getContentTransformer(),
1228  $services->getPageEditStash(),
1229  $services->getTalkPageNotificationManager(),
1230  $services->getMainWANObjectCache(),
1231  $services->getPermissionManager(),
1232  $services->getWikiPageFactory(),
1234  );
1235  },
1236 
1237  'Parser' => static function ( MediaWikiServices $services ): Parser {
1238  return $services->getParserFactory()->create();
1239  },
1240 
1241  'ParserCache' => static function ( MediaWikiServices $services ): ParserCache {
1242  return $services->getParserCacheFactory()
1243  ->getParserCache( ParserCacheFactory::DEFAULT_NAME );
1244  },
1245 
1246  'ParserCacheFactory' => static function ( MediaWikiServices $services ): ParserCacheFactory {
1247  $config = $services->getMainConfig();
1248  $cache = ObjectCache::getInstance( $config->get( MainConfigNames::ParserCacheType ) );
1249  $wanCache = $services->getMainWANObjectCache();
1250 
1251  $options = new ServiceOptions( ParserCacheFactory::CONSTRUCTOR_OPTIONS, $config );
1252 
1253  return new ParserCacheFactory(
1254  $cache,
1255  $wanCache,
1256  $services->getHookContainer(),
1257  $services->getJsonCodec(),
1258  $services->getStatsdDataFactory(),
1259  LoggerFactory::getInstance( 'ParserCache' ),
1260  $options,
1261  $services->getTitleFactory(),
1262  $services->getWikiPageFactory()
1263  );
1264  },
1265 
1266  'ParserFactory' => static function ( MediaWikiServices $services ): ParserFactory {
1268  $services->getMainConfig()
1269  );
1270 
1271  return new ParserFactory(
1272  $options,
1273  $services->getMagicWordFactory(),
1274  $services->getContentLanguage(),
1275  $services->getUrlUtils(),
1276  $services->getSpecialPageFactory(),
1277  $services->getLinkRendererFactory(),
1278  $services->getNamespaceInfo(),
1279  LoggerFactory::getInstance( 'Parser' ),
1280  $services->getBadFileLookup(),
1281  $services->getLanguageConverterFactory(),
1282  $services->getHookContainer(),
1283  $services->getTidy(),
1284  $services->getMainWANObjectCache(),
1285  $services->getUserOptionsLookup(),
1286  $services->getUserFactory(),
1287  $services->getTitleFormatter(),
1288  $services->getHttpRequestFactory(),
1289  $services->getTrackingCategories(),
1290  $services->getSignatureValidatorFactory(),
1291  $services->getUserNameUtils()
1292  );
1293  },
1294 
1295  'ParserOutputAccess' => static function ( MediaWikiServices $services ): ParserOutputAccess {
1296  return new ParserOutputAccess(
1297  $services->getParserCache(),
1298  $services->getParserCacheFactory()->getRevisionOutputCache( 'rcache' ),
1299  $services->getRevisionLookup(),
1300  $services->getRevisionRenderer(),
1301  $services->getStatsdDataFactory(),
1302  $services->getDBLoadBalancerFactory(),
1303  LoggerFactory::getProvider(),
1304  $services->getWikiPageFactory(),
1305  $services->getTitleFormatter()
1306  );
1307  },
1308 
1309  'ParsoidDataAccess' => static function ( MediaWikiServices $services ): DataAccess {
1310  $mainConfig = $services->getMainConfig();
1311  $parsoidSettings = $mainConfig->get( MainConfigNames::ParsoidSettings );
1312  if ( !empty( $parsoidSettings['debugApi'] ) ) {
1313  return ApiDataAccess::fromSettings( $parsoidSettings );
1314  }
1315  return new MWDataAccess(
1316  new ServiceOptions( MWDataAccess::CONSTRUCTOR_OPTIONS, $mainConfig ),
1317  $services->getRepoGroup(),
1318  $services->getBadFileLookup(),
1319  $services->getHookContainer(),
1320  $services->getContentTransformer(),
1321  $services->getReadOnlyMode(),
1322  $services->getParserFactory() // *legacy* parser factory
1323  );
1324  },
1325 
1326  'ParsoidOutputStash' => static function ( MediaWikiServices $services ): ParsoidOutputStash {
1327  // TODO: Determine storage requirements and config options for stashing parsoid
1328  // output for VE edits (T309016).
1329  $config = $services->getMainConfig()->get( MainConfigNames::ParsoidCacheConfig );
1330  $backend = $config['StashType']
1331  ? ObjectCache::getInstance( $config['StashType'] )
1332  : $services->getMainObjectStash();
1333 
1334  return new SimpleParsoidOutputStash( $backend, $config['StashDuration'] );
1335  },
1336 
1337  'ParsoidPageConfigFactory' => static function ( MediaWikiServices $services ): MWPageConfigFactory {
1338  return new MWPageConfigFactory( $services->getRevisionStore(),
1339  $services->getSlotRoleRegistry() );
1340  },
1341 
1342  'ParsoidSiteConfig' => static function ( MediaWikiServices $services ): SiteConfig {
1343  $mainConfig = $services->getMainConfig();
1344  $parsoidSettings = $mainConfig->get( MainConfigNames::ParsoidSettings );
1345  if ( !empty( $parsoidSettings['debugApi'] ) ) {
1346  return ApiSiteConfig::fromSettings( $parsoidSettings );
1347  }
1348  return new MWSiteConfig(
1349  new ServiceOptions( MWSiteConfig::CONSTRUCTOR_OPTIONS, $mainConfig ),
1350  $parsoidSettings,
1351  $services->getObjectFactory(),
1352  $services->getContentLanguage(),
1353  $services->getStatsdDataFactory(),
1354  $services->getMagicWordFactory(),
1355  $services->getNamespaceInfo(),
1356  $services->getSpecialPageFactory(),
1357  $services->getInterwikiLookup(),
1358  $services->getUserOptionsLookup(),
1359  $services->getLanguageFactory(),
1360  $services->getLanguageConverterFactory(),
1361  $services->getLanguageNameUtils(),
1362  // These arguments are temporary and will be removed once
1363  // better solutions are found.
1364  $services->getParser(), // T268776
1365  $mainConfig // T268777
1366  );
1367  },
1368 
1369  'PasswordFactory' => static function ( MediaWikiServices $services ): PasswordFactory {
1370  $config = $services->getMainConfig();
1371  return new PasswordFactory(
1372  $config->get( MainConfigNames::PasswordConfig ),
1373  $config->get( MainConfigNames::PasswordDefault )
1374  );
1375  },
1376 
1377  'PasswordReset' => static function ( MediaWikiServices $services ): PasswordReset {
1378  $options = new ServiceOptions( PasswordReset::CONSTRUCTOR_OPTIONS, $services->getMainConfig() );
1379  return new PasswordReset(
1380  $options,
1381  LoggerFactory::getInstance( 'authentication' ),
1382  $services->getAuthManager(),
1383  $services->getHookContainer(),
1384  $services->getDBLoadBalancer(),
1385  $services->getUserFactory(),
1386  $services->getUserNameUtils(),
1387  $services->getUserOptionsLookup()
1388  );
1389  },
1390 
1391  'PerDbNameStatsdDataFactory' =>
1392  static function ( MediaWikiServices $services ): StatsdDataFactoryInterface {
1393  $config = $services->getMainConfig();
1394  $wiki = $config->get( MainConfigNames::DBname );
1396  $services->getStatsdDataFactory(),
1397  $wiki
1398  );
1399  },
1400 
1401  'PermissionManager' => static function ( MediaWikiServices $services ): PermissionManager {
1402  return new PermissionManager(
1403  new ServiceOptions(
1404  PermissionManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
1405  ),
1406  $services->getSpecialPageFactory(),
1407  $services->getNamespaceInfo(),
1408  $services->getGroupPermissionsLookup(),
1409  $services->getUserGroupManager(),
1410  $services->getBlockErrorFormatter(),
1411  $services->getHookContainer(),
1412  $services->getUserCache(),
1413  $services->getRedirectLookup(),
1414  $services->getRestrictionStore(),
1415  $services->getTitleFormatter(),
1416  $services->getTempUserConfig(),
1417  $services->getUserFactory(),
1418  $services->getActionFactory()
1419  );
1420  },
1421 
1422  'PreferencesFactory' => static function ( MediaWikiServices $services ): PreferencesFactory {
1423  $factory = new DefaultPreferencesFactory(
1424  new ServiceOptions(
1425  DefaultPreferencesFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1426  $services->getContentLanguage(),
1427  $services->getAuthManager(),
1428  $services->getLinkRendererFactory()->create(),
1429  $services->getNamespaceInfo(),
1430  $services->getPermissionManager(),
1431  $services->getLanguageConverterFactory()->getLanguageConverter(),
1432  $services->getLanguageNameUtils(),
1433  $services->getHookContainer(),
1434  $services->getUserOptionsManager(),
1435  $services->getLanguageConverterFactory(),
1436  $services->getParser(),
1437  $services->getSkinFactory(),
1438  $services->getUserGroupManager(),
1439  $services->getSignatureValidatorFactory()
1440  );
1441  $factory->setLogger( LoggerFactory::getInstance( 'preferences' ) );
1442 
1443  return $factory;
1444  },
1445 
1446  'ProxyLookup' => static function ( MediaWikiServices $services ): ProxyLookup {
1447  $mainConfig = $services->getMainConfig();
1448  return new ProxyLookup(
1449  $mainConfig->get( MainConfigNames::CdnServers ),
1450  $mainConfig->get( MainConfigNames::CdnServersNoPurge ),
1451  $services->getHookContainer()
1452  );
1453  },
1454 
1455  'ReadOnlyMode' => static function ( MediaWikiServices $services ): ReadOnlyMode {
1456  return new ReadOnlyMode(
1457  $services->getConfiguredReadOnlyMode(),
1458  $services->getDBLoadBalancer()
1459  );
1460  },
1461 
1462  'RedirectLookup' => static function ( MediaWikiServices $services ): RedirectLookup {
1463  return $services->getRedirectStore();
1464  },
1465 
1466  'RedirectStore' => static function ( MediaWikiServices $services ): RedirectStore {
1467  return new RedirectStore( $services->getWikiPageFactory() );
1468  },
1469 
1470  'RepoGroup' => static function ( MediaWikiServices $services ): RepoGroup {
1471  $config = $services->getMainConfig();
1472  return new RepoGroup(
1473  $config->get( MainConfigNames::LocalFileRepo ),
1474  $config->get( MainConfigNames::ForeignFileRepos ),
1475  $services->getMainWANObjectCache(),
1476  $services->getMimeAnalyzer()
1477  );
1478  },
1479 
1480  'ResourceLoader' => static function ( MediaWikiServices $services ): ResourceLoader {
1481  $config = $services->getMainConfig();
1482 
1483  $maxage = $config->get( MainConfigNames::ResourceLoaderMaxage );
1484  $rl = new ResourceLoader(
1485  $config,
1486  LoggerFactory::getInstance( 'resourceloader' ),
1487  $config->get( MainConfigNames::ResourceLoaderUseObjectCacheForDeps )
1488  ? new KeyValueDependencyStore( $services->getMainObjectStash() )
1489  : new SqlModuleDependencyStore( $services->getDBLoadBalancer() ),
1490  [
1491  'loadScript' => $config->get( MainConfigNames::LoadScript ),
1492  'maxageVersioned' => $maxage['versioned'] ?? null,
1493  'maxageUnversioned' => $maxage['unversioned'] ?? null,
1494  'useFileCache' => $config->get( MainConfigNames::UseFileCache ),
1495  ]
1496  );
1497 
1498  $extRegistry = ExtensionRegistry::getInstance();
1499  // Attribute has precedence over config
1500  $modules = $extRegistry->getAttribute( 'ResourceModules' )
1501  + $config->get( MainConfigNames::ResourceModules );
1502  $moduleSkinStyles = $extRegistry->getAttribute( 'ResourceModuleSkinStyles' )
1503  + $config->get( MainConfigNames::ResourceModuleSkinStyles );
1504 
1505  $rl->setModuleSkinStyles( $moduleSkinStyles );
1506  $rl->addSource( $config->get( MainConfigNames::ResourceLoaderSources ) );
1507 
1508  // Core modules, then extension/skin modules
1509  $baseDir = $config->get( MainConfigNames::BaseDirectory );
1510  $rl->register( include "$baseDir/resources/Resources.php" );
1511  $rl->register( $modules );
1512  $hookRunner = new \MediaWiki\ResourceLoader\HookRunner( $services->getHookContainer() );
1513  $hookRunner->onResourceLoaderRegisterModules( $rl );
1514 
1515  $msgPosterAttrib = $extRegistry->getAttribute( 'MessagePosterModule' );
1516  $rl->register( 'mediawiki.messagePoster', [
1517  'localBasePath' => $baseDir,
1518  'debugRaw' => false,
1519  'scripts' => array_merge(
1520  [
1521  "resources/src/mediawiki.messagePoster/factory.js",
1522  "resources/src/mediawiki.messagePoster/MessagePoster.js",
1523  "resources/src/mediawiki.messagePoster/WikitextMessagePoster.js",
1524  ],
1525  $msgPosterAttrib['scripts'] ?? []
1526  ),
1527  'dependencies' => array_merge(
1528  [
1529  'oojs',
1530  'mediawiki.api',
1531  'mediawiki.ForeignApi',
1532  ],
1533  $msgPosterAttrib['dependencies'] ?? []
1534  ),
1535  'targets' => [ 'desktop', 'mobile' ],
1536  ] );
1537 
1538  if ( $config->get( MainConfigNames::EnableJavaScriptTest ) === true ) {
1539  $rl->registerTestModules();
1540  }
1541 
1542  return $rl;
1543  },
1544 
1545  'RestrictionStore' => static function ( MediaWikiServices $services ): RestrictionStore {
1546  return new RestrictionStore(
1547  new ServiceOptions(
1548  RestrictionStore::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
1549  ),
1550  $services->getMainWANObjectCache(),
1551  $services->getDBLoadBalancer(),
1552  $services->getLinkCache(),
1553  $services->getLinksMigration(),
1554  $services->getCommentStore(),
1555  $services->getHookContainer(),
1556  $services->getPageStore()
1557  );
1558  },
1559 
1560  'RevertedTagUpdateManager' => static function ( MediaWikiServices $services ): RevertedTagUpdateManager {
1561  $editResultCache = new EditResultCache(
1562  $services->getMainObjectStash(),
1563  $services->getDBLoadBalancer(),
1564  new ServiceOptions(
1565  EditResultCache::CONSTRUCTOR_OPTIONS,
1566  $services->getMainConfig()
1567  )
1568  );
1569 
1570  return new RevertedTagUpdateManager(
1571  $editResultCache,
1572  $services->getJobQueueGroup()
1573  );
1574  },
1575 
1576  'RevisionFactory' => static function ( MediaWikiServices $services ): RevisionFactory {
1577  return $services->getRevisionStore();
1578  },
1579 
1580  'RevisionLookup' => static function ( MediaWikiServices $services ): RevisionLookup {
1581  return $services->getRevisionStore();
1582  },
1583 
1584  'RevisionRenderer' => static function ( MediaWikiServices $services ): RevisionRenderer {
1585  $renderer = new RevisionRenderer(
1586  $services->getDBLoadBalancer(),
1587  $services->getSlotRoleRegistry(),
1588  $services->getContentRenderer()
1589  );
1590 
1591  $renderer->setLogger( LoggerFactory::getInstance( 'SaveParse' ) );
1592  return $renderer;
1593  },
1594 
1595  'RevisionStore' => static function ( MediaWikiServices $services ): RevisionStore {
1596  return $services->getRevisionStoreFactory()->getRevisionStore();
1597  },
1598 
1599  'RevisionStoreFactory' => static function ( MediaWikiServices $services ): RevisionStoreFactory {
1600  return new RevisionStoreFactory(
1601  $services->getDBLoadBalancerFactory(),
1602  $services->getBlobStoreFactory(),
1603  $services->getNameTableStoreFactory(),
1604  $services->getSlotRoleRegistry(),
1605  $services->getMainWANObjectCache(),
1606  $services->getLocalServerObjectCache(),
1607  $services->getCommentStore(),
1608  $services->getActorMigration(),
1609  $services->getActorStoreFactory(),
1610  LoggerFactory::getInstance( 'RevisionStore' ),
1611  $services->getContentHandlerFactory(),
1612  $services->getPageStoreFactory(),
1613  $services->getTitleFactory(),
1614  $services->getHookContainer()
1615  );
1616  },
1617 
1618  'RollbackPageFactory' => static function ( MediaWikiServices $services ): RollbackPageFactory {
1619  return $services->get( '_PageCommandFactory' );
1620  },
1621 
1622  'RowCommentFormatter' => static function ( MediaWikiServices $services ): RowCommentFormatter {
1623  $parserFactory = new CommentParserFactory(
1624  $services->getLinkRenderer(),
1625  $services->getLinkBatchFactory(),
1626  $services->getLinkCache(),
1627  $services->getRepoGroup(),
1628  RequestContext::getMain()->getLanguage(),
1629  $services->getContentLanguage(),
1630  $services->getTitleParser(),
1631  $services->getNamespaceInfo(),
1632  $services->getHookContainer()
1633  );
1634  return new RowCommentFormatter(
1635  $parserFactory,
1636  $services->getCommentStore()
1637  );
1638  },
1639 
1640  'SearchEngineConfig' => static function ( MediaWikiServices $services ): SearchEngineConfig {
1641  // @todo This should not take a Config object, but it's not so easy to remove because it
1642  // exposes it in a getter, which is actually used.
1643  return new SearchEngineConfig(
1644  $services->getMainConfig(),
1645  $services->getContentLanguage(),
1646  $services->getHookContainer(),
1647  ExtensionRegistry::getInstance()->getAttribute( 'SearchMappings' )
1648  );
1649  },
1650 
1651  'SearchEngineFactory' => static function ( MediaWikiServices $services ): SearchEngineFactory {
1652  return new SearchEngineFactory(
1653  $services->getSearchEngineConfig(),
1654  $services->getHookContainer(),
1655  $services->getDBLoadBalancer()
1656  );
1657  },
1658 
1659  'ShellboxClientFactory' => static function ( MediaWikiServices $services ): ShellboxClientFactory {
1660  $urls = $services->getMainConfig()->get( MainConfigNames::ShellboxUrls );
1661  // TODO: Remove this logic and $wgShellboxUrl configuration in 1.38
1662  $url = $services->getMainConfig()->get( MainConfigNames::ShellboxUrl );
1663  if ( $url !== null ) {
1664  $urls['default'] = $url;
1665  }
1666  return new ShellboxClientFactory(
1667  $services->getHttpRequestFactory(),
1668  $urls,
1669  $services->getMainConfig()->get( MainConfigNames::ShellboxSecretKey )
1670  );
1671  },
1672 
1673  'ShellCommandFactory' => static function ( MediaWikiServices $services ): CommandFactory {
1674  $config = $services->getMainConfig();
1675 
1676  $limits = [
1677  'time' => $config->get( MainConfigNames::MaxShellTime ),
1678  'walltime' => $config->get( MainConfigNames::MaxShellWallClockTime ),
1679  'memory' => $config->get( MainConfigNames::MaxShellMemory ),
1680  'filesize' => $config->get( MainConfigNames::MaxShellFileSize ),
1681  ];
1682  $cgroup = $config->get( MainConfigNames::ShellCgroup );
1683  $restrictionMethod = $config->get( MainConfigNames::ShellRestrictionMethod );
1684 
1685  $factory = new CommandFactory( $services->getShellboxClientFactory(),
1686  $limits, $cgroup, $restrictionMethod );
1687  $factory->setLogger( LoggerFactory::getInstance( 'exec' ) );
1688  $factory->logStderr();
1689 
1690  return $factory;
1691  },
1692 
1693  'SignatureValidatorFactory' => static function ( MediaWikiServices $services ): SignatureValidatorFactory {
1694  return new SignatureValidatorFactory(
1695  new ServiceOptions(
1696  SignatureValidator::CONSTRUCTOR_OPTIONS,
1697  $services->getMainConfig()
1698  ),
1699  // Use a closure for Parser to avoid a circular dependency
1700  static function () use ( $services ) {
1701  return $services->getParser();
1702  },
1703  $services->getSpecialPageFactory(),
1704  $services->getTitleFactory()
1705  );
1706  },
1707 
1708  'SiteLookup' => static function ( MediaWikiServices $services ): SiteLookup {
1709  // Use SiteStore as the SiteLookup as well. This was originally separated
1710  // to allow for a cacheable read-only interface, but this was never used.
1711  // SiteStore has caching (see below).
1712  return $services->getSiteStore();
1713  },
1714 
1715  'SiteStore' => static function ( MediaWikiServices $services ): SiteStore {
1716  $rawSiteStore = new DBSiteStore( $services->getDBLoadBalancer() );
1717 
1718  $cache = $services->getLocalServerObjectCache();
1719  if ( $cache instanceof EmptyBagOStuff ) {
1721  }
1722 
1723  return new CachingSiteStore( $rawSiteStore, $cache );
1724  },
1725 
1727  'SkinFactory' => static function ( MediaWikiServices $services ): SkinFactory {
1728  $factory = new SkinFactory(
1729  $services->getObjectFactory(),
1730  (array)$services->getMainConfig()->get( MainConfigNames::SkipSkins )
1731  );
1732 
1733  $names = $services->getMainConfig()->get( MainConfigNames::ValidSkinNames );
1734 
1735  foreach ( $names as $name => $skin ) {
1736  if ( is_array( $skin ) ) {
1737  $spec = $skin;
1738  $displayName = $skin['displayname'] ?? $name;
1739  $skippable = $skin['skippable'] ?? null;
1740  } else {
1741  $displayName = $skin;
1742  $skippable = null;
1743  $spec = [
1744  'name' => $name,
1745  'class' => "Skin$skin"
1746  ];
1747  }
1748  $factory->register( $name, $displayName, $spec, $skippable );
1749  }
1750 
1751  // Register a hidden "fallback" skin
1752  $factory->register( 'fallback', 'Fallback', [
1753  'class' => SkinFallback::class,
1754  'args' => [
1755  [
1756  'name' => 'fallback',
1757  'styles' => [ 'mediawiki.skinning.interface' ],
1758  'templateDirectory' => __DIR__ . '/skins/templates/fallback',
1759  ]
1760  ]
1761  ], true );
1762  // Register a hidden skin for api output
1763  $factory->register( 'apioutput', 'ApiOutput', [
1764  'class' => SkinApi::class,
1765  'args' => [
1766  [
1767  'name' => 'apioutput',
1768  'styles' => [ 'mediawiki.skinning.interface' ],
1769  'templateDirectory' => __DIR__ . '/skins/templates/apioutput',
1770  ]
1771  ]
1772  ], true );
1773 
1774  return $factory;
1775  },
1776 
1777  'SlotRoleRegistry' => static function ( MediaWikiServices $services ): SlotRoleRegistry {
1778  $registry = new SlotRoleRegistry(
1779  $services->getSlotRoleStore()
1780  );
1781 
1782  $config = $services->getMainConfig();
1783  $contentHandlerFactory = $services->getContentHandlerFactory();
1784  $hookContainer = $services->getHookContainer();
1785  $titleFactory = $services->getTitleFactory();
1786  $registry->defineRole(
1787  'main',
1788  static function () use ( $config, $contentHandlerFactory, $hookContainer, $titleFactory ) {
1789  return new MainSlotRoleHandler(
1790  $config->get( MainConfigNames::NamespaceContentModels ),
1791  $contentHandlerFactory,
1792  $hookContainer,
1793  $titleFactory
1794  );
1795  }
1796  );
1797 
1798  return $registry;
1799  },
1800 
1801  'SlotRoleStore' => static function ( MediaWikiServices $services ): NameTableStore {
1802  return $services->getNameTableStoreFactory()->getSlotRoles();
1803  },
1804 
1805  'SpamChecker' => static function ( MediaWikiServices $services ): SpamChecker {
1806  return new SpamChecker(
1807  (array)$services->getMainConfig()->get( MainConfigNames::SpamRegex ),
1808  (array)$services->getMainConfig()->get( MainConfigNames::SummarySpamRegex )
1809  );
1810  },
1811 
1812  'SpecialPageFactory' => static function ( MediaWikiServices $services ): SpecialPageFactory {
1813  return new SpecialPageFactory(
1814  new ServiceOptions(
1815  SpecialPageFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
1816  $services->getContentLanguage(),
1817  $services->getObjectFactory(),
1818  $services->getTitleFactory(),
1819  $services->getHookContainer()
1820  );
1821  },
1822 
1823  'StatsdDataFactory' => static function ( MediaWikiServices $services ): IBufferingStatsdDataFactory {
1824  return new BufferingStatsdDataFactory(
1825  rtrim( $services->getMainConfig()->get( MainConfigNames::StatsdMetricPrefix ), '.' )
1826  );
1827  },
1828 
1829  'TalkPageNotificationManager' => static function (
1830  MediaWikiServices $services
1832  return new TalkPageNotificationManager(
1833  new ServiceOptions(
1834  TalkPageNotificationManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
1835  ),
1836  $services->getDBLoadBalancer(),
1837  $services->getReadOnlyMode(),
1838  $services->getRevisionLookup(),
1839  $services->getHookContainer(),
1840  $services->getUserFactory()
1841  );
1842  },
1843 
1844  'TempFSFileFactory' => static function ( MediaWikiServices $services ): TempFSFileFactory {
1845  return new TempFSFileFactory( $services->getMainConfig()->get( MainConfigNames::TmpDirectory ) );
1846  },
1847 
1848  'TempUserConfig' => static function ( MediaWikiServices $services ): RealTempUserConfig {
1849  return new RealTempUserConfig(
1850  $services->getMainConfig()->get( MainConfigNames::AutoCreateTempUser )
1851  );
1852  },
1853 
1854  'TempUserCreator' => static function ( MediaWikiServices $services ): TempUserCreator {
1855  $accountCreationThrottle = $services->getMainConfig()->get( MainConfigNames::AccountCreationThrottle );
1856  // T306878: Handle old $wgAccountCreationThrottle format (number of attempts per 24 hours)
1857  if ( !is_array( $accountCreationThrottle ) ) {
1858  $accountCreationThrottle = [ [
1859  'count' => $accountCreationThrottle,
1860  'seconds' => 86400,
1861  ] ];
1862  }
1863 
1864  return new TempUserCreator(
1865  $services->getTempUserConfig(),
1866  $services->getObjectFactory(),
1867  $services->getUserFactory(),
1868  $services->getAuthManager(),
1869  // This is supposed to match ThrottlePreAuthenticationProvider
1870  new Throttler(
1871  $accountCreationThrottle,
1872  [
1873  'type' => 'acctcreate',
1874  'cache' => $services->getLocalServerObjectCache()
1875  ]
1876  )
1877  );
1878  },
1879 
1880  'Tidy' => static function ( MediaWikiServices $services ): TidyDriverBase {
1881  return new RemexDriver(
1882  new ServiceOptions(
1883  RemexDriver::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
1884  )
1885  );
1886  },
1887 
1888  'TitleFactory' => static function ( MediaWikiServices $services ): TitleFactory {
1889  return new TitleFactory();
1890  },
1891 
1892  'TitleFormatter' => static function ( MediaWikiServices $services ): TitleFormatter {
1893  return $services->getService( '_MediaWikiTitleCodec' );
1894  },
1895 
1896  'TitleParser' => static function ( MediaWikiServices $services ): TitleParser {
1897  return $services->getService( '_MediaWikiTitleCodec' );
1898  },
1899 
1900  'TrackingCategories' => static function ( MediaWikiServices $services ): TrackingCategories {
1901  return new TrackingCategories(
1902  new ServiceOptions(
1904  $services->getMainConfig()
1905  ),
1906  $services->getNamespaceInfo(),
1907  $services->getTitleParser(),
1908  LoggerFactory::getInstance( 'TrackingCategories' )
1909  );
1910  },
1911 
1912  'UnblockUserFactory' => static function ( MediaWikiServices $services ): UnblockUserFactory {
1913  return $services->getService( '_UserBlockCommandFactory' );
1914  },
1915 
1916  'UndeletePageFactory' => static function ( MediaWikiServices $services ): UndeletePageFactory {
1917  return $services->getService( '_PageCommandFactory' );
1918  },
1919 
1920  'UploadRevisionImporter' => static function ( MediaWikiServices $services ): UploadRevisionImporter {
1922  $services->getMainConfig()->get( MainConfigNames::EnableUploads ),
1923  LoggerFactory::getInstance( 'UploadRevisionImporter' )
1924  );
1925  },
1926 
1927  'UrlUtils' => static function ( MediaWikiServices $services ): UrlUtils {
1928  $config = $services->getMainConfig();
1929  return new UrlUtils( [
1930  UrlUtils::SERVER => $config->get( MainConfigNames::Server ),
1931  UrlUtils::CANONICAL_SERVER => $config->get( MainConfigNames::CanonicalServer ),
1932  UrlUtils::INTERNAL_SERVER => $config->get( MainConfigNames::InternalServer ),
1933  UrlUtils::FALLBACK_PROTOCOL => RequestContext::getMain()->getRequest()->getProtocol(),
1934  UrlUtils::HTTPS_PORT => $config->get( MainConfigNames::HttpsPort ),
1935  UrlUtils::VALID_PROTOCOLS => $config->get( MainConfigNames::UrlProtocols ),
1936  ] );
1937  },
1938 
1939  'UserCache' => static function ( MediaWikiServices $services ): UserCache {
1940  return new UserCache(
1941  LoggerFactory::getInstance( 'UserCache' ),
1942  $services->getDBLoadBalancer(),
1943  $services->getLinkBatchFactory()
1944  );
1945  },
1946 
1947  'UserEditTracker' => static function ( MediaWikiServices $services ): UserEditTracker {
1948  return new UserEditTracker(
1949  $services->getActorMigration(),
1950  $services->getDBLoadBalancer(),
1951  $services->getJobQueueGroup()
1952  );
1953  },
1954 
1955  'UserFactory' => static function ( MediaWikiServices $services ): UserFactory {
1956  return new UserFactory(
1957  $services->getDBLoadBalancer(),
1958  $services->getUserNameUtils()
1959  );
1960  },
1961 
1962  'UserGroupManager' => static function ( MediaWikiServices $services ): UserGroupManager {
1963  return $services->getUserGroupManagerFactory()->getUserGroupManager();
1964  },
1965 
1966  'UserGroupManagerFactory' => static function ( MediaWikiServices $services ): UserGroupManagerFactory {
1967  return new UserGroupManagerFactory(
1968  new ServiceOptions(
1969  UserGroupManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
1970  ),
1971  $services->getConfiguredReadOnlyMode(),
1972  $services->getDBLoadBalancerFactory(),
1973  $services->getHookContainer(),
1974  $services->getUserEditTracker(),
1975  $services->getGroupPermissionsLookup(),
1976  $services->getJobQueueGroupFactory(),
1977  LoggerFactory::getInstance( 'UserGroupManager' ),
1978  $services->getTempUserConfig(),
1979  [ static function ( UserIdentity $user ) use ( $services ) {
1980  $services->getPermissionManager()->invalidateUsersRightsCache( $user );
1981  $services->getUserFactory()->newFromUserIdentity( $user )->invalidateCache();
1982  } ]
1983  );
1984  },
1985 
1986  'UserIdentityLookup' => static function ( MediaWikiServices $services ): UserIdentityLookup {
1987  return $services->getActorStoreFactory()->getUserIdentityLookup();
1988  },
1989 
1990  'UserNamePrefixSearch' => static function ( MediaWikiServices $services ): UserNamePrefixSearch {
1991  return new UserNamePrefixSearch(
1992  $services->getDBLoadBalancer(),
1993  $services->getUserNameUtils()
1994  );
1995  },
1996 
1997  'UserNameUtils' => static function ( MediaWikiServices $services ): UserNameUtils {
1998  $messageFormatterFactory = new MessageFormatterFactory( Message::FORMAT_PLAIN );
1999  return new UserNameUtils(
2000  new ServiceOptions(
2001  UserNameUtils::CONSTRUCTOR_OPTIONS, $services->getMainConfig()
2002  ),
2003  $services->getContentLanguage(),
2004  LoggerFactory::getInstance( 'UserNameUtils' ),
2005  $services->getTitleParser(),
2006  $messageFormatterFactory->getTextFormatter(
2007  $services->getContentLanguage()->getCode()
2008  ),
2009  $services->getHookContainer(),
2010  $services->getTempUserConfig()
2011  );
2012  },
2013 
2014  'UserOptionsLookup' => static function ( MediaWikiServices $services ): UserOptionsLookup {
2015  return $services->getUserOptionsManager();
2016  },
2017 
2018  'UserOptionsManager' => static function ( MediaWikiServices $services ): UserOptionsManager {
2019  return new UserOptionsManager(
2020  new ServiceOptions( UserOptionsManager::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
2021  $services->get( '_DefaultOptionsLookup' ),
2022  $services->getLanguageConverterFactory(),
2023  $services->getDBLoadBalancer(),
2024  LoggerFactory::getInstance( 'UserOptionsManager' ),
2025  $services->getHookContainer(),
2026  $services->getUserFactory()
2027  );
2028  },
2029 
2030  'VirtualRESTServiceClient' =>
2031  static function ( MediaWikiServices $services ): VirtualRESTServiceClient {
2032  $config = $services->getMainConfig()->get( MainConfigNames::VirtualRestConfig );
2033 
2034  $vrsClient = new VirtualRESTServiceClient(
2035  $services->getHttpRequestFactory()->createMultiClient() );
2036  foreach ( $config['paths'] as $prefix => $serviceConfig ) {
2037  $class = $serviceConfig['class'];
2038  // Merge in the global defaults
2039  $constructArg = $serviceConfig['options'] ?? [];
2040  $constructArg += $config['global'];
2041  // Make the VRS service available at the mount point
2042  $vrsClient->mount( $prefix, [ 'class' => $class, 'config' => $constructArg ] );
2043  }
2044 
2045  return $vrsClient;
2046  },
2047 
2048  'WatchedItemQueryService' =>
2049  static function ( MediaWikiServices $services ): WatchedItemQueryService {
2050  return new WatchedItemQueryService(
2051  $services->getDBLoadBalancer(),
2052  $services->getCommentStore(),
2053  $services->getWatchedItemStore(),
2054  $services->getHookContainer(),
2055  $services->getMainConfig()->get( MainConfigNames::WatchlistExpiry ),
2056  $services->getMainConfig()->get( MainConfigNames::MaxExecutionTimeForExpensiveQueries )
2057  );
2058  },
2059 
2060  'WatchedItemStore' => static function ( MediaWikiServices $services ): WatchedItemStore {
2061  $store = new WatchedItemStore(
2063  $services->getMainConfig() ),
2064  $services->getDBLoadBalancerFactory(),
2065  $services->getJobQueueGroup(),
2066  $services->getMainObjectStash(),
2067  new HashBagOStuff( [ 'maxKeys' => 100 ] ),
2068  $services->getReadOnlyMode(),
2069  $services->getNamespaceInfo(),
2070  $services->getRevisionLookup(),
2071  $services->getLinkBatchFactory()
2072  );
2073  $store->setStatsdDataFactory( $services->getStatsdDataFactory() );
2074 
2075  if ( $services->getMainConfig()->get( MainConfigNames::ReadOnlyWatchedItemStore ) ) {
2076  $store = new NoWriteWatchedItemStore( $store );
2077  }
2078 
2079  return $store;
2080  },
2081 
2082  'WatchlistManager' => static function ( MediaWikiServices $services ): WatchlistManager {
2083  return new WatchlistManager(
2084  new ServiceOptions(
2085  WatchlistManager::CONSTRUCTOR_OPTIONS,
2086  $services->getMainConfig()
2087  ),
2088  $services->getHookContainer(),
2089  $services->getReadOnlyMode(),
2090  $services->getRevisionLookup(),
2091  $services->getTalkPageNotificationManager(),
2092  $services->getWatchedItemStore(),
2093  $services->getUserFactory(),
2094  $services->getNamespaceInfo(),
2095  $services->getWikiPageFactory()
2096  );
2097  },
2098 
2099  'WikiExporterFactory' => static function ( MediaWikiServices $services ): WikiExporterFactory {
2100  return new WikiExporterFactory(
2101  $services->getHookContainer(),
2102  $services->getRevisionStore(),
2103  $services->getTitleParser()
2104  );
2105  },
2106 
2107  'WikiImporterFactory' => static function ( MediaWikiServices $services ): WikiImporterFactory {
2108  return new WikiImporterFactory(
2109  $services->getMainConfig(),
2110  $services->getHookContainer(),
2111  $services->getContentLanguage(),
2112  $services->getNamespaceInfo(),
2113  $services->getTitleFactory(),
2114  $services->getWikiPageFactory(),
2115  $services->getWikiRevisionUploadImporter(),
2116  $services->getPermissionManager(),
2117  $services->getContentHandlerFactory(),
2118  $services->getSlotRoleRegistry()
2119  );
2120  },
2121 
2122  'WikiPageFactory' => static function ( MediaWikiServices $services ): WikiPageFactory {
2123  return new WikiPageFactory(
2124  $services->getTitleFactory(),
2125  new HookRunner( $services->getHookContainer() ),
2126  $services->getDBLoadBalancer()
2127  );
2128  },
2129 
2130  'WikiRevisionOldRevisionImporterNoUpdates' =>
2131  static function ( MediaWikiServices $services ): ImportableOldRevisionImporter {
2132  return new ImportableOldRevisionImporter(
2133  false,
2134  LoggerFactory::getInstance( 'OldRevisionImporter' ),
2135  $services->getDBLoadBalancer(),
2136  $services->getRevisionStore(),
2137  $services->getSlotRoleRegistry(),
2138  $services->getWikiPageFactory(),
2139  $services->getPageUpdaterFactory(),
2140  $services->getUserFactory()
2141  );
2142  },
2143 
2144  '_DefaultOptionsLookup' => static function ( MediaWikiServices $services ): DefaultOptionsLookup {
2145  return new DefaultOptionsLookup(
2146  new ServiceOptions( DefaultOptionsLookup::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
2147  $services->getContentLanguage(),
2148  $services->getHookContainer(),
2149  $services->getNamespaceInfo()
2150  );
2151  },
2152 
2153  '_EditConstraintFactory' => static function ( MediaWikiServices $services ): EditConstraintFactory {
2154  // This service is internal and currently only exists because a significant number
2155  // of dependencies will be needed by different constraints. It is not part of
2156  // the public interface and has no corresponding method in MediaWikiServices
2157  return new EditConstraintFactory(
2158  // Multiple
2159  new ServiceOptions(
2160  EditConstraintFactory::CONSTRUCTOR_OPTIONS,
2161  $services->getMainConfig()
2162  ),
2163  LoggerFactory::getProvider(),
2164 
2165  // UserBlockConstraint
2166  $services->getPermissionManager(),
2167 
2168  // EditFilterMergedContentHookConstraint
2169  $services->getHookContainer(),
2170 
2171  // ReadOnlyConstraint
2172  $services->getReadOnlyMode(),
2173 
2174  // SpamRegexConstraint
2175  $services->getSpamChecker()
2176  );
2177  },
2178 
2179  '_MediaWikiTitleCodec' => static function ( MediaWikiServices $services ): MediaWikiTitleCodec {
2180  return new MediaWikiTitleCodec(
2181  $services->getContentLanguage(),
2182  $services->getGenderCache(),
2183  $services->getMainConfig()->get( MainConfigNames::LocalInterwikis ),
2184  $services->getInterwikiLookup(),
2185  $services->getNamespaceInfo()
2186  );
2187  },
2188 
2189  '_PageCommandFactory' => static function ( MediaWikiServices $services ): PageCommandFactory {
2190  return new PageCommandFactory(
2191  $services->getMainConfig(),
2192  $services->getDBLoadBalancerFactory(),
2193  $services->getNamespaceInfo(),
2194  $services->getWatchedItemStore(),
2195  $services->getRepoGroup(),
2196  $services->getReadOnlyMode(),
2197  $services->getContentHandlerFactory(),
2198  $services->getRevisionStore(),
2199  $services->getSpamChecker(),
2200  $services->getTitleFormatter(),
2201  $services->getHookContainer(),
2202  $services->getWikiPageFactory(),
2203  $services->getUserFactory(),
2204  $services->getActorMigration(),
2205  $services->getActorNormalization(),
2206  $services->getTitleFactory(),
2207  $services->getUserEditTracker(),
2208  $services->getCollationFactory(),
2209  $services->getJobQueueGroup(),
2210  $services->getCommentStore(),
2211  $services->getMainObjectStash(),
2214  $services->getBacklinkCacheFactory(),
2215  LoggerFactory::getInstance( 'UndeletePage' ),
2216  $services->getPageUpdaterFactory(),
2217  $services->getMessageFormatterFactory()->getTextFormatter(
2218  $services->getContentLanguage()->getCode()
2219  ),
2220  $services->getArchivedRevisionLookup(),
2221  $services->getRestrictionStore()
2222  );
2223  },
2224 
2225  '_ParserObserver' => static function ( MediaWikiServices $services ): ParserObserver {
2226  return new ParserObserver( LoggerFactory::getInstance( 'DuplicateParse' ) );
2227  },
2228 
2229  '_SqlBlobStore' => static function ( MediaWikiServices $services ): SqlBlobStore {
2230  return $services->getBlobStoreFactory()->newSqlBlobStore();
2231  },
2232 
2233  '_UserBlockCommandFactory' => static function ( MediaWikiServices $services ): UserBlockCommandFactory {
2234  return new UserBlockCommandFactory(
2235  new ServiceOptions( UserBlockCommandFactory::CONSTRUCTOR_OPTIONS, $services->getMainConfig() ),
2236  $services->getHookContainer(),
2237  $services->getBlockPermissionCheckerFactory(),
2238  $services->getBlockUtils(),
2239  $services->getDatabaseBlockStore(),
2240  $services->getBlockRestrictionStore(),
2241  $services->getUserFactory(),
2242  $services->getUserEditTracker(),
2243  LoggerFactory::getInstance( 'BlockManager' ),
2244  $services->getTitleFactory(),
2245  $services->getBlockActionInfo()
2246  );
2247  },
2248 
2250  // NOTE: When adding a service here, don't forget to add a getter function
2251  // in the MediaWikiServices class. The convenience getter should just call
2252  // $this->getService( 'FooBarService' ).
2254 
2255 ];
const MIGRATION_NEW
Definition: Defines.php:305
const SCHEMA_COMPAT_NEW
Definition: Defines.php:278
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...
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
$modules
$wgSettings
Definition: Setup.php:142
This is not intended to be a long-term part of MediaWiki; it will be deprecated and removed once acto...
Class representing a cache/ephemeral data store.
Definition: BagOStuff.php:87
get( $key, $flags=0)
Get an item with the given key.
MediaWiki adaption of StatsdDataFactory that provides buffering and metric prefixing.
The CentralIdLookup service allows for connecting local users with cluster-wide IDs.
static getSoftwareTags( $all=false)
Loads defined core tags, checks for invalid types (if not array), and filters for supported and enabl...
Definition: ChangeTags.php:146
Handle database storage of comments such as edit summaries and log reasons.
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:41
A BagOStuff object with no objects in it.
Factory class for spawning EventRelayer objects using configuration.
This is the main interface for fetching or inserting objects with ExternalStore.
Class to handle file backend registration.
Caches user genders when needed to use correct namespace aliases.
Definition: GenderCache.php:36
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:43
const CONSTRUCTOR_OPTIONS
Definition: JobRunner.php:48
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:45
Cache for article titles (prefixed DB keys) and ids linked from one source.
Definition: LinkCache.php:42
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)
const APPLY_DEFAULT_CONFIG_OPTIONS
Definition: MWLBFactory.php:48
static applyDefaultConfig(array $lbConf, ServiceOptions $options, ConfiguredReadOnlyMode $readOnlyMode, BagOStuff $cpStash, BagOStuff $srvCache, WANObjectCache $wanCache, CriticalSectionProvider $csProvider)
Definition: MWLBFactory.php:81
static getLBFactoryClass(array $config)
Decide which LBFactory class to use.
static applyGlobalState(ILBFactory $lbFactory, Config $config, IBufferingStatsdDataFactory $stats)
Apply global state from the current web request or other PHP process.
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.
Defines the actions that can be blocked by a partial block.
A service class for getting formatted information about a block.
A service class for checking blocks.
Backend class for blocking utils.
Definition: BlockUtils.php:46
Common factory to construct collation classes.
This is the main service interface for converting single-line comments from various DB comment fields...
This is basically a CommentFormatter with a CommentStore dependency, allowing it to retrieve comment ...
Object which holds currently registered configuration options.
A class for passing options to services.
Constraints reflect possible errors that need to be checked.
Service to check if text (either content or a summary) qualifies as spam.
Definition: SpamChecker.php:14
Factory service for WikiExporter instances.
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...
Definition: HookRunner.php:562
Factory creating MWHttpRequest objects.
InterwikiLookup implementing the "classic" interwiki storage (hardcoded up to MW 1....
Class to construct JobQueueGroups.
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 anchor link elements for pages.
Service for retrieving and storing link targets.
Service for compat reading of links tables.
PSR-3 logger instance factory.
A class containing constants representing the names of configuration variables.
Service locator for MediaWiki core services.
The MediaWiki-specific implementation of IMessageFormatterFactory.
Implementation of various page action services.
Service for getting rendered output of a given page.
Service for storing and retreiving page redirect information.
Service for creating WikiPage objects.
Implement Parsoid's abstract class for data access.
Definition: DataAccess.php:48
Helper class used by MediaWiki to create Parsoid PageConfig objects.
Site-level configuration for Parsoid.
Definition: SiteConfig.php:63
Users can authorize applications to use their account via OAuth.
Definition: GrantsInfo.php:33
This separate service is needed because the ::getGrantsLink method requires a LinkRenderer and if we ...
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...
This is the default implementation of PreferencesFactory.
This class generates message blobs for use by ResourceLoader.
ResourceLoader is a loading system for JavaScript and CSS resources.
A SlotRoleHandler for the main slot.
The RevisionRenderer service provides access to rendered output for revisions.
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.
This is a service which provides a configured client to access a remote Shellbox installation.
Factory for handling the special page list and generating SpecialPage objects.
Service for instantiating BlobStores.
Class allowing easy storage and retrieval of EditResults associated with revisions.
Manage the pre-emptive page parsing for edits to wiki pages.
A factory for PageUpdater instances.
Class for managing delayed RevertedTagUpdateJob waiting for user approval.
Service for storing and loading Content objects.
Base class for HTML cleanup utilities.
A service class to control default user options.
The real TempUserConfig including internal methods used by TempUserCreator.
Service for temporary user creation.
Track info about user edit counts and timings.
Creates User objects.
Definition: UserFactory.php:38
Factory service for UserGroupManager instances.
Handles searching prefixes of user names.
UserNameUtils service.
Provides access to user options.
A service class to control user options.
A service to expand, parse, and otherwise manipulate URLs.
Definition: UrlUtils.php:17
Cache of messages that are defined by MediaWiki namespace pages or by hooks.
const FORMAT_PLAIN
Use message text as-is.
Definition: Message.php:143
Implements functions related to MIME types such as detection and mapping to file extension.
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
const CONSTRUCTOR_OPTIONS
static makeLocalServerCache()
Create a new BagOStuff instance for local-server caching.
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.
Definition: ObjectCache.php:75
static getLocalClusterInstance()
Get the main cluster-local cache object.
Gives access to properties of a page.
Definition: PageProps.php:33
Cache for ParserOutput objects corresponding to the latest page revisions.
Definition: ParserCache.php:63
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition: Parser.php:95
const CONSTRUCTOR_OPTIONS
Definition: Parser.php:407
Factory class for creating and checking Password objects.
Helper class for the password reset functionality shared by the web UI and the API.
const CONSTRUCTOR_OPTIONS
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:29
static getMain()
Get the RequestContext object associated with the main request.
Configuration handling class for SearchEngine.
Factory class for SearchEngine.
Factory class to create Skin objects.
Definition: SkinFactory.php:31
Creates Title objects.
This class performs some operations related to tracking categories, such as creating a list of all su...
Virtual HTTP service client loosely styled after a Virtual File System.
Multi-datacenter aware caching interface.
get( $key, &$curTTL=null, array $checkKeys=[], &$info=[])
Fetch the value of a key from cache.
static newEmpty()
Get an instance that wraps EmptyBagOStuff.
Storage layer class for WatchedItems.
static getRequestId()
Get the current request ID.
Definition: WebRequest.php:342
Factory service for WikiImporter instances.
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.
Interface for configuration instances.
Definition: Config.php:30
MediaWiki adaptation of StatsdDataFactory that provides buffering functionality.
Marker interface for entities aware of the wiki they belong to.
Interface for saving and retrieval of Parsoid HTML and Parsoid metadata from storage.
get(ParsoidRenderID $renderId)
Retrieve a page bundle (that was previously put in the stash using the ->set() method) from the stash...
Service interface for looking up Interwiki records.
Interface for sending emails.
Definition: IEmailer.php:34
Service for changing the content model of wiki pages.
Service for page delete actions.
Service for mergehistory actions.
Service for page rename actions.
Service for resolving a wiki page redirect.
Service for page rollback actions.
Service for page undelete actions.
A PreferencesFactory is a MediaWiki service that provides the definitions of preferences for a given ...
Service for constructing RevisionRecord objects.
Service for looking up page revisions.
Represents a config schema.
Service for loading and storing data blobs.
Definition: BlobStore.php:35
Service for dealing with the actor table.
Interface for objects representing user identity.
A title formatter service for MediaWiki.
A title parser service for MediaWiki.
Definition: TitleParser.php:33
A simple factory providing a message formatter for a given language code.
$command
Definition: mcc.php:125
$cache
Definition: mcc.php:33
$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