Add TitleParser and TitleFormatter to MediaWikiServices
authorKunal Mehta <legoktm@member.fsf.org>
Mon, 25 Apr 2016 05:41:32 +0000 (22:41 -0700)
committerKunal Mehta <legoktm@member.fsf.org>
Wed, 11 May 2016 17:18:40 +0000 (10:18 -0700)
Depends-On: Ibfd0a7f98f50506cd8402f966682f320bf715c8a
Change-Id: I81d48616afd1ab2bde1a5f1d12f4aefb1c866d43

includes/MediaWikiServices.php
includes/ServiceWiring.php
includes/Title.php
tests/parser/parserTest.inc
tests/phpunit/includes/MediaWikiServicesTest.php
tests/phpunit/includes/TitleTest.php
tests/phpunit/includes/parser/NewParserTest.php

index 9e18fd1..5bb5597 100644 (file)
@@ -20,6 +20,8 @@ use SiteLookup;
 use SiteStore;
 use WatchedItemStore;
 use SkinFactory;
+use TitleFormatter;
+use TitleParser;
 
 /**
  * Service locator for MediaWiki core services.
@@ -458,6 +460,21 @@ class MediaWikiServices extends ServiceContainer {
        public function getGenderCache() {
                return $this->getService( 'GenderCache' );
        }
+       /**
+        * @since 1.28
+        * @return TitleFormatter
+        */
+       public function getTitleFormatter() {
+               return $this->getService( 'TitleFormatter' );
+       }
+
+       /**
+        * @since 1.28
+        * @return TitleParser
+        */
+       public function getTitleParser() {
+               return $this->getService( 'TitleParser' );
+       }
 
        ///////////////////////////////////////////////////////////////////////////
        // NOTE: When adding a service getter here, don't forget to add a test
index e282bda..aa99a71 100644 (file)
@@ -143,6 +143,24 @@ return [
                return new GenderCache();
        },
 
+       '_MediaWikiTitleCodec' => function( MediaWikiServices $services ) {
+               global $wgContLang;
+
+               return new MediaWikiTitleCodec(
+                       $wgContLang,
+                       $services->getGenderCache(),
+                       $services->getMainConfig()->get( 'LocalInterwikis' )
+               );
+       },
+
+       'TitleFormatter' => function( MediaWikiServices $services ) {
+               return $services->getService( '_MediaWikiTitleCodec' );
+       },
+
+       'TitleParser' => function( MediaWikiServices $services ) {
+               return $services->getService( '_MediaWikiTitleCodec' );
+       },
+
        ///////////////////////////////////////////////////////////////////////////
        // NOTE: When adding a service here, don't forget to add a getter function
        // in the MediaWikiServices class. The convenience getter should just call
index 65b2d3a..d070609 100644 (file)
@@ -22,7 +22,6 @@
  * @file
  */
 use MediaWiki\Linker\LinkTarget;
-
 use MediaWiki\MediaWikiServices;
 
 /**
@@ -159,42 +158,6 @@ class Title implements LinkTarget {
        private $mIsBigDeletion = null;
        // @}
 
-       /**
-        * B/C kludge: provide a TitleParser for use by Title.
-        * Ideally, Title would have no methods that need this.
-        * Avoid usage of this singleton by using TitleValue
-        * and the associated services when possible.
-        *
-        * @return MediaWikiTitleCodec
-        */
-       private static function getMediaWikiTitleCodec() {
-               global $wgContLang, $wgLocalInterwikis;
-
-               static $titleCodec = null;
-               static $titleCodecFingerprint = null;
-
-               // $wgContLang and $wgLocalInterwikis may change (especially while testing),
-               // make sure we are using the right one. To detect changes over the course
-               // of a request, we remember a fingerprint of the config used to create the
-               // codec singleton, and re-create it if the fingerprint doesn't match.
-               $fingerprint = spl_object_hash( $wgContLang ) . '|' . implode( '+', $wgLocalInterwikis );
-
-               if ( $fingerprint !== $titleCodecFingerprint ) {
-                       $titleCodec = null;
-               }
-
-               if ( !$titleCodec ) {
-                       $titleCodec = new MediaWikiTitleCodec(
-                               $wgContLang,
-                               GenderCache::singleton(),
-                               $wgLocalInterwikis
-                       );
-                       $titleCodecFingerprint = $fingerprint;
-               }
-
-               return $titleCodec;
-       }
-
        /**
         * B/C kludge: provide a TitleParser for use by Title.
         * Ideally, Title would have no methods that need this.
@@ -204,9 +167,7 @@ class Title implements LinkTarget {
         * @return TitleFormatter
         */
        private static function getTitleFormatter() {
-               // NOTE: we know that getMediaWikiTitleCodec() returns a MediaWikiTitleCodec,
-               //      which implements TitleFormatter.
-               return self::getMediaWikiTitleCodec();
+               return MediaWikiServices::getInstance()->getTitleFormatter();
        }
 
        function __construct() {
@@ -3334,9 +3295,11 @@ class Title implements LinkTarget {
                // @note: splitTitleString() is a temporary hack to allow MediaWikiTitleCodec to share
                //        the parsing code with Title, while avoiding massive refactoring.
                // @todo: get rid of secureAndSplit, refactor parsing code.
-               $titleParser = self::getMediaWikiTitleCodec();
+               // @note: getTitleParser() returns a TitleParser implementation which does not have a
+               //        splitTitleString method, but the only implementation (MediaWikiTitleCodec) does
+               $titleCodec = MediaWikiServices::getInstance()->getTitleParser();
                // MalformedTitleException can be thrown here
-               $parts = $titleParser->splitTitleString( $dbkey, $this->getDefaultNamespace() );
+               $parts = $titleCodec->splitTitleString( $dbkey, $this->getDefaultNamespace() );
 
                # Fill fields
                $this->setFragment( '#' . $parts['fragment'] );
index 78e5f6f..ccb86d0 100644 (file)
@@ -27,6 +27,7 @@
  * @file
  * @ingroup Testing
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * @ingroup Testing
@@ -331,6 +332,18 @@ class ParserTest {
                Hooks::clear( 'InterwikiLoadPrefix' );
        }
 
+       /**
+        * Reset the Title-related services that need resetting
+        * for each test
+        */
+       public static function resetTitleServices() {
+               $services = MediaWikiServices::getInstance();
+               $services->resetServiceForTesting( 'TitleFormatter' );
+               $services->resetServiceForTesting( 'TitleParser' );
+               $services->resetServiceForTesting( '_MediaWikiTitleCodec' );
+
+       }
+
        public function setupRecorder( $options ) {
                if ( isset( $options['record'] ) ) {
                        $this->recorder = new DbTestRecorder( $this );
@@ -958,6 +971,8 @@ class ParserTest {
                MWTidy::destroySingleton();
                RepoGroup::destroySingleton();
 
+               self::resetTitleServices();
+
                return $context;
        }
 
index 4f917a5..467a2ad 100644 (file)
@@ -200,6 +200,10 @@ class MediaWikiServicesTest extends PHPUnit_Framework_TestCase {
 
                // All getters should be named just like the service, with "get" added.
                foreach ( $getServiceCases as $name => $case ) {
+                       if ( $name[0] === '_' ) {
+                               // Internal service, no getter
+                               continue;
+                       }
                        list( $service, $class ) = $case;
                        $getterCases[$name] = [
                                'get' . $service,
@@ -239,6 +243,9 @@ class MediaWikiServicesTest extends PHPUnit_Framework_TestCase {
                        'DBLoadBalancer' => [ 'DBLoadBalancer', 'LoadBalancer' ],
                        'WatchedItemStore' => [ 'WatchedItemStore', WatchedItemStore::class ],
                        'GenderCache' => [ 'GenderCache', GenderCache::class ],
+                       '_MediaWikiTitleCodec' => [ '_MediaWikiTitleCodec', MediaWikiTitleCodec::class ],
+                       'TitleFormatter' => [ 'TitleFormatter', TitleFormatter::class ],
+                       'TitleParser' => [ 'TitleParser', TitleParser::class ],
                ];
        }
 
index 7d025d2..496f18f 100644 (file)
@@ -144,6 +144,13 @@ class TitleTest extends MediaWikiTestCase {
                                ]
                        ]
                ] );
+
+               // Reset TitleParser since we modified $wgLocalInterwikis
+               $this->setService( 'TitleParser', new MediaWikiTitleCodec(
+                               Language::factory( 'en' ),
+                               new GenderCache(),
+                               [ 'localtestiw' ]
+               ) );
        }
 
        /**
index 22bb237..4c973e5 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 /**
  * Although marked as a stub, can work independently.
  *
@@ -179,6 +178,7 @@ class NewParserTest extends MediaWikiTestCase {
 
                MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
                $wgContLang->resetNamespaces(); # reset namespace cache
+               ParserTest::resetTitleServices();
        }
 
        protected function tearDown() {