function ConfigImporter::createExtensionChangelist

Same name in other branches
  1. 9 core/lib/Drupal/Core/Config/ConfigImporter.php \Drupal\Core\Config\ConfigImporter::createExtensionChangelist()
  2. 8.9.x core/lib/Drupal/Core/Config/ConfigImporter.php \Drupal\Core\Config\ConfigImporter::createExtensionChangelist()
  3. 10 core/lib/Drupal/Core/Config/ConfigImporter.php \Drupal\Core\Config\ConfigImporter::createExtensionChangelist()

Populates the extension change list.

1 call to ConfigImporter::createExtensionChangelist()
ConfigImporter::validate in core/lib/Drupal/Core/Config/ConfigImporter.php
Dispatches validate event for a ConfigImporter object.

File

core/lib/Drupal/Core/Config/ConfigImporter.php, line 379

Class

ConfigImporter
Defines a configuration importer.

Namespace

Drupal\Core\Config

Code

protected function createExtensionChangelist() {
    // Create an empty changelist.
    $this->extensionChangelist = $this->getEmptyExtensionsProcessedList();
    // Read the extensions information to determine changes.
    $current_extensions = $this->storageComparer
        ->getTargetStorage()
        ->read('core.extension');
    $new_extensions = $this->storageComparer
        ->getSourceStorage()
        ->read('core.extension');
    // If there is no extension information in sync then exit. This is probably
    // due to an empty sync directory.
    if (!$new_extensions) {
        return;
    }
    // Reset the module list in case a stale cache item has been set by another
    // process during deployment.
    $this->moduleExtensionList
        ->reset();
    // Get a list of modules with dependency weights as values.
    $module_data = $this->moduleExtensionList
        ->getList();
    // Use the actual module weights.
    $module_list = array_combine(array_keys($module_data), array_keys($module_data));
    $module_list = array_map(function ($module) use ($module_data) {
        return $module_data[$module]->sort;
    }, $module_list);
    // Determine which modules to uninstall.
    $uninstall = array_keys(array_diff_key($current_extensions['module'], $new_extensions['module']));
    // Sort the list of newly uninstalled extensions by their weights, so that
    // dependencies are uninstalled last. Extensions of the same weight are
    // sorted in reverse alphabetical order, to ensure the order is exactly
    // opposite from installation. For example, this module list:
    // @code
    // array(
    //   'actions' => 0,
    //   'ban' => 0,
    //   'options' => -2,
    //   'text' => -1,
    // );
    // @endcode
    // Will result in the following sort order:
    // 1. -2   options
    // 2. -1   text
    // 3.  0 0 ban
    // 4.  0 1 actions
    // @todo Move this sorting functionality to the extension system.
    array_multisort(array_values($module_list), SORT_ASC, array_keys($module_list), SORT_DESC, $module_list);
    $this->extensionChangelist['module']['uninstall'] = array_intersect(array_keys($module_list), $uninstall);
    // Determine which modules to install.
    $install = array_keys(array_diff_key($new_extensions['module'], $current_extensions['module']));
    // Always install required modules first. Respect the dependencies between
    // the modules.
    $install_required = [];
    $install_non_required = [];
    foreach ($install as $module) {
        if (!isset($module_data[$module])) {
            // The module doesn't exist. This is handled in
            // \Drupal\Core\EventSubscriber\ConfigImportSubscriber::validateModules().
            continue;
        }
        if (!empty($module_data[$module]->info['required'])) {
            $install_required[$module] = $module_data[$module]->sort;
        }
        else {
            $install_non_required[$module] = $module_data[$module]->sort;
        }
    }
    // Ensure that installed modules are sorted in exactly the reverse order
    // (with dependencies installed first, and modules of the same weight sorted
    // in alphabetical order).
    arsort($install_required);
    arsort($install_non_required);
    $this->extensionChangelist['module']['install'] = array_keys($install_required + $install_non_required);
    // If we're installing the install profile ensure it comes last in the
    // list of modules to be installed. This will occur when installing a site
    // from configuration.
    if (isset($new_extensions['profile'])) {
        $install_profile_key = array_search($new_extensions['profile'], $this->extensionChangelist['module']['install'], TRUE);
        // If the profile is not in the list of modules to be installed this will
        // generate a validation error. See
        // \Drupal\Core\EventSubscriber\ConfigImportSubscriber::validateModules().
        if ($install_profile_key !== FALSE) {
            unset($this->extensionChangelist['module']['install'][$install_profile_key]);
            $this->extensionChangelist['module']['install'][] = $new_extensions['profile'];
        }
    }
    // Get a list of themes with dependency weights as values.
    $theme_data = $this->themeExtensionList
        ->getList();
    // Use the actual theme weights.
    $theme_list = array_combine(array_keys($theme_data), array_keys($theme_data));
    $theme_list = array_map(function ($theme) use ($theme_data) {
        return $theme_data[$theme]->sort;
    }, $theme_list);
    array_multisort(array_values($theme_list), SORT_ASC, array_keys($theme_list), SORT_DESC, $theme_list);
    // Work out what themes to install and to uninstall.
    $uninstall = array_keys(array_diff_key($current_extensions['theme'], $new_extensions['theme']));
    $this->extensionChangelist['theme']['uninstall'] = array_intersect(array_keys($theme_list), $uninstall);
    // Ensure that installed themes are sorted in exactly the reverse order
    // (with dependencies installed first, and themes of the same weight sorted
    // in alphabetical order).
    $install = array_keys(array_diff_key($new_extensions['theme'], $current_extensions['theme']));
    $theme_list = array_reverse($theme_list);
    $this->extensionChangelist['theme']['install'] = array_intersect(array_keys($theme_list), $install);
}

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