/**
  * {@inheritdoc}
  */
 public function generate(array $packages = array(), FeaturesBundleInterface $bundle = NULL)
 {
     // If no packages were specified, get all packages.
     if (empty($packages)) {
         $packages = $this->featuresManager->getPackages();
     }
     // Determine the best name for the tar archive.
     // Single package export, so name by package name.
     if (count($packages) == 1) {
         $filename = current($packages)->getMachineName();
     } elseif (isset($bundle) && $bundle->isProfile()) {
         $filename = $bundle->getProfileName();
     } elseif (isset($bundle) && !$bundle->isDefault()) {
         $filename = $bundle->getMachineName();
     } else {
         $filename = 'generated_features';
     }
     $return = [];
     $this->archiveName = $filename . '.tar.gz';
     $archive_name = file_directory_temp() . '/' . $this->archiveName;
     if (file_exists($archive_name)) {
         file_unmanaged_delete($archive_name);
     }
     $archiver = new ArchiveTar($archive_name);
     // Add package files.
     foreach ($packages as $package) {
         if (count($packages) == 1) {
             // Single module export, so don't generate entire modules dir structure.
             $package->setDirectory($package->getMachineName());
         }
         $this->generatePackage($return, $package, $archiver);
     }
     return $return;
 }
 /**
  * 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;
     }
 }
Example #3
0
 /**
  * {@inheritdoc}
  */
 public function setPackageBundleNames(FeaturesBundleInterface $bundle, array &$package_names = [])
 {
     $this->packagesPrefixed = TRUE;
     if (!$bundle->isDefault()) {
         $new_package_names = [];
         // Assign the selected bundle to the exports.
         $packages = $this->getPackages();
         if (empty($package_names)) {
             $package_names = array_keys($packages);
         }
         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->getType() != 'profile') {
                 unset($packages[$package_name]);
                 $package->setMachineName($bundle->getFullName($package->getMachineName()));
                 $packages[$package->getMachineName()] = $package;
             }
             // Set the bundle machine name.
             $packages[$package->getMachineName()]->setBundle($bundle->getMachineName());
             $new_package_names[] = $package->getMachineName();
         }
         $this->setPackages($packages);
         $package_names = $new_package_names;
     }
 }
 /**
  * {@inheritdoc}
  */
 public function getAllModules(FeaturesBundleInterface $bundle = NULL)
 {
     // ModuleHandler::getModuleDirectories() returns data only for installed
     // modules. system_rebuild_module_data() includes only the site's install
     // profile directory, while we may need to include a custom profile.
     // @see _system_rebuild_module_data().
     $listing = new ExtensionDiscovery(\Drupal::root());
     $profile_directories = [];
     // Register the install profile.
     $installed_profile = drupal_get_profile();
     if ($installed_profile) {
         $profile_directories[] = drupal_get_path('profile', $installed_profile);
     }
     if (isset($bundle) && $bundle->isProfile()) {
         $profile_directory = 'profiles/' . $bundle->getProfileName();
         if ($bundle->getProfileName() != $installed_profile && is_dir($profile_directory)) {
             $profile_directories[] = $profile_directory;
         }
     }
     $listing->setProfileDirectories($profile_directories);
     // Find modules.
     $modules = $listing->scan('module');
     // Find installation profiles.
     $profiles = $listing->scan('profile');
     foreach ($profiles as $key => $profile) {
         $modules[$key] = $profile;
     }
     $return = array();
     // Detect modules by namespace.
     // If namespace is provided but is empty, then match all modules.
     foreach ($modules as $module_name => $extension) {
         if ($this->isFeatureModule($extension) && (!isset($bundle) || $bundle->isDefault() || $bundle->inBundle($module_name))) {
             $return[$module_name] = $extension;
         }
     }
     return $return;
 }
 /**
  * @covers Drupal\features\Plugin\FeaturesAssignment\FeaturesAssignmentExclude
  */
 public function testAssignExclude()
 {
     $method_id = 'exclude';
     // Enable the method.
     $this->enableAssignmentMethod($method_id);
     // Also enable Packages and Core plugins.
     $this->enableAssignmentMethod('packages', FALSE);
     $this->enableAssignmentMethod('core', FALSE);
     // Apply the bundle
     $this->bundle = $this->assigner->loadBundle('test_mybundle');
     $this->assigner->applyAssignmentMethod('packages');
     $packages = $this->featuresManager->getPackages();
     $this->assertNotEmpty($packages[self::TEST_INSTALLED_PACKAGE], 'Expected package not created.');
     // 1. When Required is set to True, config should stay with the module
     // First, test with "Required" set to True.
     $packages[self::TEST_INSTALLED_PACKAGE]->setRequired(true);
     $this->featuresManager->setPackages($packages);
     $this->assigner->applyAssignmentMethod('exclude');
     $this->assigner->applyAssignmentMethod('core');
     $this->assigner->applyAssignmentMethod('existing');
     $packages = $this->featuresManager->getPackages();
     $expected_config_items = ['core.date_format.long'];
     $this->assertEquals($expected_config_items, $packages[self::TEST_INSTALLED_PACKAGE]->getConfig(), 'Expected configuration items not present in existing test_core package.');
     // 2. When Required is set to False, config still stays with module
     // Because the module is installed.
     $this->reset();
     $this->bundle = $this->assigner->loadBundle('test_mybundle');
     $this->assigner->applyAssignmentMethod('packages');
     $packages = $this->featuresManager->getPackages();
     $this->assertNotEmpty($packages[self::TEST_INSTALLED_PACKAGE], 'Expected test_mybundle_core package not created.');
     // Set "Required" set to False
     $packages[self::TEST_INSTALLED_PACKAGE]->setRequired(false);
     $this->featuresManager->setPackages($packages);
     $this->assigner->applyAssignmentMethod('exclude');
     $this->assigner->applyAssignmentMethod('core');
     $this->assigner->applyAssignmentMethod('existing');
     $packages = $this->featuresManager->getPackages();
     $this->assertFalse(array_key_exists('core', $packages), 'Core package should not be created.');
     $expected_config_items = ['core.date_format.long'];
     $this->assertEquals($expected_config_items, $packages[self::TEST_INSTALLED_PACKAGE]->getConfig(), 'Expected configuration items not present in existing test_core package.');
     // 3. When Required is set to False and module is NOT installed,
     // Config stays with module if it doesn't match the current namespace
     $this->reset();
     // Load a bundle different from TEST_UNINSTALLED_PACKAGE
     $this->bundle = $this->assigner->loadBundle('test_mybundle');
     $this->assigner->applyAssignmentMethod('packages');
     $packages = $this->featuresManager->getPackages();
     $this->assertNotEmpty($packages[self::TEST_UNINSTALLED_PACKAGE], 'Expected test_feature package not created.');
     $this->assertNotEmpty($packages[self::TEST_INSTALLED_PACKAGE], 'Expected test_mybundle_core package not created.');
     // Mark package as uninstalled, set "Required" set to False
     $packages[self::TEST_UNINSTALLED_PACKAGE]->setRequired(false);
     $this->featuresManager->setPackages($packages);
     $this->assigner->applyAssignmentMethod('exclude');
     $this->assigner->applyAssignmentMethod('core');
     $this->assigner->applyAssignmentMethod('existing');
     $packages = $this->featuresManager->getPackages();
     $this->assertFalse(array_key_exists('core', $packages), 'Core package should not be created.');
     $expected_config_items = ['core.date_format.short', 'system.cron'];
     $this->assertEquals($expected_config_items, $packages[self::TEST_UNINSTALLED_PACKAGE]->getConfig(), 'Expected configuration items not present in existing test_feature package.');
     // 4. When Required is set to False and module is NOT installed,
     // Config is reassigned within modules that match the namespace.
     $this->reset();
     // Load the bundle used in TEST_UNINSTALLED_PACKAGE
     $this->bundle = $this->assigner->loadBundle('test');
     if (empty($this->bundle) || $this->bundle->isDefault()) {
         // Since we uninstalled the test_feature, we probably need to create
         // an empty "test" bundle
         $this->bundle = $this->assigner->createBundleFromDefault('test');
     }
     $this->assigner->applyAssignmentMethod('packages');
     $packages = $this->featuresManager->getPackages();
     $this->assertNotEmpty($packages[self::TEST_UNINSTALLED_PACKAGE], 'Expected test_feature package not created.');
     // Set "Required" set to False
     $packages[self::TEST_UNINSTALLED_PACKAGE]->setRequired(false);
     $this->featuresManager->setPackages($packages);
     $this->assigner->applyAssignmentMethod('exclude');
     $this->assigner->applyAssignmentMethod('core');
     $this->assigner->applyAssignmentMethod('existing');
     $packages = $this->featuresManager->getPackages();
     $this->assertNotEmpty($packages['core'], 'Expected Core package not created.');
     // Ensure "core" package is not confused with "test_core" module
     // Since we are in a bundle
     $this->assertEmpty($packages['core']->getExtension(), 'Autogenerated core package should not have an extension');
     // Core config should be reassigned from TEST_UNINSTALLED_PACKAGE into Core
     $expected_config_items = ['system.cron'];
     $this->assertEquals($expected_config_items, $packages[self::TEST_UNINSTALLED_PACKAGE]->getConfig(), 'Expected configuration items not present in existing test_feature package.');
     $expected_config_items = ['core.date_format.short'];
     $this->assertEquals($expected_config_items, $packages['core']->getConfig(), 'Expected configuration items not present in core package.');
 }