Requests for comment/Extension registration

Extensions currently need to "register" information about themselves. This includes autoloading classes, hook functions, and much more. This is typically done in filescope by adding to global variables. As a consequence, it is not possible to figure out what an extension is going to register without including the file, which would enable the extension regardless. In addition, we are planning to move away from configuring things in global scope.

This is a proposal to change the way extensions store metadata about themselves and how we enable them.

Things to "register"
This is a list of items that most extensions will typically register.


 * classes - $wgAutoloadClasses
 * hooks - $wgHooks
 * API modules - $wgAPIModules, $wgAPIFormatModules, $wgAPIMetaModules, $wgAPIPropModules, $wgAPIListModules
 * special pages - $wgSpecialPages
 * configuration globals - $wgExtensionFoo
 * namespaces, NS_CONSTANTs - this is a mess
 * ResourceLoader - $wgResourceModules
 * permissions - $wgGroupPermissions, $wgAvailableRights
 * $wgExtensionFunctions
 * credits - $wgExtensionCredits

There are many more, just look at DefaultSettings.php for an idea.

Proposal
Store all of this in a JSON file in the extension directory at. See below for how it is loaded.

Here's an example of what it might look like for the MassMessage extension (some of it, I didn't include everything).

In reality, not much has changed except for the format these options are stored in. For most extensions, this will completely eliminate the ExtName.php loader file. For backwards compatibility, we can provide a stub file, similar to how the JSON i18n migration ocurred.

For extensions that absolutely need to handle setup in PHP, a callback may be registered (using a "callback" key), that will be run after the rest of the info.json file has been processed. This would be different than extension functions, which are run after nearly all MediaWiki setup has occurred.

Loading extensions
Currently extensions are loaded by adding:  to your LocalSettings/CommonSettings.php file.

Instead of this, we would introduce a configuration setting like, which would then be appended to to "enable" extensions.

After configuration is loaded (LocalSettings.php or the future config db), all the enabled extensions would be loaded by looking at. This creates a requirement that all extensions must be placed in. The defaults of the extension will only be set if a value is not already set.

This would also provide a backend for a future web interface to enable/disable extensions.

Order
In includes/WebStart.php:
 * Include LocalSettings.php/CommonSettings.php or load the configuration database, which adds to $wgEnabledExtensions

In includes/Setup.php:
 * Right after the $wgVersion check (L40), go through $wgEnabledExtensions, loading each one
 * If the extension has a callback set, call it.
 * If an extension doesn't exist, throw a fatal error (equivalent of calling  on a non-existent file)