Although you can simply use the global $config array, that is not really the place where modules should be tinkering. First of all, because it's a global variable and it's never a good idea to change global variables, it should be left to the settings.php file. Second of all, because there is no way of controlling priority if multiple modules try to change it in the same way. Instead, we have the module override system that we can use.
Via the module overrides, we can create a service with the config.factory.override tag (remember what tagged services are?) and in this service, handle our overrides. To exemplify, let's use this system to override the maintenance mode message. Inside our Hello World module, we can have the following service class:
namespace Drupal\hello_world;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigFactoryOverrideInterface;
use Drupal\Core\Config\StorageInterface;
/**
* Overrides configuration for the Hello World module.
*/
class HelloWorldConfigOverrides implements ConfigFactoryOverrideInterface {
/**
* {@inheritdoc}
*/
public function loadOverrides($names) {
$overrides = [];
if (in_array('system.maintenance', $names)) {
$overrides['system.maintenance'] = ['message' => 'Our own message for the site maintenance mode.'];
}
return $overrides;
}
/**
* {@inheritdoc}
*/
public function getCacheSuffix() {
return 'HelloWorldConfigOverrider';
}
/**
* {@inheritdoc}
*/
public function createConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION) {
return NULL;
}
/**
* {@inheritdoc}
*/
public function getCacheableMetadata($name) {
return new CacheableMetadata();
}
}
Here, we have to implement the ConfigFactoryOverrideInterface interface which comes with four methods:
- In loadOverrides() we provide our overridden configuration values.
- In getCacheSuffix() we return a simple string to be used in the static cache identifier of our overrides.
- In createConfigObject() we don't actually do anything but we could create a configuration API object that would be used during installation or synchronization.
- In getCacheableMetadata() we return any cache metadata related to our override. We don't have any so we return an empty object.
Since this is a service, we can inject dependencies and make use of them if we want to calculate the overrides. Depending on this calculation, it can become important to set some proper cache metadata as well, but we will cover caching in another chapter.
Next, we register this as a tagged service:
hello_world.config_overrider:
class: \Drupal\hello_world\HelloWorldConfigOverrides
tags:
- {name: config.factory.override, priority: 5}
We set the priority to 5 and, with this, we can control the order in which modules get their chance at overriding configuration. The higher priority will take precedence over the lower one.
And that's it. Clearing the cache will register this service and alter our configuration. If you now put the site in maintenance mode, you will notice that the message is the one we set here. However, if you go to the maintenance mode administration page at admin/config/development/maintenance, you will still see the original message. This is so that administrators do not, by accident, save the override value into the configuration storage.