The goal is to keep the actual default values for settings in the same place as the setting is declared, and applied using the regular means for loading the settings -- not in a separate piece of code that needs to be loaded through some entirely different mechanism. SetupDynamicConfig.php now contains a few categories of things: * Post-processing of configuration settings, where already-set settings are altered. This could be moved to MainConfigSchema too as a separate set of methods. * Processing of old aliases of settings (blacklist, slave) that are not registered as settings anymore and therefore are not available to MainConfigSchema. This could perhaps be moved to LocalSettings processing somehow? * Setting $wgUseEnotif, which is also not registered as a setting. Easiest would be just to declare it as a setting and have it set unconditionally. * Setting the actual timezone to $wgLocaltimezone. This is not related to configuration and should just be in Setup.php. Bug: T305093 Change-Id: Ia5c23b52dbbfcb3d07ffcf5d3b7f2d7befba2a26
99 lines
2.4 KiB
PHP
99 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Settings;
|
|
|
|
use LogicException;
|
|
use MediaWiki\Settings\Config\ConfigBuilder;
|
|
use MediaWiki\Settings\Config\ConfigSchema;
|
|
|
|
class DynamicDefaultValues {
|
|
|
|
/**
|
|
* @var ConfigSchema
|
|
*/
|
|
private $configSchema;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
private $declarations;
|
|
|
|
/**
|
|
* @param ConfigSchema $configSchema
|
|
*/
|
|
public function __construct( ConfigSchema $configSchema ) {
|
|
$this->configSchema = $configSchema;
|
|
$this->declarations = $this->configSchema->getDynamicDefaults();
|
|
}
|
|
|
|
/**
|
|
* Compute dynamic defaults for settings that have them defined.
|
|
*
|
|
* @param ConfigBuilder $configBuilder
|
|
*
|
|
* @return void
|
|
*/
|
|
public function applyDynamicDefaults( ConfigBuilder $configBuilder ): void {
|
|
$alreadyComputed = [];
|
|
|
|
foreach ( $this->declarations as $key => $unused ) {
|
|
$this->computeDefaultFor( $key, $configBuilder, $alreadyComputed );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Compute dynamic default for a setting, recursively computing any dependencies.
|
|
*
|
|
* @param string $key Name of setting
|
|
* @param ConfigBuilder $configBuilder
|
|
* @param array &$alreadyComputed Map whose keys are the names of settings whose dynamic
|
|
* defaults have already been computed
|
|
* @param array $currentlyComputing Ordered map whose keys are the names of settings whose
|
|
* dynamic defaults are currently being computed, for cycle detection.
|
|
*/
|
|
private function computeDefaultFor(
|
|
string $key,
|
|
ConfigBuilder $configBuilder,
|
|
array &$alreadyComputed = [],
|
|
array $currentlyComputing = []
|
|
): void {
|
|
if ( !isset( $this->declarations[ $key ] ) || isset( $alreadyComputed[ $key ] ) ) {
|
|
return;
|
|
}
|
|
if ( isset( $currentlyComputing[ $key ] ) ) {
|
|
throw new LogicException(
|
|
'Cyclic dependency when computing dynamic default: ' .
|
|
implode( ' -> ', array_keys( $currentlyComputing ) ) . " -> $key"
|
|
);
|
|
}
|
|
if (
|
|
$configBuilder->get( $key ) !==
|
|
$this->configSchema->getDefaultFor( $key )
|
|
) {
|
|
// Default was already overridden, nothing more to do
|
|
$alreadyComputed[ $key ] = true;
|
|
|
|
return;
|
|
}
|
|
|
|
$currentlyComputing[ $key ] = true;
|
|
|
|
$callback = $this->declarations[ $key ]['callback'];
|
|
$argNames = $this->declarations[ $key ]['use'] ?? [];
|
|
$args = [];
|
|
|
|
foreach ( $argNames as $argName ) {
|
|
$this->computeDefaultFor(
|
|
$argName,
|
|
$configBuilder,
|
|
$alreadyComputed,
|
|
$currentlyComputing
|
|
);
|
|
$args[] = $configBuilder->get( $argName );
|
|
}
|
|
|
|
$configBuilder->set( $key, $callback( ...$args ) );
|
|
|
|
$alreadyComputed[ $key ] = true;
|
|
}
|
|
}
|