/** * {@inheritdoc} */ public function getExportInfo(Package $package, FeaturesBundleInterface $bundle = NULL) { $full_name = isset($bundle) ? $bundle->getFullName($package->getMachineName()) : $package->getMachineName(); $path = ''; // Adjust export directory to be in profile. if (isset($bundle) && $bundle->isProfile()) { $path .= 'profiles/' . $bundle->getProfileName(); } // If this is not the profile package, nest the directory. if (!isset($bundle) || !$bundle->isProfilePackage($package->getMachineName())) { $path .= empty($path) ? 'modules' : '/modules'; $export_settings = $this->getExportSettings(); if (!empty($export_settings['folder'])) { $path .= '/' . $export_settings['folder']; } } return array($full_name, $path); }
/** * Adds the optional bundle prefix to package machine names. * * @param string[] &$package_names * Array of package names, passed by reference. * @param \Drupal\features\FeaturesBundleInterface $bundle * The optional bundle used for the generation. Used to generate profiles. */ protected function setPackageBundleNames(array &$package_names, FeaturesBundleInterface $bundle = NULL) { if ($bundle && !$bundle->isDefault()) { $new_package_names = []; // Assign the selected bundle to the exports. $packages = $this->featuresManager->getPackages(); foreach ($package_names as $package_name) { // Rename package to use bundle prefix. $package = $packages[$package_name]; // The install profile doesn't need renaming. if ($package['type'] != 'profile') { unset($packages[$package_name]); $package['machine_name'] = $bundle->getFullName($package['machine_name']); $packages[$package['machine_name']] = $package; } // Set the bundle machine name. $packages[$package['machine_name']]['bundle'] = $bundle->getMachineName(); $new_package_names[] = $package['machine_name']; } $this->featuresManager->setPackages($packages); $package_names = $new_package_names; } }
/** * Builds the details of a package. * * @param \Drupal\features\Package $package * The package. * @param \Drupal\features\FeaturesBundleInterface * The current bundle. * * @return array * A render array of a form element. */ protected function buildPackageDetail(Package $package, FeaturesBundleInterface $bundle) { $config_collection = $this->featuresManager->getConfigCollection(); $url = Url::fromRoute('features.edit', array('featurename' => $package->getMachineName())); $element['name'] = array('data' => \Drupal::l($package->getName(), $url), 'class' => array('feature-name')); $machine_name = $package->getMachineName(); // Except for the 'unpackaged' pseudo-package, display the full name, since // that's what will be generated. if ($machine_name !== 'unpackaged') { $machine_name = $bundle->getFullName($machine_name); } $element['machine_name'] = $machine_name; $element['status'] = array('data' => $this->featuresManager->statusLabel($package->getStatus()), 'class' => array('column-nowrap')); // Use 'data' instead of plain string value so a blank version doesn't // remove column from table. $element['version'] = array('data' => Html::escape($package->getVersion()), 'class' => array('column-nowrap')); $overrides = $this->featuresManager->detectOverrides($package); $new_config = $this->featuresManager->detectNew($package); $conflicts = array(); $missing = array(); $moved = array(); if ($package->getStatus() == FeaturesManagerInterface::STATUS_NO_EXPORT) { $overrides = array(); $new_config = array(); } // Bundle package configuration by type. $package_config = array(); foreach ($package->getConfig() as $item_name) { if (isset($config_collection[$item_name])) { $item = $config_collection[$item_name]; $package_config[$item->getType()][] = array('name' => Html::escape($item_name), 'label' => Html::escape($item->getLabel()), 'class' => in_array($item_name, $overrides) ? 'features-override' : (in_array($item_name, $new_config) ? 'features-detected' : '')); } } // Conflict config from other modules. foreach ($package->getConfigOrig() as $item_name) { if (!isset($config_collection[$item_name])) { $missing[] = $item_name; $package_config['missing'][] = array('name' => Html::escape($item_name), 'label' => Html::escape($item_name), 'class' => 'features-missing'); } elseif (!in_array($item_name, $package->getConfig())) { $item = $config_collection[$item_name]; if (empty($item->getProvider())) { $conflicts[] = $item_name; $package_name = !empty($item->getPackage()) ? $item->getPackage() : $this->t('PACKAGE NOT ASSIGNED'); $package_config[$item->getType()][] = array('name' => Html::escape($package_name), 'label' => Html::escape($item->getLabel()), 'class' => 'features-conflict'); } else { $moved[] = $item_name; $package_name = !empty($item->getPackage()) ? $item->getPackage() : $this->t('PACKAGE NOT ASSIGNED'); $package_config[$item->getType()][] = array('name' => $this->t('Moved to @package', array('@package' => $package_name)), 'label' => Html::escape($item->getLabel()), 'class' => 'features-moved'); } } } // Add dependencies. $package_config['dependencies'] = array(); foreach ($package->getDependencies() as $dependency) { $package_config['dependencies'][] = array('name' => $dependency, 'label' => $this->moduleHandler->getName($dependency), 'class' => ''); } $class = ''; $state_links = []; if (!empty($conflicts)) { $state_links[] = array('#type' => 'link', '#title' => $this->t('Conflicts'), '#url' => Url::fromRoute('features.edit', array('featurename' => $package->getMachineName())), '#attributes' => array('class' => array('features-conflict'))); } if (!empty($overrides)) { $state_links[] = array('#type' => 'link', '#title' => $this->featuresManager->stateLabel(FeaturesManagerInterface::STATE_OVERRIDDEN), '#url' => Url::fromRoute('features.diff', array('featurename' => $package->getMachineName())), '#attributes' => array('class' => array('features-override'))); } if (!empty($new_config)) { $state_links[] = array('#type' => 'link', '#title' => $this->t('New detected'), '#url' => Url::fromRoute('features.diff', array('featurename' => $package->getMachineName())), '#attributes' => array('class' => array('features-detected'))); } if (!empty($missing) && $package->getStatus() == FeaturesManagerInterface::STATUS_INSTALLED) { $state_links[] = array('#type' => 'link', '#title' => $this->t('Missing'), '#url' => Url::fromRoute('features.edit', array('featurename' => $package->getMachineName())), '#attributes' => array('class' => array('features-missing'))); } if (!empty($moved)) { $state_links[] = array('#type' => 'link', '#title' => $this->t('Moved'), '#url' => Url::fromRoute('features.edit', array('featurename' => $package->getMachineName())), '#attributes' => array('class' => array('features-moved'))); } if (!empty($state_links)) { $element['state'] = array('data' => $state_links, 'class' => array('column-nowrap')); } else { $element['state'] = ''; } $config_types = $this->featuresManager->listConfigTypes(); // Add dependencies. $config_types['dependencies'] = $this->t('Dependencies'); $config_types['missing'] = $this->t('Missing'); uasort($config_types, 'strnatcasecmp'); $rows = array(); // Use sorted array for order. foreach ($config_types as $type => $label) { // For each component type, offer alternating rows. $row = array(); if (isset($package_config[$type])) { $row[] = array('data' => array('#type' => 'html_tag', '#tag' => 'span', '#value' => Html::escape($label), '#attributes' => array('title' => Html::escape($type), 'class' => 'features-item-label'))); $row[] = array('data' => array('#theme' => 'features_items', '#items' => $package_config[$type], '#value' => Html::escape($label), '#title' => Html::escape($type)), 'class' => 'item'); $rows[] = $row; } } $element['table'] = array('#type' => 'table', '#rows' => $rows); $details = array(); $details['description'] = array('#markup' => Xss::filterAdmin($package->getDescription())); $details['table'] = array('#type' => 'details', '#title' => array('#markup' => $this->t('Included configuration')), '#description' => array('data' => $element['table'])); $element['details'] = array('class' => array('description', 'expand'), 'data' => $details); return $element; }