Merge "Add config for serving main Page from the domain root"
[lhc/web/wiklou.git] / includes / MediaWikiServices.php
1 <?php
2
3 namespace MediaWiki;
4
5 use ActorMigration;
6 use CommentStore;
7 use Config;
8 use ConfigFactory;
9 use CryptHKDF;
10 use DateFormatterFactory;
11 use EventRelayerGroup;
12 use GenderCache;
13 use GlobalVarConfig;
14 use Hooks;
15 use IBufferingStatsdDataFactory;
16 use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
17 use MediaWiki\Block\BlockManager;
18 use MediaWiki\Block\BlockRestrictionStore;
19 use MediaWiki\FileBackend\FSFile\TempFSFileFactory;
20 use MediaWiki\FileBackend\LockManager\LockManagerGroupFactory;
21 use MediaWiki\Http\HttpRequestFactory;
22 use Wikimedia\Message\IMessageFormatterFactory;
23 use MediaWiki\Page\MovePageFactory;
24 use MediaWiki\Permissions\PermissionManager;
25 use MediaWiki\Preferences\PreferencesFactory;
26 use MediaWiki\Revision\RevisionRenderer;
27 use MediaWiki\Revision\SlotRoleRegistry;
28 use MediaWiki\Shell\CommandFactory;
29 use MediaWiki\Special\SpecialPageFactory;
30 use MediaWiki\Storage\BlobStore;
31 use MediaWiki\Storage\BlobStoreFactory;
32 use MediaWiki\Storage\NameTableStore;
33 use MediaWiki\Storage\NameTableStoreFactory;
34 use MediaWiki\Revision\RevisionFactory;
35 use MediaWiki\Revision\RevisionLookup;
36 use MediaWiki\Revision\RevisionStore;
37 use OldRevisionImporter;
38 use MediaWiki\Revision\RevisionStoreFactory;
39 use UploadRevisionImporter;
40 use Wikimedia\Rdbms\ILoadBalancer;
41 use LinkCache;
42 use MediaHandlerFactory;
43 use MediaWiki\Config\ConfigRepository;
44 use MediaWiki\Linker\LinkRenderer;
45 use MediaWiki\Linker\LinkRendererFactory;
46 use MWException;
47 use MessageCache;
48 use MimeAnalyzer;
49 use NamespaceInfo;
50 use ObjectCache;
51 use Parser;
52 use ParserCache;
53 use ParserFactory;
54 use PasswordFactory;
55 use ProxyLookup;
56 use RepoGroup;
57 use ResourceLoader;
58 use SearchEngine;
59 use SearchEngineConfig;
60 use SearchEngineFactory;
61 use SiteLookup;
62 use SiteStore;
63 use WatchedItemStoreInterface;
64 use WatchedItemQueryService;
65 use SkinFactory;
66 use TitleFormatter;
67 use TitleParser;
68 use VirtualRESTServiceClient;
69 use Wikimedia\ObjectFactory;
70 use Wikimedia\Rdbms\LBFactory;
71 use Wikimedia\Services\SalvageableService;
72 use Wikimedia\Services\ServiceContainer;
73 use Wikimedia\Services\NoSuchServiceException;
74 use MediaWiki\Interwiki\InterwikiLookup;
75 use MagicWordFactory;
76 use MediaWiki\Storage\PageEditStash;
77
78 /**
79 * Service locator for MediaWiki core services.
80 *
81 * This program is free software; you can redistribute it and/or modify
82 * it under the terms of the GNU General Public License as published by
83 * the Free Software Foundation; either version 2 of the License, or
84 * (at your option) any later version.
85 *
86 * This program is distributed in the hope that it will be useful,
87 * but WITHOUT ANY WARRANTY; without even the implied warranty of
88 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
89 * GNU General Public License for more details.
90 *
91 * You should have received a copy of the GNU General Public License along
92 * with this program; if not, write to the Free Software Foundation, Inc.,
93 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
94 * http://www.gnu.org/copyleft/gpl.html
95 *
96 * @file
97 *
98 * @since 1.27
99 */
100
101 /**
102 * MediaWikiServices is the service locator for the application scope of MediaWiki.
103 * Its implemented as a simple configurable DI container.
104 * MediaWikiServices acts as a top level factory/registry for top level services, and builds
105 * the network of service objects that defines MediaWiki's application logic.
106 * It acts as an entry point to MediaWiki's dependency injection mechanism.
107 *
108 * Services are defined in the "wiring" array passed to the constructor,
109 * or by calling defineService().
110 *
111 * @see docs/injection.txt for an overview of using dependency injection in the
112 * MediaWiki code base.
113 */
114 class MediaWikiServices extends ServiceContainer {
115
116 /**
117 * @var MediaWikiServices|null
118 */
119 private static $instance = null;
120
121 /**
122 * Returns the global default instance of the top level service locator.
123 *
124 * @since 1.27
125 *
126 * The default instance is initialized using the service instantiator functions
127 * defined in ServiceWiring.php.
128 *
129 * @note This should only be called by static functions! The instance returned here
130 * should not be passed around! Objects that need access to a service should have
131 * that service injected into the constructor, never a service locator!
132 *
133 * @return MediaWikiServices
134 */
135 public static function getInstance() {
136 if ( self::$instance === null ) {
137 // NOTE: constructing GlobalVarConfig here is not particularly pretty,
138 // but some information from the global scope has to be injected here,
139 // even if it's just a file name or database credentials to load
140 // configuration from.
141 $bootstrapConfig = new GlobalVarConfig();
142 self::$instance = self::newInstance( $bootstrapConfig, 'load' );
143 }
144
145 return self::$instance;
146 }
147
148 /**
149 * Replaces the global MediaWikiServices instance.
150 *
151 * @since 1.28
152 *
153 * @note This is for use in PHPUnit tests only!
154 *
155 * @throws MWException if called outside of PHPUnit tests.
156 *
157 * @param MediaWikiServices $services The new MediaWikiServices object.
158 *
159 * @return MediaWikiServices The old MediaWikiServices object, so it can be restored later.
160 */
161 public static function forceGlobalInstance( MediaWikiServices $services ) {
162 if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
163 throw new MWException( __METHOD__ . ' must not be used outside unit tests.' );
164 }
165
166 $old = self::getInstance();
167 self::$instance = $services;
168
169 return $old;
170 }
171
172 /**
173 * Creates a new instance of MediaWikiServices and sets it as the global default
174 * instance. getInstance() will return a different MediaWikiServices object
175 * after every call to resetGlobalInstance().
176 *
177 * @since 1.28
178 *
179 * @warning This should not be used during normal operation. It is intended for use
180 * when the configuration has changed significantly since bootstrap time, e.g.
181 * during the installation process or during testing.
182 *
183 * @warning Calling resetGlobalInstance() may leave the application in an inconsistent
184 * state. Calling this is only safe under the ASSUMPTION that NO REFERENCE to
185 * any of the services managed by MediaWikiServices exist. If any service objects
186 * managed by the old MediaWikiServices instance remain in use, they may INTERFERE
187 * with the operation of the services managed by the new MediaWikiServices.
188 * Operating with a mix of services created by the old and the new
189 * MediaWikiServices instance may lead to INCONSISTENCIES and even DATA LOSS!
190 * Any class implementing LAZY LOADING is especially prone to this problem,
191 * since instances would typically retain a reference to a storage layer service.
192 *
193 * @see forceGlobalInstance()
194 * @see resetGlobalInstance()
195 * @see resetBetweenTest()
196 *
197 * @param Config|null $bootstrapConfig The Config object to be registered as the
198 * 'BootstrapConfig' service. This has to contain at least the information
199 * needed to set up the 'ConfigFactory' service. If not given, the bootstrap
200 * config of the old instance of MediaWikiServices will be re-used. If there
201 * was no previous instance, a new GlobalVarConfig object will be used to
202 * bootstrap the services.
203 *
204 * @param string $quick Set this to "quick" to allow expensive resources to be re-used.
205 * See SalvageableService for details.
206 *
207 * @throws MWException If called after MW_SERVICE_BOOTSTRAP_COMPLETE has been defined in
208 * Setup.php (unless MW_PHPUNIT_TEST or MEDIAWIKI_INSTALL or RUN_MAINTENANCE_IF_MAIN
209 * is defined).
210 */
211 public static function resetGlobalInstance( Config $bootstrapConfig = null, $quick = '' ) {
212 if ( self::$instance === null ) {
213 // no global instance yet, nothing to reset
214 return;
215 }
216
217 self::failIfResetNotAllowed( __METHOD__ );
218
219 if ( $bootstrapConfig === null ) {
220 $bootstrapConfig = self::$instance->getBootstrapConfig();
221 }
222
223 $oldInstance = self::$instance;
224
225 self::$instance = self::newInstance( $bootstrapConfig, 'load' );
226 self::$instance->importWiring( $oldInstance, [ 'BootstrapConfig' ] );
227
228 if ( $quick === 'quick' ) {
229 self::$instance->salvage( $oldInstance );
230 } else {
231 $oldInstance->destroy();
232 }
233 }
234
235 /** @noinspection PhpDocSignatureInspection */
236
237 /**
238 * Salvages the state of any salvageable service instances in $other.
239 *
240 * @note $other will have been destroyed when salvage() returns.
241 *
242 * @param MediaWikiServices $other
243 */
244 private function salvage( self $other ) {
245 foreach ( $this->getServiceNames() as $name ) {
246 // The service could be new in the new instance and not registered in the
247 // other instance (e.g. an extension that was loaded after the instantiation of
248 // the other instance. Skip this service in this case. See T143974
249 try {
250 $oldService = $other->peekService( $name );
251 } catch ( NoSuchServiceException $e ) {
252 continue;
253 }
254
255 if ( $oldService instanceof SalvageableService ) {
256 /** @var SalvageableService $newService */
257 $newService = $this->getService( $name );
258 $newService->salvage( $oldService );
259 }
260 }
261
262 $other->destroy();
263 }
264
265 /**
266 * Creates a new MediaWikiServices instance and initializes it according to the
267 * given $bootstrapConfig. In particular, all wiring files defined in the
268 * ServiceWiringFiles setting are loaded, and the MediaWikiServices hook is called.
269 *
270 * @param Config|null $bootstrapConfig The Config object to be registered as the
271 * 'BootstrapConfig' service.
272 *
273 * @param string $loadWiring set this to 'load' to load the wiring files specified
274 * in the 'ServiceWiringFiles' setting in $bootstrapConfig.
275 *
276 * @return MediaWikiServices
277 * @throws MWException
278 * @throws \FatalError
279 */
280 private static function newInstance( Config $bootstrapConfig, $loadWiring = '' ) {
281 $instance = new self( $bootstrapConfig );
282
283 // Load the default wiring from the specified files.
284 if ( $loadWiring === 'load' ) {
285 $wiringFiles = $bootstrapConfig->get( 'ServiceWiringFiles' );
286 $instance->loadWiringFiles( $wiringFiles );
287 }
288
289 // Provide a traditional hook point to allow extensions to configure services.
290 Hooks::run( 'MediaWikiServices', [ $instance ] );
291
292 return $instance;
293 }
294
295 /**
296 * Disables all storage layer services. After calling this, any attempt to access the
297 * storage layer will result in an error. Use resetGlobalInstance() to restore normal
298 * operation.
299 *
300 * @since 1.28
301 *
302 * @warning This is intended for extreme situations only and should never be used
303 * while serving normal web requests. Legitimate use cases for this method include
304 * the installation process. Test fixtures may also use this, if the fixture relies
305 * on globalState.
306 *
307 * @see resetGlobalInstance()
308 * @see resetChildProcessServices()
309 */
310 public static function disableStorageBackend() {
311 // TODO: also disable some Caches, JobQueues, etc
312 $destroy = [ 'DBLoadBalancer', 'DBLoadBalancerFactory' ];
313 $services = self::getInstance();
314
315 foreach ( $destroy as $name ) {
316 $services->disableService( $name );
317 }
318
319 ObjectCache::clear();
320 }
321
322 /**
323 * Resets any services that may have become stale after a child process
324 * returns from after pcntl_fork(). It's also safe, but generally unnecessary,
325 * to call this method from the parent process.
326 *
327 * @since 1.28
328 *
329 * @note This is intended for use in the context of process forking only!
330 *
331 * @see resetGlobalInstance()
332 * @see disableStorageBackend()
333 */
334 public static function resetChildProcessServices() {
335 // NOTE: for now, just reset everything. Since we don't know the interdependencies
336 // between services, we can't do this more selectively at this time.
337 self::resetGlobalInstance();
338
339 // Child, reseed because there is no bug in PHP:
340 // https://bugs.php.net/bug.php?id=42465
341 mt_srand( getmypid() );
342 }
343
344 /**
345 * Resets the given service for testing purposes.
346 *
347 * @since 1.28
348 *
349 * @warning This is generally unsafe! Other services may still retain references
350 * to the stale service instance, leading to failures and inconsistencies. Subclasses
351 * may use this method to reset specific services under specific instances, but
352 * it should not be exposed to application logic.
353 *
354 * @note With proper dependency injection used throughout the codebase, this method
355 * should not be needed. It is provided to allow tests that pollute global service
356 * instances to clean up.
357 *
358 * @param string $name
359 * @param bool $destroy Whether the service instance should be destroyed if it exists.
360 * When set to false, any existing service instance will effectively be detached
361 * from the container.
362 *
363 * @throws MWException if called outside of PHPUnit tests.
364 */
365 public function resetServiceForTesting( $name, $destroy = true ) {
366 if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
367 throw new MWException( 'resetServiceForTesting() must not be used outside unit tests.' );
368 }
369
370 $this->resetService( $name, $destroy );
371 }
372
373 /**
374 * Convenience method that throws an exception unless it is called during a phase in which
375 * resetting of global services is allowed. In general, services should not be reset
376 * individually, since that may introduce inconsistencies.
377 *
378 * @since 1.28
379 *
380 * This method will throw an exception if:
381 *
382 * - self::$resetInProgress is false (to allow all services to be reset together
383 * via resetGlobalInstance)
384 * - and MEDIAWIKI_INSTALL is not defined (to allow services to be reset during installation)
385 * - and MW_PHPUNIT_TEST is not defined (to allow services to be reset during testing)
386 *
387 * This method is intended to be used to safeguard against accidentally resetting
388 * global service instances that are not yet managed by MediaWikiServices. It is
389 * defined here in the MediaWikiServices services class to have a central place
390 * for managing service bootstrapping and resetting.
391 *
392 * @param string $method the name of the caller method, as given by __METHOD__.
393 *
394 * @throws MWException if called outside bootstrap mode.
395 *
396 * @see resetGlobalInstance()
397 * @see forceGlobalInstance()
398 * @see disableStorageBackend()
399 */
400 public static function failIfResetNotAllowed( $method ) {
401 if ( !defined( 'MW_PHPUNIT_TEST' )
402 && !defined( 'MW_PARSER_TEST' )
403 && !defined( 'MEDIAWIKI_INSTALL' )
404 && !defined( 'RUN_MAINTENANCE_IF_MAIN' )
405 && defined( 'MW_SERVICE_BOOTSTRAP_COMPLETE' )
406 ) {
407 throw new MWException( $method . ' may only be called during bootstrapping and unit tests!' );
408 }
409 }
410
411 /**
412 * @param Config $config The Config object to be registered as the 'BootstrapConfig' service.
413 * This has to contain at least the information needed to set up the 'ConfigFactory'
414 * service.
415 */
416 public function __construct( Config $config ) {
417 parent::__construct();
418
419 // Register the given Config object as the bootstrap config service.
420 $this->defineService( 'BootstrapConfig', function () use ( $config ) {
421 return $config;
422 } );
423 }
424
425 // CONVENIENCE GETTERS ////////////////////////////////////////////////////
426
427 /**
428 * @since 1.31
429 * @return ActorMigration
430 */
431 public function getActorMigration() {
432 return $this->getService( 'ActorMigration' );
433 }
434
435 /**
436 * @since 1.34
437 * @return BadFileLookup
438 */
439 public function getBadFileLookup() : BadFileLookup {
440 return $this->getService( 'BadFileLookup' );
441 }
442
443 /**
444 * @since 1.31
445 * @return BlobStore
446 */
447 public function getBlobStore() {
448 return $this->getService( '_SqlBlobStore' );
449 }
450
451 /**
452 * @since 1.31
453 * @return BlobStoreFactory
454 */
455 public function getBlobStoreFactory() {
456 return $this->getService( 'BlobStoreFactory' );
457 }
458
459 /**
460 * @since 1.34
461 * @return BlockManager
462 */
463 public function getBlockManager() : BlockManager {
464 return $this->getService( 'BlockManager' );
465 }
466
467 /**
468 * @since 1.33
469 * @return BlockRestrictionStore
470 */
471 public function getBlockRestrictionStore() : BlockRestrictionStore {
472 return $this->getService( 'BlockRestrictionStore' );
473 }
474
475 /**
476 * Returns the Config object containing the bootstrap configuration.
477 * Bootstrap configuration would typically include database credentials
478 * and other information that may be needed before the ConfigFactory
479 * service can be instantiated.
480 *
481 * @note This should only be used during bootstrapping, in particular
482 * when creating the MainConfig service. Application logic should
483 * use getMainConfig() to get a Config instances.
484 *
485 * @since 1.27
486 * @return Config
487 */
488 public function getBootstrapConfig() {
489 return $this->getService( 'BootstrapConfig' );
490 }
491
492 /**
493 * @since 1.32
494 * @return NameTableStore
495 */
496 public function getChangeTagDefStore() {
497 return $this->getService( 'NameTableStoreFactory' )->getChangeTagDef();
498 }
499
500 /**
501 * @since 1.31
502 * @return CommentStore
503 */
504 public function getCommentStore() {
505 return $this->getService( 'CommentStore' );
506 }
507
508 /**
509 * @since 1.27
510 * @return ConfigFactory
511 */
512 public function getConfigFactory() {
513 return $this->getService( 'ConfigFactory' );
514 }
515
516 /**
517 * @since 1.32
518 * @return ConfigRepository
519 */
520 public function getConfigRepository() {
521 return $this->getService( 'ConfigRepository' );
522 }
523
524 /**
525 * @since 1.29
526 * @return \ConfiguredReadOnlyMode
527 */
528 public function getConfiguredReadOnlyMode() {
529 return $this->getService( 'ConfiguredReadOnlyMode' );
530 }
531
532 /**
533 * @since 1.32
534 * @return \Language
535 */
536 public function getContentLanguage() {
537 return $this->getService( 'ContentLanguage' );
538 }
539
540 /**
541 * @since 1.31
542 * @return NameTableStore
543 */
544 public function getContentModelStore() {
545 return $this->getService( 'NameTableStoreFactory' )->getContentModels();
546 }
547
548 /**
549 * @since 1.28
550 * @return CryptHKDF
551 */
552 public function getCryptHKDF() {
553 return $this->getService( 'CryptHKDF' );
554 }
555
556 /**
557 * @since 1.33
558 * @return DateFormatterFactory
559 */
560 public function getDateFormatterFactory() {
561 return $this->getService( 'DateFormatterFactory' );
562 }
563
564 /**
565 * @since 1.28
566 * @return ILoadBalancer The main DB load balancer for the local wiki.
567 */
568 public function getDBLoadBalancer() {
569 return $this->getService( 'DBLoadBalancer' );
570 }
571
572 /**
573 * @since 1.28
574 * @return LBFactory
575 */
576 public function getDBLoadBalancerFactory() {
577 return $this->getService( 'DBLoadBalancerFactory' );
578 }
579
580 /**
581 * @since 1.27
582 * @return EventRelayerGroup
583 */
584 public function getEventRelayerGroup() {
585 return $this->getService( 'EventRelayerGroup' );
586 }
587
588 /**
589 * @since 1.34
590 * @return \ExternalStoreAccess
591 */
592 public function getExternalStoreAccess() {
593 return $this->getService( 'ExternalStoreAccess' );
594 }
595
596 /**
597 * @since 1.31
598 * @return \ExternalStoreFactory
599 */
600 public function getExternalStoreFactory() {
601 return $this->getService( 'ExternalStoreFactory' );
602 }
603
604 /**
605 * @since 1.28
606 * @return GenderCache
607 */
608 public function getGenderCache() {
609 return $this->getService( 'GenderCache' );
610 }
611
612 /**
613 * @since 1.31
614 * @return HttpRequestFactory
615 */
616 public function getHttpRequestFactory() {
617 return $this->getService( 'HttpRequestFactory' );
618 }
619
620 /**
621 * @since 1.28
622 * @return InterwikiLookup
623 */
624 public function getInterwikiLookup() {
625 return $this->getService( 'InterwikiLookup' );
626 }
627
628 /**
629 * @since 1.28
630 * @return LinkCache
631 */
632 public function getLinkCache() {
633 return $this->getService( 'LinkCache' );
634 }
635
636 /**
637 * LinkRenderer instance that can be used
638 * if no custom options are needed
639 *
640 * @since 1.28
641 * @return LinkRenderer
642 */
643 public function getLinkRenderer() {
644 return $this->getService( 'LinkRenderer' );
645 }
646
647 /**
648 * @since 1.28
649 * @return LinkRendererFactory
650 */
651 public function getLinkRendererFactory() {
652 return $this->getService( 'LinkRendererFactory' );
653 }
654
655 /**
656 * @since 1.28
657 * @return \BagOStuff
658 */
659 public function getLocalServerObjectCache() {
660 return $this->getService( 'LocalServerObjectCache' );
661 }
662
663 /**
664 * @since 1.34
665 * @return LockManagerGroupFactory
666 */
667 public function getLockManagerGroupFactory() : LockManagerGroupFactory {
668 return $this->getService( 'LockManagerGroupFactory' );
669 }
670
671 /**
672 * @since 1.32
673 * @return MagicWordFactory
674 */
675 public function getMagicWordFactory() {
676 return $this->getService( 'MagicWordFactory' );
677 }
678
679 /**
680 * Returns the Config object that provides configuration for MediaWiki core.
681 * This may or may not be the same object that is returned by getBootstrapConfig().
682 *
683 * @since 1.27
684 * @return Config
685 */
686 public function getMainConfig() {
687 return $this->getService( 'MainConfig' );
688 }
689
690 /**
691 * @since 1.28
692 * @return \BagOStuff
693 */
694 public function getMainObjectStash() {
695 return $this->getService( 'MainObjectStash' );
696 }
697
698 /**
699 * @since 1.28
700 * @return \WANObjectCache
701 */
702 public function getMainWANObjectCache() {
703 return $this->getService( 'MainWANObjectCache' );
704 }
705
706 /**
707 * @since 1.28
708 * @return MediaHandlerFactory
709 */
710 public function getMediaHandlerFactory() {
711 return $this->getService( 'MediaHandlerFactory' );
712 }
713
714 /**
715 * @since 1.34
716 * @return MessageCache
717 */
718 public function getMessageCache() : MessageCache {
719 return $this->getService( 'MessageCache' );
720 }
721
722 /**
723 * @since 1.34
724 * @return IMessageFormatterFactory
725 */
726 public function getMessageFormatterFactory() {
727 return $this->getService( 'MessageFormatterFactory' );
728 }
729
730 /**
731 * @since 1.28
732 * @return MimeAnalyzer
733 */
734 public function getMimeAnalyzer() {
735 return $this->getService( 'MimeAnalyzer' );
736 }
737
738 /**
739 * @since 1.34
740 * @return MovePageFactory
741 */
742 public function getMovePageFactory() : MovePageFactory {
743 return $this->getService( 'MovePageFactory' );
744 }
745
746 /**
747 * @since 1.34
748 * @return NamespaceInfo
749 */
750 public function getNamespaceInfo() : NamespaceInfo {
751 return $this->getService( 'NamespaceInfo' );
752 }
753
754 /**
755 * @since 1.32
756 * @return NameTableStoreFactory
757 */
758 public function getNameTableStoreFactory() {
759 return $this->getService( 'NameTableStoreFactory' );
760 }
761
762 /**
763 * ObjectFactory is intended for instantiating "handlers" from declarative definitions,
764 * such as Action API modules, special pages, or REST API handlers.
765 *
766 * @since 1.34
767 * @return ObjectFactory
768 */
769 public function getObjectFactory() {
770 return $this->getService( 'ObjectFactory' );
771 }
772
773 /**
774 * @since 1.32
775 * @return OldRevisionImporter
776 */
777 public function getOldRevisionImporter() {
778 return $this->getService( 'OldRevisionImporter' );
779 }
780
781 /**
782 * @return PageEditStash
783 * @since 1.34
784 */
785 public function getPageEditStash() {
786 return $this->getService( 'PageEditStash' );
787 }
788
789 /**
790 * @since 1.29
791 * @return Parser
792 */
793 public function getParser() {
794 return $this->getService( 'Parser' );
795 }
796
797 /**
798 * @since 1.30
799 * @return ParserCache
800 */
801 public function getParserCache() {
802 return $this->getService( 'ParserCache' );
803 }
804
805 /**
806 * @since 1.32
807 * @return ParserFactory
808 */
809 public function getParserFactory() {
810 return $this->getService( 'ParserFactory' );
811 }
812
813 /**
814 * @since 1.32
815 * @return PasswordFactory
816 */
817 public function getPasswordFactory() {
818 return $this->getService( 'PasswordFactory' );
819 }
820
821 /**
822 * @since 1.32
823 * @return StatsdDataFactoryInterface
824 */
825 public function getPerDbNameStatsdDataFactory() {
826 return $this->getService( 'PerDbNameStatsdDataFactory' );
827 }
828
829 /**
830 * @since 1.33
831 * @return PermissionManager
832 */
833 public function getPermissionManager() {
834 return $this->getService( 'PermissionManager' );
835 }
836
837 /**
838 * @since 1.31
839 * @return PreferencesFactory
840 */
841 public function getPreferencesFactory() {
842 return $this->getService( 'PreferencesFactory' );
843 }
844
845 /**
846 * @since 1.28
847 * @return ProxyLookup
848 */
849 public function getProxyLookup() {
850 return $this->getService( 'ProxyLookup' );
851 }
852
853 /**
854 * @since 1.29
855 * @return \ReadOnlyMode
856 */
857 public function getReadOnlyMode() {
858 return $this->getService( 'ReadOnlyMode' );
859 }
860
861 /**
862 * @since 1.34
863 * @return RepoGroup
864 */
865 public function getRepoGroup() : RepoGroup {
866 return $this->getService( 'RepoGroup' );
867 }
868
869 /**
870 * @since 1.33
871 * @return ResourceLoader
872 */
873 public function getResourceLoader() {
874 return $this->getService( 'ResourceLoader' );
875 }
876
877 /**
878 * @since 1.31
879 * @return RevisionFactory
880 */
881 public function getRevisionFactory() {
882 return $this->getService( 'RevisionFactory' );
883 }
884
885 /**
886 * @since 1.31
887 * @return RevisionLookup
888 */
889 public function getRevisionLookup() {
890 return $this->getService( 'RevisionLookup' );
891 }
892
893 /**
894 * @since 1.32
895 * @return RevisionRenderer
896 */
897 public function getRevisionRenderer() {
898 return $this->getService( 'RevisionRenderer' );
899 }
900
901 /**
902 * @since 1.31
903 * @return RevisionStore
904 */
905 public function getRevisionStore() {
906 return $this->getService( 'RevisionStore' );
907 }
908
909 /**
910 * @since 1.32
911 * @return RevisionStoreFactory
912 */
913 public function getRevisionStoreFactory() {
914 return $this->getService( 'RevisionStoreFactory' );
915 }
916
917 /**
918 * @since 1.27
919 * @return SearchEngine
920 */
921 public function newSearchEngine() {
922 // New engine object every time, since they keep state
923 return $this->getService( 'SearchEngineFactory' )->create();
924 }
925
926 /**
927 * @since 1.27
928 * @return SearchEngineConfig
929 */
930 public function getSearchEngineConfig() {
931 return $this->getService( 'SearchEngineConfig' );
932 }
933
934 /**
935 * @since 1.27
936 * @return SearchEngineFactory
937 */
938 public function getSearchEngineFactory() {
939 return $this->getService( 'SearchEngineFactory' );
940 }
941
942 /**
943 * @since 1.30
944 * @return CommandFactory
945 */
946 public function getShellCommandFactory() {
947 return $this->getService( 'ShellCommandFactory' );
948 }
949
950 /**
951 * @since 1.27
952 * @return SiteLookup
953 */
954 public function getSiteLookup() {
955 return $this->getService( 'SiteLookup' );
956 }
957
958 /**
959 * @since 1.27
960 * @return SiteStore
961 */
962 public function getSiteStore() {
963 return $this->getService( 'SiteStore' );
964 }
965
966 /**
967 * @since 1.27
968 * @return SkinFactory
969 */
970 public function getSkinFactory() {
971 return $this->getService( 'SkinFactory' );
972 }
973
974 /**
975 * @since 1.33
976 * @return SlotRoleRegistry
977 */
978 public function getSlotRoleRegistry() {
979 return $this->getService( 'SlotRoleRegistry' );
980 }
981
982 /**
983 * @since 1.31
984 * @return NameTableStore
985 */
986 public function getSlotRoleStore() {
987 return $this->getService( 'NameTableStoreFactory' )->getSlotRoles();
988 }
989
990 /**
991 * @since 1.32
992 * @return SpecialPageFactory
993 */
994 public function getSpecialPageFactory() : SpecialPageFactory {
995 return $this->getService( 'SpecialPageFactory' );
996 }
997
998 /**
999 * @since 1.27
1000 * @return IBufferingStatsdDataFactory
1001 */
1002 public function getStatsdDataFactory() {
1003 return $this->getService( 'StatsdDataFactory' );
1004 }
1005
1006 /**
1007 * @since 1.34
1008 * @return TempFSFileFactory
1009 */
1010 public function getTempFSFileFactory() : TempFSFileFactory {
1011 return $this->getService( 'TempFSFileFactory' );
1012 }
1013
1014 /**
1015 * @since 1.28
1016 * @return TitleFormatter
1017 */
1018 public function getTitleFormatter() {
1019 return $this->getService( 'TitleFormatter' );
1020 }
1021
1022 /**
1023 * @since 1.28
1024 * @return TitleParser
1025 */
1026 public function getTitleParser() {
1027 return $this->getService( 'TitleParser' );
1028 }
1029
1030 /**
1031 * @since 1.32
1032 * @return UploadRevisionImporter
1033 */
1034 public function getUploadRevisionImporter() {
1035 return $this->getService( 'UploadRevisionImporter' );
1036 }
1037
1038 /**
1039 * @since 1.28
1040 * @return VirtualRESTServiceClient
1041 */
1042 public function getVirtualRESTServiceClient() {
1043 return $this->getService( 'VirtualRESTServiceClient' );
1044 }
1045
1046 /**
1047 * @since 1.28
1048 * @return WatchedItemQueryService
1049 */
1050 public function getWatchedItemQueryService() {
1051 return $this->getService( 'WatchedItemQueryService' );
1052 }
1053
1054 /**
1055 * @since 1.28
1056 * @return WatchedItemStoreInterface
1057 */
1058 public function getWatchedItemStore() {
1059 return $this->getService( 'WatchedItemStore' );
1060 }
1061
1062 /**
1063 * @since 1.31
1064 * @return \OldRevisionImporter
1065 */
1066 public function getWikiRevisionOldRevisionImporter() {
1067 return $this->getService( 'OldRevisionImporter' );
1068 }
1069
1070 /**
1071 * @since 1.31
1072 * @return \OldRevisionImporter
1073 */
1074 public function getWikiRevisionOldRevisionImporterNoUpdates() {
1075 return $this->getService( 'WikiRevisionOldRevisionImporterNoUpdates' );
1076 }
1077
1078 /**
1079 * @since 1.31
1080 * @return \UploadRevisionImporter
1081 */
1082 public function getWikiRevisionUploadImporter() {
1083 return $this->getService( 'UploadRevisionImporter' );
1084 }
1085
1086 }