features-8.x-3.11/src/Plugin/FeaturesAssignment/FeaturesAssignmentForwardDependency.php
src/Plugin/FeaturesAssignment/FeaturesAssignmentForwardDependency.php
<?php
namespace Drupal\features\Plugin\FeaturesAssignment;
use Drupal\Component\Graph\Graph;
use Drupal\features\FeaturesAssignmentMethodBase;
/**
* Class for assigning configuration to packages based on forward dependencies.
*
* @Plugin(
* id = "forward_dependency",
* weight = 20,
* name = @Translation("Forward dependency"),
* description = @Translation("Add to packages configuration on which items in the package depend."),
* )
*/
class FeaturesAssignmentForwardDependency extends FeaturesAssignmentMethodBase {
/**
* {@inheritdoc}
*/
public function assignPackages($force = FALSE) {
$config_collection = $this->featuresManager->getConfigCollection();
$ordered = $this->dependencyOrder($config_collection);
foreach ($ordered as $name) {
$item = $config_collection[$name];
if ($item->getPackage()) {
// Already has a package, not our business.
continue;
}
// Find packages of dependent items.
$dependent_packages = [];
foreach ($item->getDependents() as $dependent) {
if (isset($config_collection[$dependent])) {
if ($package = $config_collection[$dependent]->getPackage()) {
$dependent_packages[$package] = $package;
}
}
}
// If zero or multiple packages, we don't know what to do.
if (count($dependent_packages) == 1) {
$package = key($dependent_packages);
$this->featuresManager->assignConfigPackage($package, [$name]);
}
}
}
/**
* 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(array $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);
}
}
