Drupal 10: Hook To Force Install Configuration

Note: If you are using Drupal 10.3+ or 11.0+ then it's might be better to use recipes to accomplish this task.

It is possible in Drupal modules to provide configuration that will be picked up and installed when the module is enabled. There are some limitations to this approach.

If you want to install configuration when you module is installed you can add yaml files to the config/install directory in your module. This works fine for configuration that won't be present on install (ie. you own module configuration) but it breaks when attempting to override the configuration of other modules. You will see an error that states "already exists in active configuration".

Alternatively, you can add yaml files to the config/optional directory in your module. This will attempt to install configuration, but won't throw any errors if the configuration can't be installed. This is a good place to add configuration for other modules that would be built by your module, like configuration entities. That includes things like path auto settings or content types, and they will only be installed if the module associated with it is already installed.

If you place default configuration for another module in this directory then it will be ignored in favour of the configuration from that module. So, you can't add your Seckit module settings file to that directory as the default configuration from Seckit will be used.

The way around this is to use the hook_install() hook to pull the configuration you want and apply it to your active configuration when the module is installed. To do this, add some configuration files that you want to apply to the site to your config/optional directory.

Then, create a .install file and add the following content to it (be sure to change the name of the module in here, it's mentioned twice).

use Drupal\Core\Config\FileStorage;

/**
 * Implements hook_install().
 */
function mymodule_install() {
  // Force the configuration in the config/optional to be installed.
  $moduleConfigPath = \Drupal::service('extension.list.module')->getPath('mymodule') . '/config/optional';

  $files = \Drupal::service('file_system')->scanDirectory($moduleConfigPath, '/\.yml$/');

  /** @var \Drupal\Core\Config\StorageCacheInterface $configStorage */
  $configStorage = \Drupal::service('config.storage');
  
  /** @var \Drupal\Core\Config\FileStorage $source */
  $source = new FileStorage($moduleConfigPath);

  if ($files) {
    foreach ($files as $file) {
      $configName = basename($file->name, '.yml');
      $configStorage->write($configName, $source->read($configName));
    }
  }
}

When you install the module the hook will pick up all of the configuration files in the optional configuration directory and write their contents to the active configuration. This allows setting default configuration for other modules outside of your own module.

I would, however, use this with caution. It will just override any existing configuration in your site and will not export that configuration to disk.

Note that this might also work with the hook_installed() hook.

Add new comment

The content of this field is kept private and will not be shown publicly.