You are here

protected function ConfigImportSubscriber::validateModules in Drupal 8

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php \Drupal\Core\EventSubscriber\ConfigImportSubscriber::validateModules()

Validates module installations and uninstallations.

Parameters

\Drupal\Core\Config\ConfigImporter $config_importer: The configuration importer.

1 call to ConfigImportSubscriber::validateModules()
ConfigImportSubscriber::onConfigImporterValidate in core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php
Validates the configuration to be imported.

File

core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php, line 90

Class

ConfigImportSubscriber
Config import subscriber for config import events.

Namespace

Drupal\Core\EventSubscriber

Code

protected function validateModules(ConfigImporter $config_importer) {
  $core_extension = $config_importer
    ->getStorageComparer()
    ->getSourceStorage()
    ->read('core.extension');

  // Get the install profile from the site's configuration.
  $current_core_extension = $config_importer
    ->getStorageComparer()
    ->getTargetStorage()
    ->read('core.extension');
  $install_profile = isset($current_core_extension['profile']) ? $current_core_extension['profile'] : NULL;

  // Ensure the profile is not changing.
  if ($install_profile !== $core_extension['profile']) {
    if (InstallerKernel::installationAttempted()) {
      $config_importer
        ->logError($this
        ->t('The selected installation profile %install_profile does not match the profile stored in configuration %config_profile.', [
        '%install_profile' => $install_profile,
        '%config_profile' => $core_extension['profile'],
      ]));

      // If this error has occurred the other checks are irrelevant.
      return;
    }
    else {
      $config_importer
        ->logError($this
        ->t('Cannot change the install profile from %profile to %new_profile once Drupal is installed.', [
        '%profile' => $install_profile,
        '%new_profile' => $core_extension['profile'],
      ]));
    }
  }

  // Get a list of modules with dependency weights as values.
  $module_data = $this->moduleExtensionList
    ->getList();
  $nonexistent_modules = array_keys(array_diff_key($core_extension['module'], $module_data));
  foreach ($nonexistent_modules as $module) {
    $config_importer
      ->logError($this
      ->t('Unable to install the %module module since it does not exist.', [
      '%module' => $module,
    ]));
  }

  // Ensure that all modules being installed have their dependencies met.
  $installs = $config_importer
    ->getExtensionChangelist('module', 'install');
  foreach ($installs as $module) {
    $missing_dependencies = [];
    foreach (array_keys($module_data[$module]->requires) as $required_module) {
      if (!isset($core_extension['module'][$required_module])) {
        $missing_dependencies[] = $module_data[$required_module]->info['name'];
      }
    }
    if (!empty($missing_dependencies)) {
      $module_name = $module_data[$module]->info['name'];
      $message = $this
        ->formatPlural(count($missing_dependencies), 'Unable to install the %module module since it requires the %required_module module.', 'Unable to install the %module module since it requires the %required_module modules.', [
        '%module' => $module_name,
        '%required_module' => implode(', ', $missing_dependencies),
      ]);
      $config_importer
        ->logError($message);
    }
  }

  // Ensure that all modules being uninstalled are not required by modules
  // that will be installed after the import.
  $uninstalls = $config_importer
    ->getExtensionChangelist('module', 'uninstall');
  foreach ($uninstalls as $module) {
    foreach (array_keys($module_data[$module]->required_by) as $dependent_module) {
      if ($module_data[$dependent_module]->status && !in_array($dependent_module, $uninstalls, TRUE) && $dependent_module !== $install_profile) {
        $module_name = $module_data[$module]->info['name'];
        $dependent_module_name = $module_data[$dependent_module]->info['name'];
        $config_importer
          ->logError($this
          ->t('Unable to uninstall the %module module since the %dependent_module module is installed.', [
          '%module' => $module_name,
          '%dependent_module' => $dependent_module_name,
        ]));
      }
    }
  }

  // Ensure that the install profile is not being uninstalled.
  if (in_array($install_profile, $uninstalls, TRUE)) {
    $profile_name = $module_data[$install_profile]->info['name'];
    $config_importer
      ->logError($this
      ->t('Unable to uninstall the %profile profile since it is the install profile.', [
      '%profile' => $profile_name,
    ]));
  }
}