You are here

public function ConfigInstaller::installOptionalConfig in Drupal 8

Same name in this branch
  1. 8 core/lib/Drupal/Core/Config/ConfigInstaller.php \Drupal\Core\Config\ConfigInstaller::installOptionalConfig()
  2. 8 core/lib/Drupal/Core/ProxyClass/Config/ConfigInstaller.php \Drupal\Core\ProxyClass\Config\ConfigInstaller::installOptionalConfig()
Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Config/ConfigInstaller.php \Drupal\Core\Config\ConfigInstaller::installOptionalConfig()

Installs optional configuration.

Optional configuration is only installed if:

  • the configuration does not exist already.
  • it's a configuration entity.
  • its dependencies can be met.

Parameters

\Drupal\Core\Config\StorageInterface $storage: (optional) The configuration storage to search for optional configuration. If not provided, all enabled extension's optional configuration directories including the install profile's will be searched.

array $dependency: (optional) If set, ensures that the configuration being installed has this dependency. The format is dependency type as the key ('module', 'theme', or 'config') and the dependency name as the value ('book', 'bartik', 'views.view.frontpage').

Overrides ConfigInstallerInterface::installOptionalConfig

1 call to ConfigInstaller::installOptionalConfig()
ConfigInstaller::installDefaultConfig in core/lib/Drupal/Core/Config/ConfigInstaller.php
Installs the default configuration of a given extension.

File

core/lib/Drupal/Core/Config/ConfigInstaller.php, line 166

Class

ConfigInstaller

Namespace

Drupal\Core\Config

Code

public function installOptionalConfig(StorageInterface $storage = NULL, $dependency = []) {
  $profile = $this
    ->drupalGetProfile();
  $enabled_extensions = $this
    ->getEnabledExtensions();
  $existing_config = $this
    ->getActiveStorages()
    ->listAll();

  // Create the storages to read configuration from.
  if (!$storage) {

    // Search the install profile's optional configuration too.
    $storage = new ExtensionInstallStorage($this
      ->getActiveStorages(StorageInterface::DEFAULT_COLLECTION), InstallStorage::CONFIG_OPTIONAL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION, TRUE, $this->installProfile);

    // The extension install storage ensures that overrides are used.
    $profile_storage = NULL;
  }
  elseif (!empty($profile)) {

    // Creates a profile storage to search for overrides.
    $profile_install_path = $this
      ->drupalGetPath('module', $profile) . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY;
    $profile_storage = new FileStorage($profile_install_path, StorageInterface::DEFAULT_COLLECTION);
  }
  else {

    // Profile has not been set yet. For example during the first steps of the
    // installer or during unit tests.
    $profile_storage = NULL;
  }

  // Build the list of possible configuration to create.
  $list = $storage
    ->listAll();
  if ($profile_storage && !empty($dependency)) {

    // Only add the optional profile configuration into the list if we are
    // have a dependency to check. This ensures that optional profile
    // configuration is not unexpectedly re-created after being deleted.
    $list = array_unique(array_merge($list, $profile_storage
      ->listAll()));
  }

  // Filter the list of configuration to only include configuration that
  // should be created.
  $list = array_filter($list, function ($config_name) use ($existing_config) {

    // Only list configuration that:
    // - does not already exist
    // - is a configuration entity (this also excludes config that has an
    //   implicit dependency on modules that are not yet installed)
    return !in_array($config_name, $existing_config) && $this->configManager
      ->getEntityTypeIdByName($config_name);
  });
  $all_config = array_merge($existing_config, $list);
  $all_config = array_combine($all_config, $all_config);
  $config_to_create = $storage
    ->readMultiple($list);

  // Check to see if the corresponding override storage has any overrides or
  // new configuration that can be installed.
  if ($profile_storage) {
    $config_to_create = $profile_storage
      ->readMultiple($list) + $config_to_create;
  }

  // Sort $config_to_create in the order of the least dependent first.
  $dependency_manager = new ConfigDependencyManager();
  $dependency_manager
    ->setData($config_to_create);
  $config_to_create = array_merge(array_flip($dependency_manager
    ->sortAll()), $config_to_create);
  if (!empty($dependency)) {

    // In order to work out dependencies we need the full config graph.
    $dependency_manager
      ->setData($this
      ->getActiveStorages()
      ->readMultiple($existing_config) + $config_to_create);
    $dependencies = $dependency_manager
      ->getDependentEntities(key($dependency), reset($dependency));
  }
  foreach ($config_to_create as $config_name => $data) {

    // Remove configuration where its dependencies cannot be met.
    $remove = !$this
      ->validateDependencies($config_name, $data, $enabled_extensions, $all_config);

    // Remove configuration that is not dependent on $dependency, if it is
    // defined.
    if (!$remove && !empty($dependency)) {
      $remove = !isset($dependencies[$config_name]);
    }
    if ($remove) {

      // Remove from the list of configuration to create.
      unset($config_to_create[$config_name]);

      // Remove from the list of all configuration. This ensures that any
      // configuration that depends on this configuration is also removed.
      unset($all_config[$config_name]);
    }
  }

  // Create the optional configuration if there is any left after filtering.
  if (!empty($config_to_create)) {
    $this
      ->createConfiguration(StorageInterface::DEFAULT_COLLECTION, $config_to_create, TRUE);
  }
}