function ConfigImportSubscriber::validateModules

Same name in other branches
  1. 9 core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php \Drupal\Core\EventSubscriber\ConfigImportSubscriber::validateModules()
  2. 8.9.x core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php \Drupal\Core\EventSubscriber\ConfigImportSubscriber::validateModules()
  3. 10 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 99

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 = $current_core_extension['profile'] ?? NULL;
    $new_install_profile = $core_extension['profile'] ?? NULL;
    // Ensure the profile is not changing.
    if ($install_profile !== $new_install_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' => $new_install_profile,
            ]));
            // If this error has occurred the other checks are irrelevant.
            return;
        }
        elseif ($new_install_profile) {
            $config_importer->logError($this->t('Cannot change the install profile from %profile to %new_profile once Drupal is installed.', [
                '%profile' => $install_profile,
                '%new_profile' => $new_install_profile,
            ]));
        }
    }
    elseif ($new_install_profile && !isset($core_extension['module'][$new_install_profile])) {
        $config_importer->logError($this->t('The install profile %profile is not in the list of installed modules.', [
            '%profile' => $new_install_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 modules can be uninstalled.
        foreach ($this->uninstallValidators as $validator) {
            $reasons = $validator instanceof ConfigImportModuleUninstallValidatorInterface ? $validator->validateConfigImport($module, $config_importer->getStorageComparer()
                ->getSourceStorage()) : $validator->validate($module);
            foreach ($reasons as $reason) {
                $config_importer->logError($this->t('Unable to uninstall the %module module because: @reason.', [
                    '%module' => $module_data[$module]->info['name'],
                    '@reason' => $reason,
                ]));
            }
        }
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.