Daniel Kinzler has uploaded a new change for review. https://gerrit.wikimedia.org/r/286540
Change subject: Manage $wgCOntLang and $wgParser in MediaWikiServices. ...................................................................... Manage $wgCOntLang and $wgParser in MediaWikiServices. Some global singletons are currently accessible via global variables. This change introduces a mechanism for keeping such globals in sync with the service instances in the global MediaWikiServices instance. Change-Id: I70a3a4d2b342489433edd300698126916b436cb8 --- M autoload.php M includes/MediaWikiServices.php M includes/ServiceWiring.php A includes/Services/GlobalServiceStub.php M includes/Setup.php M includes/installer/CliInstaller.php M includes/installer/WebInstaller.php M tests/phpunit/includes/MediaWikiServicesTest.php A tests/phpunit/includes/Services/GlobalServiceStubTest.php M tests/phpunit/includes/Services/ServiceContainerTest.php 10 files changed, 178 insertions(+), 8 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/40/286540/1 diff --git a/autoload.php b/autoload.php index c8277f5..ce80a3a 100644 --- a/autoload.php +++ b/autoload.php @@ -796,6 +796,7 @@ 'MediaWiki\\Logger\\NullSpi' => __DIR__ . '/includes/debug/logger/NullSpi.php', 'MediaWiki\\Logger\\Spi' => __DIR__ . '/includes/debug/logger/Spi.php', 'MediaWiki\\Services\\DestructibleService' => __DIR__ . '/includes/Services/DestructibleService.php', + 'MediaWiki\\Services\\GlobalServiceStub' => __DIR__ . '/includes/Services/GlobalServiceStub.php', 'MediaWiki\\Services\\ServiceContainer' => __DIR__ . '/includes/Services/ServiceContainer.php', 'MediaWiki\\Services\\NoSuchServiceException' => __DIR__ . '/includes/Services/NoSuchServiceException.php', 'MediaWiki\\Services\\CannotReplaceActiveServiceException' => __DIR__ . '/includes/Services/CannotReplaceActiveServiceException.php', diff --git a/includes/MediaWikiServices.php b/includes/MediaWikiServices.php index 3792943..88cadfd 100644 --- a/includes/MediaWikiServices.php +++ b/includes/MediaWikiServices.php @@ -6,11 +6,13 @@ use EventRelayerGroup; use GlobalVarConfig; use Hooks; +use Language; use LBFactory; use Liuggio\StatsdClient\Factory\StatsdDataFactory; use LoadBalancer; use MediaWiki\Services\ServiceContainer; use MWException; +use Parser; use ResourceLoader; use SearchEngine; use SearchEngineConfig; @@ -18,6 +20,7 @@ use SiteLookup; use SiteStore; use SkinFactory; +use StubObject; /** * Service locator for MediaWiki core services. @@ -82,6 +85,7 @@ // configuration from. $bootstrapConfig = new GlobalVarConfig(); self::$instance = self::newInstance( $bootstrapConfig ); + self::$instance->updateLegacyGlobals(); } return self::$instance; @@ -105,6 +109,7 @@ $old = self::getInstance(); self::$instance = $services; + self::$instance->updateLegacyGlobals(); return $old; } @@ -158,6 +163,7 @@ self::$instance->destroy(); self::$instance = self::newInstance( $bootstrapConfig ); + self::$instance->updateLegacyGlobals(); } /** @@ -307,6 +313,39 @@ } ); } + /** + * Sets global variables to new service instances. + * + * Some legacy services are accessed via global variables, e.g. $wgUser and $wgContLang. + * In order to allow such service instances to be managed by MediaWikiServices, + * these global variables need to be kept in sync with the global MediaWikiServices + * instance. + * + * @warning: this should only be called on the global instance! + */ + private function updateLegacyGlobals() { + $bindings = [ + 'wgContLang' => 'ContentLanguage', + 'wgParser' => 'WikitextParser', + // TODO: $wgMemc, $wgParser (stub?), $wgOut + // XXX: $wgAuth may be set in LocalSettings.php! + ]; + + // update globals that are set and not stubs + foreach ( $bindings as $var => $service) { + if ( isset( $GLOBALS[$var] ) && !( $GLOBALS[$var] instanceof StubObject ) ) { + $GLOBALS[$var] = $this->getService( $service ); + } + } + + // XXX: initContLang() seems to be unused. Can we remove it? + if ( isset( $GLOBALS['wgContLang'] ) ) { + $GLOBALS['wgContLang']->initContLang(); + } + + // TODO: from RequestContext: $wgUser, $wgLang (stub?), $wgRequest, $wgTitle + } + // CONVENIENCE GETTERS //////////////////////////////////////////////////// /** @@ -413,6 +452,20 @@ return $this->getService( 'DBLoadBalancer' ); } + /** + * @return Language The Language object for the site's content language. + */ + public function getContentLanguage() { + return $this->getService( 'ContentLanguage' ); + } + + /** + * @return Parser + */ + public function getWikitextParser() { + return $this->getService( 'WikitextParser' ); + } + /////////////////////////////////////////////////////////////////////////// // NOTE: When adding a service getter here, don't forget to add a test // case for it in MediaWikiServicesTest::provideGetters() and in diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 69cb82e..4103e07 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -92,6 +92,22 @@ return $services->getConfigFactory()->makeConfig( 'main' ); }, + 'ContentLanguage' => function( MediaWikiServices $services ) { + $code = $services->getBootstrapConfig()->get( 'LanguageCode' ); + + //TODO: turn Language::factory into an actual service + $lang = Language::factory( $code ); + $lang->initEncoding(); + return $lang; + }, + + 'WikitextParser' => function( MediaWikiServices $services ) { + $conf = $services->getBootstrapConfig()->get( 'ParserConf' ); + $class = $conf['class']; + + return new $class( $conf ); + }, + 'StatsdDataFactory' => function( MediaWikiServices $services ) { return new BufferingStatsdDataFactory( rtrim( $services->getMainConfig()->get( 'StatsdMetricPrefix' ), '.' ) @@ -107,8 +123,10 @@ }, 'SearchEngineConfig' => function( MediaWikiServices $services ) { - global $wgContLang; - return new SearchEngineConfig( $services->getMainConfig(), $wgContLang ); + return new SearchEngineConfig( + $services->getMainConfig(), + $services->getContentLanguage() + ); }, 'SkinFactory' => function( MediaWikiServices $services ) { diff --git a/includes/Services/GlobalServiceStub.php b/includes/Services/GlobalServiceStub.php new file mode 100644 index 0000000..a91a835 --- /dev/null +++ b/includes/Services/GlobalServiceStub.php @@ -0,0 +1,63 @@ +<?php +namespace MediaWiki\Services; + +/** + * Delayed loading of a global service instance. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + */ +use MediaWiki\MediaWikiServices; +use StubObject; +use Wikimedia\Assert\Assert; + +/** + * Delayed loading of a global service instance. + * The service instance will be acquired from MediaWikiServices::getInstance()->getService(). + * + * @see MediaWikiServices + */ +class GlobalServiceStub extends StubObject { + + /** + * @var string + */ + protected $serviceName; + + /** + * DeprecatedGlobal constructor. + * + * @param string $variableName + * @param string $serviceName + */ + function __construct( $variableName, $serviceName ) { + Assert::parameterType( 'string', $variableName, '$variableName' ); + Assert::parameterType( 'string', $serviceName, '$serviceName' ); + + parent::__construct( $variableName ); + + $this->serviceName = $serviceName; + } + + // @codingStandardsIgnoreStart + // PSR2.Methods.MethodDeclaration.Underscore + // PSR2.Classes.PropertyDeclaration.ScopeMissing + function _newObject() { + return MediaWikiServices::getInstance()->getService( $this->serviceName ); + } + // @codingStandardsIgnoreEnd +} diff --git a/includes/Setup.php b/includes/Setup.php index b96ca3d..cd91bff 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -24,6 +24,7 @@ * @file */ use MediaWiki\MediaWikiServices; +use MediaWiki\Services\GlobalServiceStub; /** * This file is not a valid entry point, perform no further processing unless @@ -684,9 +685,7 @@ /** * @var Language $wgContLang */ -$wgContLang = Language::factory( $wgLanguageCode ); -$wgContLang->initEncoding(); -$wgContLang->initContLang(); +$wgContLang = MediaWikiServices::getInstance()->getContentLanguage(); // Now that variant lists may be available... $wgRequest->interpolateTitle(); @@ -781,7 +780,7 @@ /** * @var Parser $wgParser */ -$wgParser = new StubObject( 'wgParser', $wgParserConf['class'], [ $wgParserConf ] ); +$wgParser = new GlobalServiceStub( 'wgParser', 'WikitextParser' ); /** * @var Title $wgTitle diff --git a/includes/installer/CliInstaller.php b/includes/installer/CliInstaller.php index 661c3ec..c37e2b9 100644 --- a/includes/installer/CliInstaller.php +++ b/includes/installer/CliInstaller.php @@ -76,6 +76,9 @@ $wgLang = Language::factory( $option['lang'] ); $wgLanguageCode = $option['lang']; RequestContext::getMain()->setLanguage( $wgLang ); + + // FIXME: we should call MediaWikiServices::resetGlobalInstance() here. + // TODO: wrap $this->getVar into a Config object and pass it to resetGlobalInstance } $this->setVar( 'wgSitename', $siteName ); diff --git a/includes/installer/WebInstaller.php b/includes/installer/WebInstaller.php index 4c4e6b7..bd0af48 100644 --- a/includes/installer/WebInstaller.php +++ b/includes/installer/WebInstaller.php @@ -517,6 +517,9 @@ $wgLanguageCode = $this->getVar( 'wgLanguageCode' ); $wgContLang = Language::factory( $wgLanguageCode ); } + + // FIXME: we should call MediaWikiServices::resetGlobalInstance() here. + // TODO: wrap $this->getVar into a Config object and pass it to resetGlobalInstance } /** diff --git a/tests/phpunit/includes/MediaWikiServicesTest.php b/tests/phpunit/includes/MediaWikiServicesTest.php index df0ce8e..eb1cdf2 100644 --- a/tests/phpunit/includes/MediaWikiServicesTest.php +++ b/tests/phpunit/includes/MediaWikiServicesTest.php @@ -7,6 +7,7 @@ * @covers MediaWiki\MediaWikiServices * * @group MediaWiki + * @group MediaWikiServices */ class MediaWikiServicesTest extends PHPUnit_Framework_TestCase { @@ -19,6 +20,8 @@ $testConfig = new HashConfig(); $testConfig->set( 'ServiceWiringFiles', $globalConfig->get( 'ServiceWiringFiles' ) ); $testConfig->set( 'ConfigRegistry', $globalConfig->get( 'ConfigRegistry' ) ); + $testConfig->set( 'ParserConf', $globalConfig->get( 'ParserConf' ) ); + $testConfig->set( 'LanguageCode', 'en' ); return $testConfig; } @@ -235,8 +238,10 @@ 'SearchEngineFactory' => [ 'SearchEngineFactory', SearchEngineFactory::class ], 'SearchEngineConfig' => [ 'SearchEngineConfig', SearchEngineConfig::class ], 'SkinFactory' => [ 'SkinFactory', SkinFactory::class ], - 'DBLoadBalancerFactory' => [ 'DBLoadBalancerFactory', 'LBFactory' ], - 'DBLoadBalancer' => [ 'DBLoadBalancer', 'LoadBalancer' ], + 'DBLoadBalancerFactory' => [ 'DBLoadBalancerFactory', LBFactory::class ], + 'DBLoadBalancer' => [ 'DBLoadBalancer', LoadBalancer::class ], + 'ContentLanguage' => [ 'ContentLanguage', Language::class ], + 'WikitextParser' => [ 'WikitextParser', Parser::class ], ]; } diff --git a/tests/phpunit/includes/Services/GlobalServiceStubTest.php b/tests/phpunit/includes/Services/GlobalServiceStubTest.php new file mode 100644 index 0000000..97d838c --- /dev/null +++ b/tests/phpunit/includes/Services/GlobalServiceStubTest.php @@ -0,0 +1,24 @@ +<?php +use MediaWiki\MediaWikiServices; +use MediaWiki\Services\GlobalServiceStub; +use MediaWiki\Services\ServiceContainer; + +/** + * @covers MediaWiki\Services\GlobalServiceStub + * + * @group MediaWiki + * @group MediaWikiServices + */ +class GlobalServiceStubTest extends PHPUnit_Framework_TestCase { + + public function testUnstub() { + global $test_GlobalServiceStubTest; + + $test_GlobalServiceStubTest = new GlobalServiceStub( 'test_GlobalServiceStubTest', 'ContentLanguage' ); + StubObject::unstub( $test_GlobalServiceStubTest ); + + $expected = MediaWikiServices::getInstance()->getService( 'ContentLanguage' ); + $this->assertSame( $expected, $test_GlobalServiceStubTest ); + } + +} diff --git a/tests/phpunit/includes/Services/ServiceContainerTest.php b/tests/phpunit/includes/Services/ServiceContainerTest.php index 933777c..2fab27d 100644 --- a/tests/phpunit/includes/Services/ServiceContainerTest.php +++ b/tests/phpunit/includes/Services/ServiceContainerTest.php @@ -5,6 +5,7 @@ * @covers MediaWiki\Services\ServiceContainer * * @group MediaWiki + * @group MediaWikiServices */ class ServiceContainerTest extends PHPUnit_Framework_TestCase { -- To view, visit https://gerrit.wikimedia.org/r/286540 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I70a3a4d2b342489433edd300698126916b436cb8 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: Daniel Kinzler <daniel.kinz...@wikimedia.de> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits