Requests for comment/Configuration database 2

Introduction
This is a RfC for MediaWiki to have a sane and easy to use configuration interface through the wiki itself. This RfC is based off a previous RfC and the Configure extension.

Why?
Many of the various MediaWiki settings should be adjustable by local administrators/bureaucrats without requiring sysadmin intervention. Additionally, this would make those configuration values public to all users without requiring the LocalSettings.php file being uploaded somewhere.

Requirements

 * Overall goal: Site administrators should be able to configure various global settings via a web interface instead of editing a PHP file.
 * Performant: should not slow down the site
 * Backwards compatible: should work fine with existing code and extensions
 * Farm support: Work for both single-wiki installations and large farms like Wikimedia
 * Cross-wiki support: should be able to access another wiki's settings

Implementation
There are three major steps in implementing this:
 * 1) An interface and internal API for accessing and setting various configuration options (see  below)
 * 2) An actual "configuration database"
 * 3) A graphical configuration interface

Wikisets
Wikisets are primarily for wiki farms, and are comparable to Wikimedia's dblists. Individual wikis won't use this and will have an empty table. This is a shared table, and each wiki farm should only have one.

Each wikiset is just a list of wikis, and an optional parent wikiset. Each wikiset also has a "priority", which is an arbitrary integer that can be used for conflict resolution.

Each wiki will automatically be a member of a wikiset with the same name as their wikiid, so a wiki named "enwiki" will automatically be a part of the "enwiki" wikiset.

A wikiset editor (similar to the one in CentralAuth) will be provided to allow users with the proper rights to create new sets or edit existing ones.

Storage
Settings will be stored in a "config" table:


 * cf_id is the primary key, and also used as the "revision id" when comparing diffs.
 * cf_family is the wikiset the setting applies to, if null it applies to all wikis.
 * cf_name is the name of the setting, like "wgLogo". Because this will be extracted into a global, it must be a valid PHP variable name.
 * cf_value is the serialized value of the configuration variable.
 * cf_log_id is the foreign id to the log entry and can be used to look up the user who made the change, the log summary.
 * cf_deleted is for integration with RevDel. May not be necessary.

This table can be thought to be equivalent to the revision table for pages.

For some complicated arrays, it may make sense to split them into their own tables (user groups/permissions, namespaces), but those can be done in future RfCs.

Metadata
DefaultSettings.php will store metadata, similar to how the Configure extension works.

A very simple example might look like:

A hook will be available to extensions to add their own configuration options.

Accessing settings

 * For backwards compatibility, all globals will still be accessible.
 * Something similar to SiteConfiguration::extractAllGlobals will be called
 * For security reasons, only setting names starting with 'wg' will be extracted into PHP globals (possibly configurable in LocalSettings in case extensions want to add their own prefixes too).
 * Accessible via context:

Internal interface
Get a Conf object via context:

Basic variable lookup:

If you wanted to lookup another wiki's settings:

Backwards compatibility

 * Something similar to SiteConfiguration::extractAllGlobals will be called so globals will still work
 * LocalSettings.php will still exist to store certain settings such as database connection information (as this has to be configured before we can hit the database):
 * Loading order will be: DefaultSettings.php, LocalSettings.php, and then database settings
 * A maintenance script could be written to migrate LocalSettings.php/CommonSettings.php settings into a database.

Special page

 * New special page at Special:ConfigureSettings. It will look similar to Special:Preferences, and generated via HTMLForm.
 * The page is based on categories, so if you want to edit something in the "site" category, you would go to Special:ConfigureSettings/site. For SpamBlacklist, it would be Special:ConfigureSettings/SpamBlacklist.
 * The main Special:ConfigureSettings is just a landing page with a listing of various categories.
 * Users can choose which wikiset the setting will apply to, or if it is just the local wiki
 * If users cannot edit certain fields because they do not have the proper rights, they can still view the current value (unless it's set to private).

User rights

 * There is one super powerful right named 'configure' which lets you view and configure everything
 * There are also rights for specific categories, so 'configure-$group' would allow you to edit anything in the $group category.
 * A permission to let users set rights for any family or just the local one

Logging

 * This will use the standard MediaWiki logging mechanism.
 * Entries will look like "Tim changed $wgMagicEnabled from false to true (happiness for everyone!)".
 * May need to figure something out for complex arrays
 * If a variable is set to private, the log entry will only say: "Tim changed $wgMagicEnabled".
 * Since we store revision history, diffs will also be provided

Other considerations
Another option that has been mentioned is using a ContentHandler to store configuration settings in wiki pages. This has been rejected for a few reasons:
 * Cannot store private settings due to Security issues with authorization extensions
 * Editing pages already requires a lot of configuration to be set up
 * Getting page text can be non-trivial