You are here

FeaturesAssignmentProfile.php in Features 8.4

Same filename and directory in other branches
  1. 8.3 src/Plugin/FeaturesAssignment/FeaturesAssignmentProfile.php

File

src/Plugin/FeaturesAssignment/FeaturesAssignmentProfile.php
View source
<?php

namespace Drupal\features\Plugin\FeaturesAssignment;

use Drupal\features\FeaturesAssignmentMethodBase;
use Drupal\Component\Serialization\Yaml;
use Drupal\Core\Config\InstallStorage;

/**
 * Class for adding configuration for the optional install profile.
 *
 * @Plugin(
 *   id = "profile",
 *   weight = 10,
 *   name = @Translation("Profile"),
 *   description = @Translation("Add configuration and other files to the optional install profile from the Drupal core Standard install profile. Without these additions, a generated install profile will be missing some important initial setup."),
 *   config_route_name = "features.assignment_profile",
 *   default_settings = {
 *     "curated" = FALSE,
 *     "standard" = {
 *       "files" = FALSE,
 *       "dependencies" = FALSE,
 *     },
 *     "types" = { "config" = {} }
 *   }
 * )
 */
class FeaturesAssignmentProfile extends FeaturesAssignmentMethodBase {

  /**
   * {@inheritdoc}
   */
  public function assignPackages($force = FALSE) {
    $current_bundle = $this->assigner
      ->getBundle();
    if ($current_bundle
      ->isProfile()) {
      $settings = $current_bundle
        ->getAssignmentSettings($this
        ->getPluginId());

      // Ensure the profile package exists.
      $profile_name = $current_bundle
        ->getProfileName();
      $profile_package = $this->featuresManager
        ->getPackage($profile_name);
      if (empty($profile_package)) {
        $profile_package = $this->featuresManager
          ->initPackage($profile_name, $current_bundle
          ->getName(), $current_bundle
          ->getDescription(), 'profile', $current_bundle);
      }

      // Assign configuration by type.
      $this
        ->assignPackageByConfigTypes($profile_name, $force);

      // Include a curated list of configuration.
      if ($settings['curated']) {
        $config_collection = $this->featuresManager
          ->getConfigCollection();
        $item_names = [
          'automated_cron.settings',
          'system.cron',
          'system.theme',
        ];
        $theme_settings = $this->configFactory
          ->get('system.theme');
        foreach ([
          'default',
          'admin',
        ] as $key) {
          $item_names[] = $theme_settings
            ->get($key) . '.settings';
        }
        foreach ($item_names as $item_name) {
          if (isset($config_collection[$item_name])) {
            try {
              $this->featuresManager
                ->assignConfigPackage($profile_name, [
                $item_name,
              ]);
            } catch (\Exception $exception) {
              \Drupal::logger('features')
                ->error($exception
                ->getMessage());
            }
          }
        }
      }

      // Only read in from the Standard profile if this profile doesn't already
      // exist.
      $package_directories = $this->featuresManager
        ->listPackageDirectories([], $current_bundle);
      if (!isset($package_directories[$profile_name])) {
        $standard_directory = 'core/profiles/standard';

        // Conditionally add files from the 'standard' install profile.
        if ($settings['standard']['files']) {

          // Add configuration from the Standard profile.
          $config_collection = $this->featuresManager
            ->getConfigCollection();
          $subdirectory = InstallStorage::CONFIG_INSTALL_DIRECTORY;
          $item_names = $this
            ->listRequiredStandardConfig();
          foreach ($item_names as $item_name) {

            // If the configuration is present on the site, assign it.
            if (isset($config_collection[$item_name])) {

              // Only assign it if it's not already assigned to a package.
              // @todo: if it's provided by a module, add a dependency.
              if (!$config_collection[$item_name]
                ->getPackage()) {
                $this->featuresManager
                  ->assignConfigPackage($profile_name, [
                  $item_name,
                ], $force);

                // Reload the profile to refresh the config array after the
                // addition.
                $profile_package = $this->featuresManager
                  ->getPackage($profile_name);
              }
              else {
                $machine_name = $current_bundle
                  ->getFullName($config_collection[$item_name]
                  ->getPackage());
                if (!in_array($machine_name, $profile_package
                  ->getDependencies())) {
                  $profile_package
                    ->appendDependency($machine_name);
                }
              }
            }
            else {
              $filename = $item_name . '.yml';
              $profile_package
                ->appendFile([
                'filename' => $filename,
                'subdirectory' => $subdirectory,
                'string' => file_get_contents($standard_directory . '/' . $subdirectory . '/' . $filename),
              ]);
            }
          }

          // Add .profile and .install files from Standard.
          $files = [
            'install',
            'profile',
          ];

          // Iterate through the files.
          foreach ($files as $extension) {
            $filename = $standard_directory . '/standard.' . $extension;
            if (file_exists($filename)) {

              // Read the file contents.
              $string = file_get_contents($filename);

              // Substitute the profile's machine name and name for the Standard
              // profile's equivalents.
              $string = str_replace([
                'standard',
                'Standard',
              ], [
                $profile_name,
                $current_bundle
                  ->getName(),
              ], $string);

              // Add the files to those to be output.
              $profile_package
                ->appendFile([
                'filename' => $profile_name . '.' . $extension,
                'subdirectory' => NULL,
                'string' => $string,
              ], $extension);
            }
          }
        }

        // Conditionally merge in module and theme dependencies from the
        // 'standard' install profile.
        if ($settings['standard']['dependencies']) {
          $info_file_uri = $standard_directory . '/standard.info.yml';
          if (file_exists($info_file_uri)) {
            $profile_info = Yaml::decode(file_get_contents($info_file_uri));
            $info = [
              'dependencies' => $profile_package
                ->getDependencies(),
              'themes' => $profile_package
                ->getThemes(),
            ];
            $info = $this->featuresManager
              ->mergeInfoArray($info, $profile_info);
            $profile_package
              ->setDependencies($info['dependencies']);
            $profile_package
              ->setThemes($info['themes']);
          }
        }
        $this->featuresManager
          ->setPackage($profile_package);
      }
    }
  }

  /**
   * Returns the list of configuration items required by the Standard install
   * profile.
   *
   * If install code is adapted from the Standard profile, these configuration
   * items will be required.
   *
   * @return array
   *   An array of configuration item names.
   */
  protected function listRequiredStandardConfig() {
    return [
      'contact.form.feedback',
      'user.role.administrator',
    ];
  }

}

Classes

Namesort descending Description
FeaturesAssignmentProfile Class for adding configuration for the optional install profile.