Requests for comment/Configuration database 2

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

Request for comment (RFC)
Configuration database 2
Component General
Creation date
Author(s) Kunal Mehta, Ryan Schmidt
Document status in discussion
See Phabricator.

Goal

edit

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

edit
  • 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

edit

There are three major steps in implementing this:

  1. An interface and internal API for accessing and setting various configuration options (see #Accessing settings below)
  2. An actual "configuration database"
  3. A graphical configuration interface

Wikisets

edit

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.

CREATE TABLE /*_*/wiki_set (
	ws_child VARBINARY(255), -- name of wiki

	ws_parent VARBINARY(255), -- family it belongs to

	ws_priority int -- priority of this relationship

) /*$wgDBTableOptions*/;

PRIMARY KEY( ws_child, ws_parent )

Storage

edit

Settings will be stored in a "config" table:

CREATE TABLE /*_*/config (
	cf_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
	cf_family VARBINARY(255),
	cf_name VARBINARY(255) NOT NULL,
	cf_value blob,
	cf_log_id int,
	cf_deleted int,

) /*$wgDBTableOptions*/;
  • 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

edit

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

A very simple example might look like:

$wgDefaultSettings = array(
	'site' => array( // category name
		'wgSitename' => array(
			'type' => 'text',
			'default' => 'Awesome wiki',
		),
	),
	'secrets' => array(
		'wgSecretKey' => array(
			'private' => true, // Is this config variable considered to be private?
			'type' => 'text',
		),
	),
);

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

Accessing settings

edit
  • 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: $conf = $this->getContext()->getConf();

Internal interface

edit

Get a Conf object via context:

  • $conf = $this->getContext()->getConf()

Basic variable lookup:

  • $conf->get('wgName')

If you wanted to lookup another wiki's settings:

  • Conf::newForWiki('xxwiki')->get('wgName')

Backwards compatibility

edit
  • 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.

User interface

edit

Special page

edit
  • 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

edit
  • 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

edit
  • 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

edit

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:

See also

edit
  • Starting with MediaWiki 1.25, Manual:Extension registration lets extensions and skins update numerous configuration variables by setting keys in an extension.json file, rather than appending to $wgFoo globals directly.