You are here

protected function ConfigImporter::createExtensionChangelist in Drupal 9

Same name and namespace in other branches
  1. 8 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 368

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;
  }

  // Get a list of modules with dependency weights as values.
  $module_data = $this->moduleExtensionList
    ->getList();

  // Set 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']));

  // 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).
  $module_list = array_reverse($module_list);
  $this->extensionChangelist['module']['install'] = array_intersect(array_keys($module_list), $install);

  // If we're installing the install profile ensure it comes last. This will
  // occur when installing a site from configuration.
  $install_profile_key = array_search($new_extensions['profile'], $this->extensionChangelist['module']['install'], TRUE);
  if ($install_profile_key !== FALSE) {
    unset($this->extensionChangelist['module']['install'][$install_profile_key]);
    $this->extensionChangelist['module']['install'][] = $new_extensions['profile'];
  }

  // Work out what themes to install and to uninstall.
  $this->extensionChangelist['theme']['install'] = array_keys(array_diff_key($new_extensions['theme'], $current_extensions['theme']));
  $this->extensionChangelist['theme']['uninstall'] = array_keys(array_diff_key($current_extensions['theme'], $new_extensions['theme']));
}