6

I have been playing a lot lately with an import configuration to Drupal 8. And I notice that all documentation show you how to edit value per value instead of overriding the entire config file. You can find more information about this at Configuration override system page.

I notice that DrupalConsole and Drush have the ability of overriding configuration by file.

  • Using Drush, you can run drush config-import
  • Using DrupalConsole, you can run drupal config-import

This will override the entire configuration base on the configuration file. How can I achieve this on the code? Hopefully, I will like to edit my configuration when I'm installation my module on hook_install.

4 Answers 4

8

To override config on code is simple. Above is an exemple how you get, set and save any config (that you just installed via .yml and from core).

On .install or .module file

  //Getting editable configs
  $module_cfg = \Drupal::configFactory()->getEditable('your.module.file');
  $settings = \Drupal::configFactory()->getEditable('any_core.settings');
  //Getting values
  $a_value = $settings->get('key_from_core');
  //Setting and save configs
  $module_cfg->set('any.key', $a_value)->save();
  $settings->set('key', 'new_value')->save();

From hook_install docs:

Implementations of this hook are by convention declared in the module's .install file.

For further information see ConfigFactory docs.

There is a module called Features that helps if you want keep on track of your configs. I'm currently using this module for code-driven development, maybe is this what you're looking for.

Edit 1 - Replace entire config

First of all, you need to provide which config you pretend to override.

On my.custom.config.yml file

# Make sure this config exists in your database
target: 'config.to.override'
... # all your data (CAUTION with 'dependencies')

On .install file

function module_install() {
  //Get your custom config
  $cfg = \Drupal::configFactory()->getEditable('my.custom.config');
  //Get config name to override
  $target = $cfg->get('target');
  //Get Config object
  $settings = \Drupal::configFactory()->getEditable($target);
  //Override all data that can be overridden
  $settings->setData($cfg->get())->save();
  //If you won't store any previous state, get rid of your custom config
  $cfg->delete();
}

This was tested in my development environment.

3
  • The example that you provide it seem like is changing value per value. Instead of replacing the entire values from the config and update with the extenal file provide by the module. Commented Jan 21, 2016 at 3:14
  • Well, yes and no, you could iterate keys and values from your file. I'll edit my answer to provide a better option to replace entire config with Config->setData().
    – Vagner
    Commented Jan 21, 2016 at 13:28
  • This worked for me except I had to update the set data to: $settings->setData($cfg)->save();
    – albertski
    Commented Jun 9, 2017 at 16:55
4

I leave here another example, in addition to @Vagner's answer, in case it is useful.

The scenario is as follows: I would like to override addtoany's settings.

The module's settings are located at modules/contrib/addtoany/config/install/addtoany.settings.yml.

In order to override them, create a custom module foobar and a file modules/custom/foobar/config/install/foobar.addtoany.settings.yml:

buttons_size: 32
additional_html: |
  <a class="a2a_button_facebook"></a>
  <a class="a2a_button_twitter"></a>
additional_css: ''
additional_js: ''
universal_button: none
custom_universal_button: ''
universal_button_placement: before
no_3p: false

In modules/custom/foobar/foobar.install, apply the new settings:

<?php

function foobar_install()
{
  // Get your custom config
  $cfg = \Drupal::configFactory()->getEditable('foobar.addtoany.settings');
  // Get Config object
  $settings = \Drupal::configFactory()->getEditable('addtoany.settings');
  // Override all data that can be overridden
  $settings->setData($cfg->get())->save();
  // Get rid of your custom config
  $cfg->delete();
}
2
  • just curious , wouldn't there be conflict if X module overrides Y module's default settings? for ex: if X module's email setting is [email protected] then it could be overridden with value like [email protected]. Wouldn't there be any prob...
    – kiranking
    Commented Mar 3, 2018 at 18:26
  • Apparently we need to define all entries, even the ones we don't want to change (like buttons_size: 32 which is the same as before). It would be neat to know a way to merge, keeping the missing attributes as before.
    – dxvargas
    Commented Sep 3, 2018 at 13:47
2

Inspired by @Vagner's, answer, I choose to read a directory of config files to be imported during installation. Call this from HOOK_install(). This avoid having to install config and then delete it. You can also simply copy config files from the sync director to the install/override directory (and remove the uuid entry of course). If you have a number of config files, this might be easier.

use Drupal\Core\Config\FileStorage;
// (snip)
/**
 * Read all configuration from config/override and install.
 */
function _MODULE_override_config() {
  $path = drupal_get_path('module', 'MODULE') . '/config/override';
  $file = new FileStorage($path);
  foreach ($file->listAll() as $id) {
    $config_data = $file->read($id);
    $config = \Drupal::configFactory()->getEditable($id);
    $config->setData($config_data)->save();
  }
}
1
Apparently we need to define all entries, even the ones we don't want to change

Maybe this was the case, but currently I have just used the above example in 4 (thanks turdus-merula) to override just two of Devel modules settings. The others remain untouched.

[edit: cannot add my comment directly to dxvargas's reply to which it relates]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.