diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigDependencyManager.php b/core/lib/Drupal/Core/Config/Entity/ConfigDependencyManager.php index b7eb9db..c274f28 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigDependencyManager.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigDependencyManager.php @@ -187,11 +187,32 @@ public function getDependentEntities($type, $name) { */ public function sortAll() { $graph = $this->getGraph(); - // Sort by reverse weight and alphabetically. The most dependent entities + // Sort by weight and alphabetically. The most dependent entities // are last and entities with the same weight are alphabetically ordered. - uasort($graph, array($this, 'sortGraph')); + uasort($graph, array($this, 'sortGraphByWeight')); // Use array_intersect_key() to exclude modules and themes from the list. - return array_reverse(array_keys(array_intersect_key($graph, $this->data))); + return array_keys(array_intersect_key($graph, $this->data)); + } + + /** + * Sorts the dependency graph by weight and alphabetically. + * + * @param array $a + * First item for comparison. The compared items should be associative + * arrays that include a 'weight' and a 'name' key. + * @param array $b + * Second item for comparison. + * + * @return int + * The comparison result for uasort(). + */ + protected function sortGraphByWeight(array $a, array $b) { + $weight_cmp = SortArray::sortByKeyInt($a, $b, 'weight'); + + if ($weight_cmp === 0) { + return SortArray::sortByKeyString($a, $b, 'name'); + } + return $weight_cmp; } /** @@ -266,6 +287,8 @@ protected function getGraph() { $graph[$dependency]['name'] = $dependency; } } + // Ensure that order of the graph is consistent. + krsort($graph); $graph_object = new Graph($graph); $this->graph = $graph_object->searchAndSort(); } diff --git a/core/tests/Drupal/Tests/Core/Config/ConfigDependencyManagerTest.php b/core/tests/Drupal/Tests/Core/Config/ConfigDependencyManagerTest.php new file mode 100644 index 0000000..bd1af59 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Config/ConfigDependencyManagerTest.php @@ -0,0 +1,120 @@ +setData($data); + $this->assertEquals($expected_order, $dependency_manager->sortAll()); + } + + public function providerTestSortAll() { + $datasets[] = [ + [ + 'provider.entity_b' => [], + 'provider.entity_a' => [], + ], + ['provider.entity_a', 'provider.entity_b'], + ]; + + $datasets[] = [ + [ + 'provider.entity_a' => [], + 'provider.entity_b' => [], + ], + ['provider.entity_a', 'provider.entity_b'], + ]; + + $datasets[] = [ + [ + 'provider.entity_b' => ['dependencies' => ['config' => ['provider.entity_a']]], + 'provider.entity_a' => [], + ], + ['provider.entity_a', 'provider.entity_b'], + ]; + + $datasets[] = [ + [ + 'provider.entity_a' => [], + 'provider.entity_b' => ['dependencies' => ['config' => ['provider.entity_a']]], + ], + ['provider.entity_a', 'provider.entity_b'], + ]; + + $datasets[] = [ + [ + 'provider.entity_b' => [], + 'provider.entity_a' => ['dependencies' => ['config' => ['provider.entity_b']]], + ], + ['provider.entity_b', 'provider.entity_a'], + ]; + + $datasets[] = [ + [ + 'provider.entity_a' => ['dependencies' => ['config' => ['provider.entity_b']]], + 'provider.entity_b' => [], + ], + ['provider.entity_b', 'provider.entity_a'], + ]; + + $datasets[] = [ + [ + 'provider.entity_a' => ['dependencies' => ['config' => ['provider.entity_b']]], + 'provider.entity_b' => [], + 'block.block.a' => [], + 'block.block.b' => [], + ], + ['block.block.a', 'provider.entity_b', 'block.block.b', 'provider.entity_a'], + ]; + + $datasets[] = [ + [ + 'provider.entity_b' => [], + 'block.block.b' => [], + 'block.block.a' => [], + 'provider.entity_a' => ['dependencies' => ['config' => ['provider.entity_b']]], + ], + ['block.block.a', 'provider.entity_b', 'block.block.b', 'provider.entity_a'], + ]; + + $datasets[] = [ + [ + 'provider.entity_b' => [], + 'block.block.b' => [], + 'block.block.a' => [], + 'provider.entity_a' => ['dependencies' => ['config' => ['provider.entity_b']]], + 'provider.entity_c' => ['dependencies' => ['config' => ['block.block.a']]], + ], + ['block.block.a', 'block.block.b', 'provider.entity_b', 'provider.entity_a', 'provider.entity_c'], + ]; + + $datasets[] = [ + [ + 'provider.entity_b' => ['dependencies' => ['module' => ['system']]], + 'block.block.b' => [], + 'block.block.a' => ['dependencies' => ['module' => ['system']]], + 'provider.entity_a' => ['dependencies' => ['config' => ['provider.entity_c']]], + 'provider.entity_c' => ['dependencies' => ['config' => ['block.block.a']]], + ], + ['block.block.b', 'block.block.a', 'provider.entity_c', 'provider.entity_a', 'provider.entity_b'], + ]; + + return $datasets; + } + +} diff --git a/core/tests/Drupal/Tests/Core/Config/StorageComparerTest.php b/core/tests/Drupal/Tests/Core/Config/StorageComparerTest.php index 982ab81..e339af7 100644 --- a/core/tests/Drupal/Tests/Core/Config/StorageComparerTest.php +++ b/core/tests/Drupal/Tests/Core/Config/StorageComparerTest.php @@ -158,8 +158,8 @@ public function testCreateChangelistCreate() { $this->storageComparer->createChangelist(); $expected = array( 'field.storage.node.body', - 'views.view.test_view', 'field.field.node.article.body', + 'views.view.test_view', ); $this->assertEquals($expected, $this->storageComparer->getChangelist('create')); $this->assertEmpty($this->storageComparer->getChangelist('delete')); @@ -196,8 +196,8 @@ public function testCreateChangelistDelete() { $this->storageComparer->createChangelist(); $expected = array( - 'field.field.node.article.body', 'views.view.test_view', + 'field.field.node.article.body', 'field.storage.node.body', ); $this->assertEquals($expected, $this->storageComparer->getChangelist('delete')); @@ -236,8 +236,8 @@ public function testCreateChangelistUpdate() { $this->storageComparer->createChangelist(); $expected = array( 'field.storage.node.body', - 'system.site', 'field.field.node.article.body', + 'system.site', ); $this->assertEquals($expected, $this->storageComparer->getChangelist('update')); $this->assertEmpty($this->storageComparer->getChangelist('create'));