You are here

public function ConfigInstaller::installOptionalConfig in Drupal 10

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

File

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

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->extensionPathResolver
      ->getPath('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);
  }
}