You are here

FeaturesAssignmentForwardDependency.php in Features 8.4

File

src/Plugin/FeaturesAssignment/FeaturesAssignmentForwardDependency.php
View source
<?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);
  }

}

Classes

Namesort descending Description
FeaturesAssignmentForwardDependency Class for assigning configuration to packages based on forward dependencies.