Mediawiki Extension throws exception "Class not found" using AutoloadNamespaces

670 Views Asked by At

I try to write a parser-function extension for mediawiki and even with a very simple skeleton adapted from their docs, I get a class not found error, if the extension is loaded. I compared my skeleton code with the popular "ParserFunctions" extension, for me it looks identically...

"extensions/MyExtension/extension.json":

{
  "name": "MyExtension",
  "author": "me",
  "version": "0.1.0",
  "descriptionmsg": "myextension-desc",
  "license-name": "proprietary",
  "type": "parserhook",
  "requires": {
    "MediaWiki": ">= 1.31.0"
  },
  "config": {
    "MyExtensionUrls": {
      "value": [],
      "description": "Set api URLs (associative array)"
    }
  },
  "ConfigRegistry": {
    "myextension": "GlobalVarConfig::newInstance"
  },
  "MessagesDirs": {
    "MyExtension": [
      "i18n"
    ]
  },
  "AutoloadNamespaces": {
    "MediaWiki\\Extension\\MyExtension\\": "src/"
  },
  "ExtensionMessagesFiles": {
    "MyExtensionMagic": "MyExtension.i18n.php"
  },
  "Hooks": {
    "ParserFirstCallInit": "MyExtension::onParserFirstCallInit"
  },
  "manifest_version": 2
}

"extensions/MyExtension/src/MyExtension.php":

<?php
namespace MediaWiki\Extension\MyExtension;

use Parser;
use MWException;
use MediaWiki\MediaWikiServices;

class MyExtension {
    
    private static array $urls;
    
    public static function onParserFirstCallInit(Parser $parser): void {
    
        // get config
        $config = MediaWikiServices::getInstance()->getConfigFactory()->makeConfig('myextension');
        // get api urls
        $urls = $config->get('MyExtensionUrls');
        // check api urls
        if(\sizeof($urls) === 0) {
            throw new MWException("Configuration error, no api URL set.\n
                Please set at least one \"keyName\" => \"http://url.to/api\" pair in LocalSettings.php \$wgMyExtensionUrls array.");
        } else {
            
            // set urls
            self::$urls = $urls;
    
            // Create a function hook associating the "example" magic word with renderExample()
            $parser->setFunctionHook('example', [ self::class, 'renderExample' ]);
        }
    }
    
    public static function renderExample(Parser &$parser, ...$args): string {
                
        // return
        return '--Example--';
    }
}

"extensions/MyExtension/MyExtension.i18n.php":

<?php

$magicWords = [];

// English
$magicWords['en'] = [
    'example' => [ 0, 'example' ],
];

// German
$magicWords['de'] = [
    'example' => [ 0, 'beispiel' ],
];

Using wfLoadExtension('MyExtension'); in LocalSettings.php leads to the following stack trace:

MediaWiki internal error.

Original exception: [2e8e18a2084d81b05f93bf0f] /index.php/Hauptseite Error: Class 'MyExtension' not found
Backtrace:
from /var/www/html/includes/HookContainer/HookContainer.php(338)
#0 /var/www/html/includes/HookContainer/HookContainer.php(137): MediaWiki\HookContainer\HookContainer->callLegacyHook(string, array, array, array)
#1 /var/www/html/includes/HookContainer/HookRunner.php(2872): MediaWiki\HookContainer\HookContainer->run(string, array)
#2 /var/www/html/includes/parser/Parser.php(533): MediaWiki\HookContainer\HookRunner->onParserFirstCallInit(Parser)
#3 /var/www/html/includes/parser/ParserFactory.php(196): Parser->__construct(MediaWiki\Config\ServiceOptions, MagicWordFactory, Language, ParserFactory, string, MediaWiki\SpecialPage\SpecialPageFactory, MediaWiki\Linker\LinkRendererFactory, NamespaceInfo, MediaWiki\Logger\LegacyLogger, MediaWiki\BadFileLookup, MediaWiki\Languages\LanguageConverterFactory, MediaWiki\HookContainer\HookContainer, MediaWiki\Tidy\RemexDriver, WANObjectCache, MediaWiki\User\UserOptionsManager, MediaWiki\User\UserFactory, MediaWikiTitleCodec, MediaWiki\Http\HttpRequestFactory, TrackingCategories)
#4 /var/www/html/includes/ServiceWiring.php(1211): ParserFactory->create()
#5 /var/www/html/vendor/wikimedia/services/src/ServiceContainer.php(447): Wikimedia\Services\ServiceContainer::{closure}(MediaWiki\MediaWikiServices)
#6 /var/www/html/vendor/wikimedia/services/src/ServiceContainer.php(416): Wikimedia\Services\ServiceContainer->createService(string)
#7 /var/www/html/includes/MediaWikiServices.php(294): Wikimedia\Services\ServiceContainer->getService(string)
#8 /var/www/html/includes/MediaWikiServices.php(1366): MediaWiki\MediaWikiServices->getService(string)
#9 /var/www/html/includes/cache/MessageCache.php(1270): MediaWiki\MediaWikiServices->getParser()
#10 /var/www/html/includes/cache/MessageCache.php(1249): MessageCache->getParser()
#11 /var/www/html/includes/language/Message.php(1474): MessageCache->transform(string, boolean, Language, Title)
#12 /var/www/html/includes/language/Message.php(1007): Message->transformText(string)
#13 /var/www/html/includes/language/Message.php(1071): Message->format(string)
#14 /var/www/html/includes/OutputPage.php(1041): Message->text()
#15 /var/www/html/includes/OutputPage.php(1090): OutputPage->setHTMLTitle(Message)
#16 /var/www/html/includes/page/Article.php(464): OutputPage->setPageTitle(string)
#17 /var/www/html/includes/actions/ViewAction.php(80): Article->view()
#18 /var/www/html/includes/MediaWiki.php(543): ViewAction->show()
#19 /var/www/html/includes/MediaWiki.php(321): MediaWiki->performAction(Article, Title)
#20 /var/www/html/includes/MediaWiki.php(912): MediaWiki->performRequest()
#21 /var/www/html/includes/MediaWiki.php(563): MediaWiki->main()
#22 /var/www/html/index.php(53): MediaWiki->run()
#23 /var/www/html/index.php(46): wfIndexMain()
#24 {main}

My test environment is the "official" docker container where I used the extensions directory as local volume.

Can anyone point me in the right direction, what my mistake might be?

UPDATE

I made a test using the AutoloadClasses setting in extension.json

{
  "AutoloadClasses": {
    "MyExtension": "src/MyExtension.php"
  },
}

and removing the namespacing of the extension

<?php

use MediaWiki\MediaWikiServices;

class MyExtension {
...

and it (nearly) works like it should (but that "nearly" has nothing to do with the namespace problem here)...

So my code has definitively a problem with the namespacing, but I'd like to use it... if anyone sees my mistake, please post an answere...

0

There are 0 best solutions below