Page MenuHomePhabricator

"Allow $wgSettings to be used in LocalSettings.php" breaks SMW
Closed, ResolvedPublic

Description

After updating MediaWiki core to master in translatewiki.net (more specifically to rMW80fd54ffb028: Allow $wgSettings to be used in LocalSettings.), we observe the following issues when running maintenance/rebuildLocalisationCache.php:

PHP Notice:  Undefined index: wgVersion in /srv/mediawiki/workdir/extensions/SemanticMediaWiki/src/SetupCheck.php on line 190
PHP Notice:  Undefined index: wgLanguageCode in /srv/mediawiki/workdir/extensions/SemanticMediaWiki/src/SetupCheck.php on line 191

A stacktrace (with xdebug in local development environment) is provided for your convenience:

PHP Notice:  Undefined index: wgLanguageCode in /srv/mediawiki/workdir/extensions/SemanticMediaWiki/src/SetupCheck.php on line 191
PHP Stack trace:
PHP   1. {main}() /srv/mediawiki/workdir/maintenance/rebuildLocalisationCache.php:0
PHP   2. require_once() /srv/mediawiki/workdir/maintenance/rebuildLocalisationCache.php:248
PHP   3. require_once() /srv/mediawiki/workdir/maintenance/doMaintenance.php:90
PHP   4. require_once() /srv/mediawiki/workdir/includes/Setup.php:109
PHP   5. ComposerAutoloaderInitbfb9dfa5d5c7756c1cea00c2480225c2::getLoader() /srv/mediawiki/workdir/vendor/autoload.php:7
PHP   6. composerRequirebfb9dfa5d5c7756c1cea00c2480225c2($fileIdentifier = 'cd9b6b6b76aed1304a64986142337d3a', $file = '/srv/mediawiki/workdir/vendor/composer/../../extensions/SemanticMediaWiki/SemanticMediaWiki.php') /srv/mediawiki/workdir/vendor/composer/autoload_real.php:65
PHP   7. require() /srv/mediawiki/workdir/vendor/composer/autoload_real.php:75
PHP   8. SemanticMediaWiki::load() /srv/mediawiki/workdir/extensions/SemanticMediaWiki/SemanticMediaWiki.php:18
PHP   9. SMW\Setup::registerExtensionCheck([....]) /srv/mediawiki/workdir/extensions/SemanticMediaWiki/SemanticMediaWiki.php:72
PHP  10. SMW\SetupCheck::newFromDefaults($setupFile = *uninitialized*) /srv/mediawiki/workdir/extensions/SemanticMediaWiki/src/Setup.php:50

In addition to this, the wiki no longer works and displays this warning:

MediaWiki internal error.

Original exception: [f8b8165ba0180c7aaa5bf807] / MWException: Error: invalid magic word 'ask'
Backtrace:
from /srv/mediawiki/workdir/includes/MagicWord.php(129)
#0 /srv/mediawiki/workdir/includes/MagicWordFactory.php(230): MagicWord->load()
#1 /srv/mediawiki/workdir/includes/parser/Parser.php(4942): MagicWordFactory->get()
#2 /srv/mediawiki/workdir/extensions/SemanticMediaWiki/src/ParserFunctionFactory.php(77): Parser->setFunctionHook()
#3 /srv/mediawiki/workdir/extensions/SemanticMediaWiki/src/MediaWiki/Hooks.php(1205): SMW\ParserFunctionFactory->registerFunctionHandlers()
#4 /srv/mediawiki/workdir/includes/HookContainer/HookContainer.php(338): SMW\MediaWiki\Hooks->onParserFirstCallInit()
#5 /srv/mediawiki/workdir/includes/HookContainer/HookContainer.php(137): MediaWiki\HookContainer\HookContainer->callLegacyHook()
#6 /srv/mediawiki/workdir/includes/HookContainer/HookRunner.php(2868): MediaWiki\HookContainer\HookContainer->run()
#7 /srv/mediawiki/workdir/includes/parser/Parser.php(528): MediaWiki\HookContainer\HookRunner->onParserFirstCallInit()
#8 /srv/mediawiki/workdir/includes/parser/ParserFactory.php(196): Parser->__construct()
#9 /srv/mediawiki/workdir/includes/ServiceWiring.php(1186): ParserFactory->create()
#10 /srv/mediawiki/workdir/vendor/wikimedia/services/src/ServiceContainer.php(447): Wikimedia\Services\ServiceContainer::{closure}()
#11 /srv/mediawiki/workdir/vendor/wikimedia/services/src/ServiceContainer.php(416): Wikimedia\Services\ServiceContainer->createService()
#12 /srv/mediawiki/workdir/includes/MediaWikiServices.php(289): Wikimedia\Services\ServiceContainer->getService()
#13 /srv/mediawiki/workdir/includes/MediaWikiServices.php(1345): MediaWiki\MediaWikiServices->getService()
#14 /srv/mediawiki/workdir/includes/preferences/DefaultPreferencesFactory.php(209): MediaWiki\MediaWikiServices->getParser()
#15 /srv/mediawiki/workdir/extensions/GlobalPreferences/includes/Hooks.php(215): MediaWiki\Preferences\DefaultPreferencesFactory->__construct()
#16 /srv/mediawiki/workdir/vendor/wikimedia/services/src/ServiceContainer.php(447): GlobalPreferences\Hooks::GlobalPreferences\{closure}()
#17 /srv/mediawiki/workdir/vendor/wikimedia/services/src/ServiceContainer.php(416): Wikimedia\Services\ServiceContainer->createService()
#18 /srv/mediawiki/workdir/includes/MediaWikiServices.php(289): Wikimedia\Services\ServiceContainer->getService()
#19 /srv/mediawiki/workdir/includes/MediaWikiServices.php(1417): MediaWiki\MediaWikiServices->getService()
#20 /srv/mediawiki/workdir/extensions/GlobalPreferences/includes/Hooks.php(286): MediaWiki\MediaWikiServices->getPreferencesFactory()
#21 /srv/mediawiki/workdir/extensions/GlobalPreferences/includes/Hooks.php(42): GlobalPreferences\Hooks::getPreferencesFactory()
#22 /srv/mediawiki/workdir/includes/HookContainer/HookContainer.php(338): GlobalPreferences\Hooks::onLoadUserOptions()
#23 /srv/mediawiki/workdir/includes/HookContainer/HookContainer.php(137): MediaWiki\HookContainer\HookContainer->callLegacyHook()
#24 /srv/mediawiki/workdir/includes/HookContainer/HookRunner.php(4197): MediaWiki\HookContainer\HookContainer->run()
#25 /srv/mediawiki/workdir/includes/user/UserOptionsManager.php(633): MediaWiki\HookContainer\HookRunner->onLoadUserOptions()
#26 /srv/mediawiki/workdir/includes/user/UserOptionsManager.php(497): MediaWiki\User\UserOptionsManager->loadOriginalOptions()
#27 /srv/mediawiki/workdir/includes/user/UserOptionsManager.php(147): MediaWiki\User\UserOptionsManager->loadUserOptions()
#28 /srv/mediawiki/workdir/includes/user/User.php(2356): MediaWiki\User\UserOptionsManager->getOption()
#29 /srv/mediawiki/workdir/includes/context/RequestContext.php(384): User->getOption()
#30 /srv/mediawiki/workdir/includes/StubUserLang.php(34): RequestContext->getLanguage()
#31 /srv/mediawiki/workdir/includes/StubObject.php(223): StubUserLang->_newObject()
#32 /srv/mediawiki/workdir/includes/StubObject.php(103): StubObject->_unstub()
#33 /srv/mediawiki/workdir/includes/content/ContentHandler.php(736): StubObject::unstub()
#34 /srv/mediawiki/workdir/includes/Title.php(3963): ContentHandler->getPageLanguage()
#35 /srv/mediawiki/workdir/includes/OutputPage.php(2370): Title->getPageLanguage()
#36 /srv/mediawiki/workdir/includes/OutputPage.php(2502): OutputPage->addAcceptLanguage()
#37 /srv/mediawiki/workdir/includes/OutputPage.php(2613): OutputPage->sendCacheControl()
#38 /srv/mediawiki/workdir/includes/MediaWiki.php(939): OutputPage->output()
#39 /srv/mediawiki/workdir/includes/MediaWiki.php(952): MediaWiki::{closure}()
#40 /srv/mediawiki/workdir/includes/MediaWiki.php(559): MediaWiki->main()
#41 /srv/mediawiki/workdir/index.php(53): MediaWiki->run()
#42 /srv/mediawiki/workdir/index.php(46): wfIndexMain()
#43 {main}

Exception caught inside exception handler: [f8b8165ba0180c7aaa5bf807] / MWException: Error: invalid magic word 'ask'
Backtrace:
from /srv/mediawiki/workdir/includes/MagicWord.php(129)
#0 /srv/mediawiki/workdir/includes/MagicWordFactory.php(230): MagicWord->load()
#1 /srv/mediawiki/workdir/includes/parser/Parser.php(4942): MagicWordFactory->get()
#2 /srv/mediawiki/workdir/extensions/SemanticMediaWiki/src/ParserFunctionFactory.php(77): Parser->setFunctionHook()
#3 /srv/mediawiki/workdir/extensions/SemanticMediaWiki/src/MediaWiki/Hooks.php(1205): SMW\ParserFunctionFactory->registerFunctionHandlers()
#4 /srv/mediawiki/workdir/includes/HookContainer/HookContainer.php(338): SMW\MediaWiki\Hooks->onParserFirstCallInit()
#5 /srv/mediawiki/workdir/includes/HookContainer/HookContainer.php(137): MediaWiki\HookContainer\HookContainer->callLegacyHook()
#6 /srv/mediawiki/workdir/includes/HookContainer/HookRunner.php(2868): MediaWiki\HookContainer\HookContainer->run()
#7 /srv/mediawiki/workdir/includes/parser/Parser.php(528): MediaWiki\HookContainer\HookRunner->onParserFirstCallInit()
#8 /srv/mediawiki/workdir/includes/parser/ParserFactory.php(196): Parser->__construct()
#9 /srv/mediawiki/workdir/includes/ServiceWiring.php(1186): ParserFactory->create()
#10 /srv/mediawiki/workdir/vendor/wikimedia/services/src/ServiceContainer.php(447): Wikimedia\Services\ServiceContainer::{closure}()
#11 /srv/mediawiki/workdir/vendor/wikimedia/services/src/ServiceContainer.php(416): Wikimedia\Services\ServiceContainer->createService()
#12 /srv/mediawiki/workdir/includes/MediaWikiServices.php(289): Wikimedia\Services\ServiceContainer->getService()
#13 /srv/mediawiki/workdir/includes/MediaWikiServices.php(1345): MediaWiki\MediaWikiServices->getService()
#14 /srv/mediawiki/workdir/includes/cache/MessageCache.php(1260): MediaWiki\MediaWikiServices->getParser()
#15 /srv/mediawiki/workdir/includes/cache/MessageCache.php(1239): MessageCache->getParser()
#16 /srv/mediawiki/workdir/includes/language/Message.php(1438): MessageCache->transform()
#17 /srv/mediawiki/workdir/includes/language/Message.php(977): Message->transformText()
#18 /srv/mediawiki/workdir/includes/language/Message.php(1035): Message->format()
#19 /srv/mediawiki/workdir/includes/OutputPage.php(949): Message->text()
#20 /srv/mediawiki/workdir/includes/OutputPage.php(998): OutputPage->setHTMLTitle()
#21 /srv/mediawiki/workdir/includes/OutputPage.php(2727): OutputPage->setPageTitle()
#22 /srv/mediawiki/workdir/includes/exception/MWException.php(179): OutputPage->prepareErrorPage()
#23 /srv/mediawiki/workdir/includes/exception/MWException.php(231): MWException->reportHTML()
#24 /srv/mediawiki/workdir/includes/exception/MWExceptionHandler.php(105): MWException->report()
#25 /srv/mediawiki/workdir/includes/exception/MWExceptionHandler.php(202): MWExceptionHandler::report()
#26 /srv/mediawiki/workdir/includes/MediaWiki.php(578): MWExceptionHandler::handleException()
#27 /srv/mediawiki/workdir/index.php(53): MediaWiki->run()
#28 /srv/mediawiki/workdir/index.php(46): wfIndexMain()
#29 {main}

This is likely because SMW does not see wgLanguageCode and fails to provide localisations due to that.

Event Timeline

SMW uses composer's autoloading mechanism to run setup code (instead of wfLoadExtension). MediaWiki core is no longer doing all the setup before that point.

If this part of the change is intentional, we would like a temporary solution to keep SMW running until a permanent fix is in place in SMW master branch.

What the path above did was to move composer autoloading before loading DefaultSettings.php. Which should not have mattered - composer dependencies shouldn't really depend on MediaWiki.

Is this composer-based extension loading something that we explicitly support or supported at some point, or is it custom witchcraft from SemanticMediawiki?

Is this composer-based extension loading something that we explicitly support or supported at some point, or is it custom witchcraft from SemanticMediawiki?

Installing extensions (and their dependencies) via composer is supported. But composer autoloading should not run code that depends on mediawiki. It shouldn't run any code at all, I think...

Anyway: we need the ability to use things that come from libraries when loading SefaultSettings.php. I don't really see a way around this...

SMW has been using it for a long time: https://www.semantic-mediawiki.org/wiki/Help:Installation/Quick_guide. It's the only one to my knowledge.

It would be good if it would use the standard wfLoadExtension, but I don't know how involved change that is.

Relevant code for reference:
https://github.com/SemanticMediaWiki/SemanticMediaWiki/blob/a25e511471dad2eaa3b37d3d365b588921f81c51/src/SetupCheck.php#L190

Interestingly, it also uses wgLanguageCode, which afaics will always be 'en' at this point, since this happens before LocalSettings have been loaded.

What the path above did was to move composer autoloading before loading DefaultSettings.php. Which should not have mattered - composer dependencies shouldn't really depend on MediaWiki.

Is this composer-based extension loading something that we explicitly support or supported at some point, or is it custom witchcraft from SemanticMediawiki?

T61872: Add mechanism to prevent autoloading of Composer installed extensions via LocalSettings.php
T249573: Remove support for extensions requiring a MediaWiki version via Composer

Hacky workaround: make a composer package that sets the expected global variables...

Ok, from reading all the tickets posted by @Reedy it seems like SemanticMediawiki supports installing via composer (e.g. it's code is pulled via composer). It's not (should not) be enabled by default though, there's enableSemantics function for that.

However on composer autoload the extension executes SemanticMediawiki::load(), which loads some global functions, defines, etc. According to the comment in there it's done specifically to reverse the order of loading and load SMW constants and global functions before LocalSettings is loaded.

Obviously, by that time none of the local configuration was loaded, so it shouldn't depend on it. But now after the core change point none of the DefaultSettings.php is loaded either. It also does some setting of the core globals, which reverse the order of initialization and will break as well

e.g. $GLOBALS['wgMessagesDirs']['SemanticMediaWiki'] = __DIR__ . '/i18n'; - this will just be overridden by standard mediawiki loading now.

Fixing the specific bug seems to be as easy as adding a null safe ?? operator so that the SetupCheck and moving globals initialization from this custom craft code to extension.json where they are explicitly supported.

What the path above did was to move composer autoloading before loading DefaultSettings.php. Which should not have mattered - composer dependencies shouldn't really depend on MediaWiki.

Is this composer-based extension loading something that we explicitly support or supported at some point, or is it custom witchcraft from SemanticMediawiki?

It is supported in the sense that it is widely used in parts of the MediaWiki ecosystem and we've tried avoiding breaking it. It's not really a SMW-specific thing, but SMW is the largest user (and refuses to switch IIRC). If we do decide that we need to break this, I think it needs to be an intentional/conscious decision that gets announced as such.

https://github.com/SemanticMediaWiki/SemanticMediaWiki/pull/5136 should fix the immediate issue on translatewiki.

Could you please test it in your staging environment?

Change 739911 had a related patch set uploaded (by Ppchelko; author: Ppchelko):

[mediawiki/core@master] RELEASE-NOTES: Add a note for autoloading change.

https://gerrit.wikimedia.org/r/739911

Thank you all for looking into this!

Change 739911 merged by jenkins-bot:

[mediawiki/core@master] RELEASE-NOTES: Add a note for autoloading change.

https://gerrit.wikimedia.org/r/739911