Example #1
0
 /**
  * {@inheritdoc}
  */
 public function buildDependencyMigration(array $migrations, array $dynamic_ids)
 {
     // Migration dependencies defined in the migration storage can be
     // optional or required. If an optional dependency does not run, the current
     // migration is still OK to go. Both optional and required dependencies
     // (if run at all) must run before the current migration.
     $dependency_graph = array();
     $requirement_graph = array();
     $different = FALSE;
     foreach ($migrations as $migration) {
         /** @var \Drupal\migrate\Entity\MigrationInterface $migration */
         $id = $migration->id();
         $requirements[$id] = array();
         $dependency_graph[$id]['edges'] = array();
         $migration_dependencies = $migration->getMigrationDependencies();
         if (isset($migration_dependencies['required'])) {
             foreach ($migration_dependencies['required'] as $dependency) {
                 if (!isset($dynamic_ids[$dependency])) {
                     $this->addDependency($requirement_graph, $id, $dependency, $dynamic_ids);
                 }
                 $this->addDependency($dependency_graph, $id, $dependency, $dynamic_ids);
             }
         }
         if (isset($migration_dependencies['optional'])) {
             foreach ($migration_dependencies['optional'] as $dependency) {
                 $different = TRUE;
                 $this->addDependency($dependency_graph, $id, $dependency, $dynamic_ids);
             }
         }
     }
     $graph_object = new Graph($dependency_graph);
     $dependency_graph = $graph_object->searchAndSort();
     if ($different) {
         $graph_object = new Graph($requirement_graph);
         $requirement_graph = $graph_object->searchAndSort();
     } else {
         $requirement_graph = $dependency_graph;
     }
     $weights = array();
     foreach ($migrations as $migration_id => $migration) {
         // Populate a weights array to use with array_multisort later.
         $weights[] = $dependency_graph[$migration_id]['weight'];
         if (!empty($requirement_graph[$migration_id]['paths'])) {
             $migration->set('requirements', $requirement_graph[$migration_id]['paths']);
         }
     }
     array_multisort($weights, SORT_DESC, SORT_NUMERIC, $migrations);
     return $migrations;
 }
 /**
  * Get config items such that each item comes before anything it depends on.
  *
  * @param \Drupal\features\ConfigurationItem[] $config_collection
  *   A collection of configuration items.
  *
  * @return string[]
  *   The names of configuration items, in dependency order.
  */
 protected function dependencyOrder($config_collection)
 {
     // Populate a graph.
     $graph = [];
     foreach ($config_collection as $config) {
         $graph[$config->getName()] = [];
         foreach ($config->getDependents() as $dependent) {
             $graph[$config->getName()]['edges'][$dependent] = 1;
         }
     }
     $graph_object = new Graph($graph);
     $graph = $graph_object->searchAndSort();
     // Order by inverse weight.
     $weights = array_column($graph, 'weight');
     array_multisort($weights, SORT_DESC, $graph);
     return array_keys($graph);
 }
Example #3
0
 /**
  * Test depth-first-search features.
  */
 public function testDepthFirstSearch()
 {
     // The sample graph used is:
     // 1 --> 2 --> 3     5 ---> 6
     //       |     ^     ^
     //       |     |     |
     //       |     |     |
     //       +---> 4 <-- 7      8 ---> 9
     $graph = $this->normalizeGraph(array(1 => array(2), 2 => array(3, 4), 3 => array(), 4 => array(3), 5 => array(6), 7 => array(4, 5), 8 => array(9), 9 => array()));
     $graph_object = new Graph($graph);
     $graph = $graph_object->searchAndSort();
     $expected_paths = array(1 => array(2, 3, 4), 2 => array(3, 4), 3 => array(), 4 => array(3), 5 => array(6), 7 => array(4, 3, 5, 6), 8 => array(9), 9 => array());
     $this->assertPaths($graph, $expected_paths);
     $expected_reverse_paths = array(1 => array(), 2 => array(1), 3 => array(2, 1, 4, 7), 4 => array(2, 1, 7), 5 => array(7), 7 => array(), 8 => array(), 9 => array(8));
     $this->assertReversePaths($graph, $expected_reverse_paths);
     // Assert that DFS didn't created "missing" vertexes automatically.
     $this->assertFalse(isset($graph[6]), 'Vertex 6 has not been created');
     $expected_components = array(array(1, 2, 3, 4, 5, 7), array(8, 9));
     $this->assertComponents($graph, $expected_components);
     $expected_weights = array(array(1, 2, 3), array(2, 4, 3), array(7, 4, 3), array(7, 5), array(8, 9));
     $this->assertWeights($graph, $expected_weights);
 }
Example #4
0
 /**
  * {@inheritdoc}
  */
 public function buildModuleDependencies(array $modules)
 {
     foreach ($modules as $module) {
         $graph[$module->getName()]['edges'] = array();
         if (isset($module->info['dependencies']) && is_array($module->info['dependencies'])) {
             foreach ($module->info['dependencies'] as $dependency) {
                 $dependency_data = static::parseDependency($dependency);
                 $graph[$module->getName()]['edges'][$dependency_data['name']] = $dependency_data;
             }
         }
     }
     $graph_object = new Graph($graph);
     $graph = $graph_object->searchAndSort();
     foreach ($graph as $module_name => $data) {
         $modules[$module_name]->required_by = isset($data['reverse_paths']) ? $data['reverse_paths'] : array();
         $modules[$module_name]->requires = isset($data['paths']) ? $data['paths'] : array();
         $modules[$module_name]->sort = $data['weight'];
     }
     return $modules;
 }
 /**
  * Gets the dependency graph of all the config entities.
  *
  * @return array
  *   The dependency graph of all the config entities.
  */
 protected function getGraph()
 {
     if (!isset($this->graph)) {
         $graph = array();
         foreach ($this->data as $entity) {
             $graph_key = $entity->getConfigDependencyName();
             $graph[$graph_key]['edges'] = array();
             $dependencies = $entity->getDependencies('config');
             if (!empty($dependencies)) {
                 foreach ($dependencies as $dependency) {
                     $graph[$graph_key]['edges'][$dependency] = TRUE;
                 }
             }
         }
         $graph_object = new Graph($graph);
         $this->graph = $graph_object->searchAndSort();
     }
     return $this->graph;
 }
 /**
  * Gets the dependency graph of all the config entities.
  *
  * @return array
  *   The dependency graph of all the config entities.
  */
 protected function getGraph()
 {
     if (!isset($this->graph)) {
         $graph = array();
         foreach ($this->data as $entity) {
             $graph_key = $entity->getConfigDependencyName();
             if (!isset($graph[$graph_key])) {
                 $graph[$graph_key] = ['edges' => [], 'name' => $graph_key];
             }
             // Include all dependencies in the graph so that topographical sorting
             // works.
             foreach (array_merge($entity->getDependencies('config'), $entity->getDependencies('module'), $entity->getDependencies('theme')) as $dependency) {
                 $graph[$dependency]['edges'][$graph_key] = TRUE;
                 $graph[$dependency]['name'] = $dependency;
             }
         }
         // Ensure that order of the graph is consistent.
         krsort($graph);
         $graph_object = new Graph($graph);
         $this->graph = $graph_object->searchAndSort();
     }
     return $this->graph;
 }
 protected function sortTree(array $graph)
 {
     $graph_object = new Graph($graph);
     $sorted = $graph_object->searchAndSort();
     uasort($sorted, 'Drupal\\Component\\Utility\\SortArray::sortByWeightElement');
     return array_reverse($sorted);
 }