Issue #3163226 by dww, jungle, alexpott, larowlan, longwave, cburschka: Add the ability to deprecate a Settings name
parent
1d44c8ebbb
commit
7d1f82b8bb
|
@ -26,6 +26,19 @@ final class Settings {
|
||||||
*/
|
*/
|
||||||
private static $instance = NULL;
|
private static $instance = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about all deprecated settings, keyed by legacy settings name.
|
||||||
|
*
|
||||||
|
* Each entry should be an array that defines the following keys:
|
||||||
|
* - 'replacement': The new name for the setting.
|
||||||
|
* - 'message': The deprecation message to use for trigger_error().
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* @see self::handleDeprecations()
|
||||||
|
*/
|
||||||
|
private static $deprecatedSettings = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
@ -84,6 +97,11 @@ final class Settings {
|
||||||
* The value of the setting, the provided default if not set.
|
* The value of the setting, the provided default if not set.
|
||||||
*/
|
*/
|
||||||
public static function get($name, $default = NULL) {
|
public static function get($name, $default = NULL) {
|
||||||
|
// If the caller is asking for the value of a deprecated setting, trigger a
|
||||||
|
// deprecation message about it.
|
||||||
|
if (isset(self::$deprecatedSettings[$name])) {
|
||||||
|
@trigger_error(self::$deprecatedSettings[$name]['message'], E_USER_DEPRECATED);
|
||||||
|
}
|
||||||
return isset(self::$instance->storage[$name]) ? self::$instance->storage[$name] : $default;
|
return isset(self::$instance->storage[$name]) ? self::$instance->storage[$name] : $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +140,8 @@ final class Settings {
|
||||||
require $app_root . '/' . $site_path . '/settings.php';
|
require $app_root . '/' . $site_path . '/settings.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self::handleDeprecations($settings);
|
||||||
|
|
||||||
// Initialize databases.
|
// Initialize databases.
|
||||||
foreach ($databases as $key => $targets) {
|
foreach ($databases as $key => $targets) {
|
||||||
foreach ($targets as $target => $info) {
|
foreach ($targets as $target => $info) {
|
||||||
|
@ -191,4 +211,28 @@ final class Settings {
|
||||||
return 'drupal.' . $identifier . '.' . \Drupal::VERSION . '.' . static::get('deployment_identifier') . '.' . Crypt::hashBase64($root . '/' . $site_path);
|
return 'drupal.' . $identifier . '.' . \Drupal::VERSION . '.' . static::get('deployment_identifier') . '.' . Crypt::hashBase64($root . '/' . $site_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle deprecated values in the site settings.
|
||||||
|
*
|
||||||
|
* @param array $settings
|
||||||
|
* The site settings.
|
||||||
|
*
|
||||||
|
* @see self::getDeprecatedSettings()
|
||||||
|
*/
|
||||||
|
private static function handleDeprecations(array &$settings): void {
|
||||||
|
foreach (self::$deprecatedSettings as $legacy => $deprecation) {
|
||||||
|
if (!empty($settings[$legacy])) {
|
||||||
|
@trigger_error($deprecation['message'], E_USER_DEPRECATED);
|
||||||
|
// Set the new key if needed.
|
||||||
|
if (!isset($settings[$deprecation['replacement']])) {
|
||||||
|
$settings[$deprecation['replacement']] = $settings[$legacy];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Ensure that both keys have the same value.
|
||||||
|
if (isset($settings[$deprecation['replacement']])) {
|
||||||
|
$settings[$legacy] = $settings[$deprecation['replacement']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace Drupal\Tests\Core\Site;
|
||||||
use Drupal\Core\Site\Settings;
|
use Drupal\Core\Site\Settings;
|
||||||
use Drupal\Tests\Traits\ExpectDeprecationTrait;
|
use Drupal\Tests\Traits\ExpectDeprecationTrait;
|
||||||
use Drupal\Tests\UnitTestCase;
|
use Drupal\Tests\UnitTestCase;
|
||||||
|
use org\bovigo\vfs\vfsStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @coversDefaultClass \Drupal\Core\Site\Settings
|
* @coversDefaultClass \Drupal\Core\Site\Settings
|
||||||
|
@ -150,4 +151,125 @@ class SettingsTest extends UnitTestCase {
|
||||||
$settings->getInstance();
|
$settings->getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests deprecation messages and values when using fake deprecated settings.
|
||||||
|
*
|
||||||
|
* Note: Tests for real deprecated settings should not be added to this test
|
||||||
|
* or provider. This test is only for the general deprecated settings API
|
||||||
|
* itself.
|
||||||
|
*
|
||||||
|
* @param string[] $settings_config
|
||||||
|
* Array of settings to put in the settings.php file for testing.
|
||||||
|
* @param string $setting_name
|
||||||
|
* The name of the setting this case should use for Settings::get().
|
||||||
|
* @param string $expected_value
|
||||||
|
* The expected value of the setting.
|
||||||
|
* @param bool $expect_deprecation_message
|
||||||
|
* Should the case expect a deprecation message? Defaults to TRUE.
|
||||||
|
*
|
||||||
|
* @runInSeparateProcess
|
||||||
|
*
|
||||||
|
* @dataProvider providerTestFakeDeprecatedSettings
|
||||||
|
*
|
||||||
|
* @covers ::handleDeprecations
|
||||||
|
* @covers ::initialize
|
||||||
|
*
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
|
public function testFakeDeprecatedSettings(array $settings_config, string $setting_name, string $expected_value, bool $expect_deprecation_message = TRUE): void {
|
||||||
|
|
||||||
|
$settings_file_content = "<?php\n";
|
||||||
|
foreach ($settings_config as $name => $value) {
|
||||||
|
$settings_file_content .= "\$settings['$name'] = '$value';\n";
|
||||||
|
}
|
||||||
|
$class_loader = NULL;
|
||||||
|
$vfs_root = vfsStream::setup('root');
|
||||||
|
$sites_directory = vfsStream::newDirectory('sites')->at($vfs_root);
|
||||||
|
vfsStream::newFile('settings.php')
|
||||||
|
->at($sites_directory)
|
||||||
|
->setContent($settings_file_content);
|
||||||
|
|
||||||
|
// This is the deprecated setting used by all cases for this test method.
|
||||||
|
$deprecated_setting = [
|
||||||
|
'replacement' => 'happy_replacement',
|
||||||
|
'message' => 'The settings key "deprecated_legacy" is deprecated in drupal:9.1.0 and will be removed in drupal:10.0.0. Use "happy_replacement" instead. See https://www.drupal.org/node/3163226.',
|
||||||
|
];
|
||||||
|
|
||||||
|
$class = new \ReflectionClass(Settings::class);
|
||||||
|
$instance_property = $class->getProperty('deprecatedSettings');
|
||||||
|
$instance_property->setAccessible(TRUE);
|
||||||
|
$deprecated_settings = $instance_property->getValue();
|
||||||
|
$deprecated_settings['deprecated_legacy'] = $deprecated_setting;
|
||||||
|
$instance_property->setValue($deprecated_settings);
|
||||||
|
|
||||||
|
if ($expect_deprecation_message) {
|
||||||
|
$this->addExpectedDeprecationMessage($deprecated_setting['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::initialize(vfsStream::url('root'), 'sites', $class_loader);
|
||||||
|
$this->assertEquals($expected_value, Settings::get($setting_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides data for testFakeDeprecatedSettings().
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* Test case data.
|
||||||
|
*/
|
||||||
|
public function providerTestFakeDeprecatedSettings(): array {
|
||||||
|
|
||||||
|
$only_legacy = [
|
||||||
|
'deprecated_legacy' => 'old',
|
||||||
|
];
|
||||||
|
$only_replacement = [
|
||||||
|
'happy_replacement' => 'new',
|
||||||
|
];
|
||||||
|
$both_settings = [
|
||||||
|
'deprecated_legacy' => 'old',
|
||||||
|
'happy_replacement' => 'new',
|
||||||
|
];
|
||||||
|
|
||||||
|
return [
|
||||||
|
'Only legacy defined, get legacy' => [
|
||||||
|
$only_legacy,
|
||||||
|
'deprecated_legacy',
|
||||||
|
'old',
|
||||||
|
],
|
||||||
|
'Only legacy defined, get replacement' => [
|
||||||
|
$only_legacy,
|
||||||
|
'happy_replacement',
|
||||||
|
// Since the new setting isn't yet defined, use the old value.
|
||||||
|
'old',
|
||||||
|
// Since the old setting is there, we should see a deprecation message.
|
||||||
|
],
|
||||||
|
'Both legacy and replacement defined, get legacy' => [
|
||||||
|
$both_settings,
|
||||||
|
'deprecated_legacy',
|
||||||
|
// Since the replacement is already defined, that should be used.
|
||||||
|
'new',
|
||||||
|
],
|
||||||
|
'Both legacy and replacement defined, get replacement' => [
|
||||||
|
$both_settings,
|
||||||
|
'happy_replacement',
|
||||||
|
'new',
|
||||||
|
// Should see the deprecation, since the legacy setting is defined.
|
||||||
|
],
|
||||||
|
'Only replacement defined, get legacy' => [
|
||||||
|
$only_replacement,
|
||||||
|
'deprecated_legacy',
|
||||||
|
// Should get the new value.
|
||||||
|
'new',
|
||||||
|
// But we should see a deprecation message for accessing the old name.
|
||||||
|
],
|
||||||
|
'Only replacement defined, get replacement' => [
|
||||||
|
$only_replacement,
|
||||||
|
'happy_replacement',
|
||||||
|
// Should get the new value.
|
||||||
|
'new',
|
||||||
|
// No deprecation since the old name is neither used nor defined.
|
||||||
|
FALSE,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue