Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ site value when it changes.
separate action, and restores inheritance.
- Only listed config objects are exposed, and within them only the keys
their schema declares. Internal keys are always dropped, and an exclusion
list removes the rest. The site email address is excluded by default.
list removes the rest. The site email address and the notification
address are excluded by default.
- Logo and favicon come from core's theme settings resolution, as usable
URLs with core's fallbacks.
- Responses carry the config cache tags of every object read, and a cache
Expand Down
1 change: 1 addition & 0 deletions config/install/decoupled_settings.settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ expose_theme_settings: true
# Schema bounds the shape of an object, not the sensitivity of its values.
excluded_keys:
- 'system.site:mail'
- 'system.site:mail_notification'
18 changes: 18 additions & 0 deletions decoupled_settings.install
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,21 @@ function decoupled_settings_install(): void {
}
}
}

/**
* Exclude system.site:mail_notification from the exposed settings.
*
* The shipped exclude list held system.site:mail but not the notification
* address next to it. Append it for existing installs. A site that wants
* the key exposed can remove it again: this hook runs once.
*/
function decoupled_settings_update_10001(): string {
$config = \Drupal::configFactory()->getEditable('decoupled_settings.settings');
$excluded = $config->get('excluded_keys') ?? [];
if (!in_array('system.site:mail_notification', $excluded, TRUE)) {
$excluded[] = 'system.site:mail_notification';
$config->set('excluded_keys', $excluded)->save();
return 'system.site:mail_notification is now excluded.';
}
return 'system.site:mail_notification was already excluded.';
}
21 changes: 21 additions & 0 deletions tests/src/Kernel/FormLogicTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,27 @@ public function testOverrideFormListsInheritedValues(): void {
$this->assertFalse((bool) $form['settings']['system.site:name']['enabled']['#default_value']);
}

/**
* A setting with no value is listed with an empty inherited cell.
*
* The notification address is NULL on a fresh site. It is excluded by
* default, so this exposes it on purpose to render the NULL path.
*/
public function testOverrideFormListsNullValueAsEmpty(): void {
$this->config('decoupled_settings.settings')
->set('excluded_keys', [])
->save();
$consumer = $this->createConsumer();

$form_state = new FormState();
$form_state->addBuildInfo('args', [$consumer]);
$form = $this->container->get('form_builder')
->buildForm(ConsumerOverridesForm::class, $form_state);

$this->assertArrayHasKey('system.site:mail_notification', $form['settings']);
$this->assertSame('', $form['settings']['system.site:mail_notification']['inherited']['#markup']);
}

/**
* An already overridden setting is shown as ticked, with its own value.
*/
Expand Down
26 changes: 26 additions & 0 deletions tests/src/Kernel/SettingsResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ protected function setUp(): void {
$this->config('system.site')
->set('name', 'Global Site')
->set('slogan', 'Global slogan')
->set('mail_notification', 'webmaster@example.com')
->save();

// Theme settings are off by default here, so each test opts in.
Expand Down Expand Up @@ -141,6 +142,31 @@ public function testExcludedKeyIsNotExposed(): void {
$resolved = $this->resolver->resolve(NULL, new CacheableMetadata());

$this->assertArrayNotHasKey('mail', $resolved['system.site']);
$this->assertArrayNotHasKey('mail_notification', $resolved['system.site']);
}

/**
* The update hook appends the notification address exclusion once.
*/
public function testUpdateHookExcludesMailNotification(): void {
\Drupal::moduleHandler()->loadInclude('decoupled_settings', 'install');

// An install from before the exclusion shipped.
$this->config('decoupled_settings.settings')
->set('excluded_keys', ['system.site:mail'])
->save();
$resolved = $this->resolver->resolve(NULL, new CacheableMetadata());
$this->assertArrayHasKey('mail_notification', $resolved['system.site']);

decoupled_settings_update_10001();

$resolved = $this->resolver->resolve(NULL, new CacheableMetadata());
$this->assertArrayNotHasKey('mail_notification', $resolved['system.site']);

// Running again does not duplicate the entry.
decoupled_settings_update_10001();
$excluded = $this->config('decoupled_settings.settings')->get('excluded_keys');
$this->assertCount(1, array_keys($excluded, 'system.site:mail_notification', TRUE));
}

/**
Expand Down
Loading