123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- <?php
- namespace Drupal\features_ui\Controller;
- use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
- use Symfony\Component\DependencyInjection\ContainerInterface;
- use Symfony\Component\HttpFoundation\JsonResponse;
- use Drupal\features\FeaturesManagerInterface;
- use Drupal\features\FeaturesAssignerInterface;
- /**
- * Returns ajax responses for the Features UI.
- */
- class FeaturesUIController implements ContainerInjectionInterface {
- /**
- * The features manager.
- *
- * @var \Drupal\features\FeaturesManagerInterface
- */
- protected $featuresManager;
- /**
- * The package assigner.
- *
- * @var array
- */
- protected $assigner;
- /**
- * Constructs a new FeaturesUIController object.
- *
- * @param \Drupal\features\FeaturesManagerInterface $features_manager
- * The features manager.
- */
- public function __construct(FeaturesManagerInterface $features_manager, FeaturesAssignerInterface $assigner) {
- $this->featuresManager = $features_manager;
- $this->assigner = $assigner;
- }
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container) {
- return new static(
- $container->get('features.manager'),
- $container->get('features_assigner')
- );
- }
- /**
- * Returns a list of auto-detected config items for a feature.
- *
- * @param string $name
- * Short machine name of feature to process.
- *
- * @return array
- * List of auto-detected config items, keyed by type and short name.
- */
- public function detect($name) {
- $detected = array();
- $this->assigner->assignConfigPackages();
- $config_collection = $this->featuresManager->getConfigCollection();
- $items = $_POST['items'];
- if (!empty($items)) {
- $excluded = (!empty($_POST['excluded'])) ? $_POST['excluded'] : array();
- $selected = array();
- foreach ($items as $key) {
- preg_match('/^([^\[]+)(\[.+\])?\[(.+)\]\[(.+)\]$/', $key, $matches);
- if (!empty($matches[1]) && !empty($matches[4])) {
- $component = $matches[1];
- $item = $this->domDecode($matches[4]);
- if (!isset($excluded[$component][$item])) {
- $selected[] = $this->featuresManager->getFullName($component, $item);
- }
- }
- }
- $detected = !empty($selected) ? $this->getConfigDependents($selected, $name) : array();
- $detected = array_merge($detected, $selected);
- }
- $result = [];
- foreach ($detected as $config_name) {
- $item = $config_collection[$config_name];
- $result[$item->getType()][$item->getShortName()] = $item->getName();
- }
- return new JsonResponse($result);
- }
- /**
- * Returns the configuration dependent on given items.
- *
- * @param array $item_names
- * An array of item names.
- * @param string $package_name
- * Short machine name of feature to process.
- *
- * @return array
- * An array of config items.
- */
- protected function getConfigDependents(array $item_names, $package_name) {
- $result = [];
- $config_collection = $this->featuresManager->getConfigCollection();
- $packages = $this->featuresManager->getPackages();
- $settings = $this->featuresManager->getSettings();
- $allow_conflicts = $settings->get('conflicts');
- if (empty($item_names)) {
- $item_names = array_keys($config_collection);
- }
- // Add any existing auto-detected items already in the package config
- $this->package = $packages[$package_name];
- $package_config = isset($this->package) ? $this->package->getConfig() : array();
- $package_config = !empty($package_config) ? array_unique(array_merge($package_config, $item_names)) : $item_names;
- foreach ($package_config as $config_name) {
- if (!$config_collection[$config_name]->getPackageExcluded()) {
- $result[] = $config_name;
- }
- }
- // Now add dependents of the items selected
- foreach ($item_names as $item_name) {
- if ($config_collection[$item_name]->getPackage()) {
- foreach ($config_collection[$item_name]->getDependents() as $dependent_item_name) {
- if (isset($config_collection[$dependent_item_name])) {
- $allow = TRUE;
- if (!$allow_conflicts && $config_collection[$dependent_item_name]->getPackage()) {
- if ($packages[$config_collection[$dependent_item_name]->getPackage()]) {
- $allow = ($packages[$config_collection[$dependent_item_name]->getPackage()]->getStatus() == FeaturesManagerInterface::STATUS_NO_EXPORT)
- || ($config_collection[$item_name]->getPackage() == $config_collection[$dependent_item_name]->getPackage());
- }
- }
- if ($allow) {
- $result[] = $dependent_item_name;
- }
- }
- }
- }
- }
- return $result;
- }
- /**
- * Encodes a given key.
- *
- * @param string $key
- * The key to encode.
- *
- * @return string
- * The encoded key.
- */
- protected function domEncode($key) {
- $replacements = $this->domEncodeMap();
- return strtr($key, $replacements);
- }
- /**
- * Decodes a given key.
- *
- * @param string $key
- * The key to decode.
- *
- * @return string
- * The decoded key.
- */
- protected function domDecode($key) {
- $replacements = array_flip($this->domEncodeMap());
- return strtr($key, $replacements);
- }
- /**
- * Returns encoding map for decode and encode options.
- *
- * @return array
- * An encoding map.
- */
- protected function domEncodeMap() {
- return array(
- ':' => '__' . ord(':') . '__',
- '/' => '__' . ord('/') . '__',
- ',' => '__' . ord(',') . '__',
- '.' => '__' . ord('.') . '__',
- '<' => '__' . ord('<') . '__',
- '>' => '__' . ord('>') . '__',
- '%' => '__' . ord('%') . '__',
- ')' => '__' . ord(')') . '__',
- '(' => '__' . ord('(') . '__',
- );
- }
- }
|