Mercurial > hg > isophonics-drupal-site
comparison core/lib/Drupal/Core/Config/ConfigManager.php @ 12:7a779792577d
Update Drupal core to v8.4.5 (via Composer)
author | Chris Cannam |
---|---|
date | Fri, 23 Feb 2018 15:52:07 +0000 |
parents | 4c8ae668cc8c |
children | af1871eacc83 |
comparison
equal
deleted
inserted
replaced
11:bfffd8d7479a | 12:7a779792577d |
---|---|
290 | 290 |
291 /** | 291 /** |
292 * {@inheritdoc} | 292 * {@inheritdoc} |
293 */ | 293 */ |
294 public function getConfigEntitiesToChangeOnDependencyRemoval($type, array $names, $dry_run = TRUE) { | 294 public function getConfigEntitiesToChangeOnDependencyRemoval($type, array $names, $dry_run = TRUE) { |
295 // Determine the current list of dependent configuration entities and set up | |
296 // initial values. | |
297 $dependency_manager = $this->getConfigDependencyManager(); | 295 $dependency_manager = $this->getConfigDependencyManager(); |
298 $dependents = $this->findConfigEntityDependentsAsEntities($type, $names, $dependency_manager); | 296 |
299 $original_dependencies = $dependents; | 297 // Store the list of dependents in three separate variables. This allows us |
300 $delete_uuids = []; | 298 // to determine how the dependency graph changes as entities are fixed by |
301 | 299 // calling the onDependencyRemoval() method. |
300 | |
301 // The list of original dependents on $names. This list never changes. | |
302 $original_dependents = $this->findConfigEntityDependentsAsEntities($type, $names, $dependency_manager); | |
303 | |
304 // The current list of dependents on $names. This list is recalculated when | |
305 // calling an entity's onDependencyRemoval() method results in the entity | |
306 // changing. This list is passed to each entity's onDependencyRemoval() | |
307 // method as the list of affected entities. | |
308 $current_dependents = $original_dependents; | |
309 | |
310 // The list of dependents to process. This list changes as entities are | |
311 // processed and are either fixed or deleted. | |
312 $dependents_to_process = $original_dependents; | |
313 | |
314 // Initialize other variables. | |
315 $affected_uuids = []; | |
302 $return = [ | 316 $return = [ |
303 'update' => [], | 317 'update' => [], |
304 'delete' => [], | 318 'delete' => [], |
305 'unchanged' => [], | 319 'unchanged' => [], |
306 ]; | 320 ]; |
307 | 321 |
308 // Create a map of UUIDs to $original_dependencies key so that we can remove | 322 // Try to fix the dependents and find out what will happen to the dependency |
309 // fixed dependencies. | 323 // graph. Entities are processed in the order of most dependent first. For |
310 $uuid_map = []; | 324 // example, this ensures that Menu UI third party dependencies on node types |
311 foreach ($original_dependencies as $key => $entity) { | 325 // are fixed before processing the node type's other dependents. |
312 $uuid_map[$entity->uuid()] = $key; | 326 while ($dependent = array_pop($dependents_to_process)) { |
313 } | |
314 | |
315 // Try to fix any dependencies and find out what will happen to the | |
316 // dependency graph. Entities are processed in the order of most dependent | |
317 // first. For example, this ensures that Menu UI third party dependencies on | |
318 // node types are fixed before processing the node type's other | |
319 // dependencies. | |
320 while ($dependent = array_pop($dependents)) { | |
321 /** @var \Drupal\Core\Config\Entity\ConfigEntityInterface $dependent */ | 327 /** @var \Drupal\Core\Config\Entity\ConfigEntityInterface $dependent */ |
322 if ($dry_run) { | 328 if ($dry_run) { |
323 // Clone the entity so any changes do not change any static caches. | 329 // Clone the entity so any changes do not change any static caches. |
324 $dependent = clone $dependent; | 330 $dependent = clone $dependent; |
325 } | 331 } |
326 $fixed = FALSE; | 332 $fixed = FALSE; |
327 if ($this->callOnDependencyRemoval($dependent, $original_dependencies, $type, $names)) { | 333 if ($this->callOnDependencyRemoval($dependent, $current_dependents, $type, $names)) { |
328 // Recalculate dependencies and update the dependency graph data. | 334 // Recalculate dependencies and update the dependency graph data. |
329 $dependent->calculateDependencies(); | 335 $dependent->calculateDependencies(); |
330 $dependency_manager->updateData($dependent->getConfigDependencyName(), $dependent->getDependencies()); | 336 $dependency_manager->updateData($dependent->getConfigDependencyName(), $dependent->getDependencies()); |
331 // Based on the updated data rebuild the list of dependents. This will | 337 // Based on the updated data rebuild the list of current dependents. |
332 // remove entities that are no longer dependent after the recalculation. | 338 // This will remove entities that are no longer dependent after the |
333 $dependents = $this->findConfigEntityDependentsAsEntities($type, $names, $dependency_manager); | 339 // recalculation. |
334 // Remove any entities that we've already marked for deletion. | 340 $current_dependents = $this->findConfigEntityDependentsAsEntities($type, $names, $dependency_manager); |
335 $dependents = array_filter($dependents, function ($dependent) use ($delete_uuids) { | 341 // Rebuild the list of entities that we need to process using the new |
336 return !in_array($dependent->uuid(), $delete_uuids); | 342 // list of current dependents and removing any entities that we've |
343 // already processed. | |
344 $dependents_to_process = array_filter($current_dependents, function ($current_dependent) use ($affected_uuids) { | |
345 return !in_array($current_dependent->uuid(), $affected_uuids); | |
337 }); | 346 }); |
338 // Ensure that the dependency has actually been fixed. It is possible | 347 // Ensure that the dependent has actually been fixed. It is possible |
339 // that the dependent has multiple dependencies that cause it to be in | 348 // that other dependencies cause it to still be in the list. |
340 // the dependency chain. | |
341 $fixed = TRUE; | 349 $fixed = TRUE; |
342 foreach ($dependents as $key => $entity) { | 350 foreach ($dependents_to_process as $key => $entity) { |
343 if ($entity->uuid() == $dependent->uuid()) { | 351 if ($entity->uuid() == $dependent->uuid()) { |
344 $fixed = FALSE; | 352 $fixed = FALSE; |
345 unset($dependents[$key]); | 353 unset($dependents_to_process[$key]); |
346 break; | 354 break; |
347 } | 355 } |
348 } | 356 } |
349 if ($fixed) { | 357 if ($fixed) { |
350 // Remove the fixed dependency from the list of original dependencies. | 358 $affected_uuids[] = $dependent->uuid(); |
351 unset($original_dependencies[$uuid_map[$dependent->uuid()]]); | |
352 $return['update'][] = $dependent; | 359 $return['update'][] = $dependent; |
353 } | 360 } |
354 } | 361 } |
355 // If the entity cannot be fixed then it has to be deleted. | 362 // If the entity cannot be fixed then it has to be deleted. |
356 if (!$fixed) { | 363 if (!$fixed) { |
357 $delete_uuids[] = $dependent->uuid(); | 364 $affected_uuids[] = $dependent->uuid(); |
358 // Deletes should occur in the order of the least dependent first. For | 365 // Deletes should occur in the order of the least dependent first. For |
359 // example, this ensures that fields are removed before field storages. | 366 // example, this ensures that fields are removed before field storages. |
360 array_unshift($return['delete'], $dependent); | 367 array_unshift($return['delete'], $dependent); |
361 } | 368 } |
362 } | 369 } |
363 // Use the lists of UUIDs to filter the original list to work out which | 370 // Use the list of affected UUIDs to filter the original list to work out |
364 // configuration entities are unchanged. | 371 // which configuration entities are unchanged. |
365 $return['unchanged'] = array_filter($original_dependencies, function ($dependent) use ($delete_uuids) { | 372 $return['unchanged'] = array_filter($original_dependents, function ($dependent) use ($affected_uuids) { |
366 return !(in_array($dependent->uuid(), $delete_uuids)); | 373 return !(in_array($dependent->uuid(), $affected_uuids)); |
367 }); | 374 }); |
368 | 375 |
369 return $return; | 376 return $return; |
370 } | 377 } |
371 | 378 |