function ConfigManager::getConfigEntitiesToChangeOnDependencyRemoval

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Config/ConfigManager.php \Drupal\Core\Config\ConfigManager::getConfigEntitiesToChangeOnDependencyRemoval()
  2. 10 core/lib/Drupal/Core/Config/ConfigManager.php \Drupal\Core\Config\ConfigManager::getConfigEntitiesToChangeOnDependencyRemoval()
  3. 11.x core/lib/Drupal/Core/Config/ConfigManager.php \Drupal\Core\Config\ConfigManager::getConfigEntitiesToChangeOnDependencyRemoval()

Overrides ConfigManagerInterface::getConfigEntitiesToChangeOnDependencyRemoval

1 call to ConfigManager::getConfigEntitiesToChangeOnDependencyRemoval()
ConfigManager::uninstall in core/lib/Drupal/Core/Config/ConfigManager.php
Uninstalls the configuration of a given extension.

File

core/lib/Drupal/Core/Config/ConfigManager.php, line 318

Class

ConfigManager
The ConfigManager provides helper functions for the configuration system.

Namespace

Drupal\Core\Config

Code

public function getConfigEntitiesToChangeOnDependencyRemoval($type, array $names, $dry_run = TRUE) {
    $dependency_manager = $this->getConfigDependencyManager();
    // Store the list of dependents in three separate variables. This allows us
    // to determine how the dependency graph changes as entities are fixed by
    // calling the onDependencyRemoval() method.
    // The list of original dependents on $names. This list never changes.
    $original_dependents = $this->findConfigEntityDependentsAsEntities($type, $names, $dependency_manager);
    // The current list of dependents on $names. This list is recalculated when
    // calling an entity's onDependencyRemoval() method results in the entity
    // changing. This list is passed to each entity's onDependencyRemoval()
    // method as the list of affected entities.
    $current_dependents = $original_dependents;
    // The list of dependents to process. This list changes as entities are
    // processed and are either fixed or deleted.
    $dependents_to_process = $original_dependents;
    // Initialize other variables.
    $affected_uuids = [];
    $return = [
        'update' => [],
        'delete' => [],
        'unchanged' => [],
    ];
    // Try to fix the dependents and find out what will happen to the dependency
    // graph. Entities are processed in the order of most dependent first. For
    // example, this ensures that Menu UI third party dependencies on node types
    // are fixed before processing the node type's other dependents.
    while ($dependent = array_pop($dependents_to_process)) {
        
        /** @var \Drupal\Core\Config\Entity\ConfigEntityInterface $dependent */
        if ($dry_run) {
            // Clone the entity so any changes do not change any static caches.
            $dependent = clone $dependent;
        }
        $fixed = FALSE;
        if ($this->callOnDependencyRemoval($dependent, $current_dependents, $type, $names)) {
            // Recalculate dependencies and update the dependency graph data.
            $dependent->calculateDependencies();
            $dependency_manager->updateData($dependent->getConfigDependencyName(), $dependent->getDependencies());
            // Based on the updated data rebuild the list of current dependents.
            // This will remove entities that are no longer dependent after the
            // recalculation.
            $current_dependents = $this->findConfigEntityDependentsAsEntities($type, $names, $dependency_manager);
            // Rebuild the list of entities that we need to process using the new
            // list of current dependents and removing any entities that we've
            // already processed.
            $dependents_to_process = array_filter($current_dependents, function ($current_dependent) use ($affected_uuids) {
                return !in_array($current_dependent->uuid(), $affected_uuids);
            });
            // Ensure that the dependent has actually been fixed. It is possible
            // that other dependencies cause it to still be in the list.
            $fixed = TRUE;
            foreach ($dependents_to_process as $key => $entity) {
                if ($entity->uuid() == $dependent->uuid()) {
                    $fixed = FALSE;
                    unset($dependents_to_process[$key]);
                    break;
                }
            }
            if ($fixed) {
                $affected_uuids[] = $dependent->uuid();
                $return['update'][] = $dependent;
            }
        }
        // If the entity cannot be fixed then it has to be deleted.
        if (!$fixed) {
            $affected_uuids[] = $dependent->uuid();
            // Deletes should occur in the order of the least dependent first. For
            // example, this ensures that fields are removed before field storages.
            array_unshift($return['delete'], $dependent);
        }
    }
    // Use the list of affected UUIDs to filter the original list to work out
    // which configuration entities are unchanged.
    $return['unchanged'] = array_filter($original_dependents, function ($dependent) use ($affected_uuids) {
        return !in_array($dependent->uuid(), $affected_uuids);
    });
    return $return;
}

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