You are here

class FeaturesInstallStorage in Features 8.4

Same name and namespace in other branches
  1. 8.3 src/FeaturesInstallStorage.php \Drupal\features\FeaturesInstallStorage

Storage to access configuration and schema in installed extensions.

Overrides the normal ExtensionInstallStorage to prevent profile from overriding.

Also supports modules that are not installed yet.

Hierarchy

Expanded class hierarchy of FeaturesInstallStorage

See also

\Drupal\Core\Config\ExtensionInstallStorage

1 string reference to 'FeaturesInstallStorage'
features.services.yml in ./features.services.yml
features.services.yml
2 services use FeaturesInstallStorage
features.extension_optional_storage in ./features.services.yml
Drupal\features\FeaturesInstallStorage
features.extension_storage in ./features.services.yml
Drupal\features\FeaturesInstallStorage

File

src/FeaturesInstallStorage.php, line 20

Namespace

Drupal\features
View source
class FeaturesInstallStorage extends ExtensionInstallStorage {

  /**
   * Overrides \Drupal\Core\Config\ExtensionInstallStorage::__construct().
   *
   * Sets includeProfile to FALSE.
   *
   * @param \Drupal\Core\Config\StorageInterface $config_storage
   *   The active configuration store where the list of enabled modules and
   *   themes is stored.
   * @param string $directory
   *   The directory to scan in each extension to scan for files. Defaults to
   *   'config/install'. This parameter will be mandatory in Drupal 9.0.0.
   * @param string $collection
   *   (optional) The collection to store configuration in. Defaults to the
   *   default collection. This parameter will be mandatory in Drupal 9.0.0.
   * @param bool $include_profile
   *   (optional) Whether to include the install profile in extensions to
   *   search and to get overrides from. This parameter will be mandatory in
   *   Drupal 9.0.0.
   * @param string|null $profile
   *   (optional) The current installation profile. This parameter will be
   *   mandatory in Drupal 9.0.0.
   */
  public function __construct(StorageInterface $config_storage, $directory = self::CONFIG_INSTALL_DIRECTORY, $collection = StorageInterface::DEFAULT_COLLECTION, $include_profile = TRUE, $profile = NULL) {

    // @todo: determine if we should be setting $include_profile to FALSE.
    parent::__construct($config_storage, $directory, $collection, FALSE, $profile);
  }

  /**
   * Returns a map of all config object names and their folders.
   *
   * The list is based on installed modules and themes. The active
   * configuration storage is used rather than
   * \Drupal\Core\Extension\ModuleHandler and
   * \Drupal\Core\Extension\ThemeHandler in order to resolve circular
   * dependencies between these services and
   * \Drupal\Core\Config\ConfigInstaller and
   * \Drupal\Core\Config\TypedConfigManager.
   *
   * NOTE: This code is copied from ExtensionInstallStorage::getAllFolders()
   * with the following changes (Notes in CHANGED below)
   *   - Load all modules whether installed or not
   *
   * @return array
   *   An array mapping config object names with directories.
   */
  public function getAllFolders() {

    // @todo: update to bring in upstream changes from the method this was
    // forked from.
    if (!isset($this->folders)) {
      $this->folders = [];
      $this->folders += $this
        ->getCoreNames();
      $install_profile = Settings::get('install_profile');
      $profile = $this->installProfile;
      $extensions = $this->configStorage
        ->read('core.extension');

      // @todo Remove this scan as part of https://www.drupal.org/node/2186491
      $listing = new ExtensionDiscovery(\Drupal::root());

      // CHANGED START: Add profile directories for any bundles that use a
      // profile.
      $listing
        ->setProfileDirectoriesFromSettings();
      $profile_directories = $listing
        ->getProfileDirectories();
      if ($this->includeProfile) {

        // Add any profiles used in bundles.

        /** @var \Drupal\features\FeaturesAssignerInterface $assigner */
        $assigner = \Drupal::service('features_assigner');
        $bundles = $assigner
          ->getBundleList();
        foreach ($bundles as $bundle_name => $bundle) {
          if ($bundle
            ->isProfile()) {

            // Register the profile directory.
            $profile_directory = 'profiles/' . $bundle
              ->getProfileName();
            if (is_dir($profile_directory)) {
              $profile_directories[] = $profile_directory;
            }
          }
        }
      }
      $listing
        ->setProfileDirectories($profile_directories);

      // CHANGED END.
      if (!empty($extensions['module'])) {

        // CHANGED START: Find ANY modules, not just installed ones.
        // $modules = $extensions['module'];.
        $module_list_scan = $listing
          ->scan('module');
        $modules = $module_list_scan;

        // CHANGED END.
        // Remove the install profile as this is handled later.
        unset($modules[$install_profile]);
        $profile_list = $listing
          ->scan('profile');
        if ($profile && isset($profile_list[$profile])) {

          // Prime the drupal_get_filename() static cache with the profile info
          // file location so we can use drupal_get_path() on the active profile
          // during the module scan.
          // @todo Remove as part of https://www.drupal.org/node/2186491
          drupal_get_filename('profile', $profile, $profile_list[$profile]
            ->getPathname());
        }

        // CHANGED START: Put Features modules first in list returned.
        // to allow features to override config provided by other extensions.
        $featuresManager = \Drupal::service('features.manager');
        $features_list = [];
        $module_list = [];
        foreach (array_keys($module_list_scan) as $module) {
          if ($featuresManager
            ->isFeatureModule($module_list_scan[$module])) {
            $features_list[$module] = $module_list_scan[$module];
          }
          else {
            $module_list[$module] = $module_list_scan[$module];
          }
        }
        $this->folders += $this
          ->getComponentNames($features_list);
        $this->folders += $this
          ->getComponentNames($module_list);

        // CHANGED END.
      }
      if (!empty($extensions['theme'])) {
        $theme_list_scan = $listing
          ->scan('theme');
        foreach (array_keys($extensions['theme']) as $theme) {
          if (isset($theme_list_scan[$theme])) {
            $theme_list[$theme] = $theme_list_scan[$theme];
          }
        }
        $this->folders += $this
          ->getComponentNames($theme_list);
      }
      if ($this->includeProfile) {

        // The install profile can override module default configuration. We do
        // this by replacing the config file path from the module/theme with the
        // install profile version if there are any duplicates.
        if (isset($profile)) {
          if (!isset($profile_list)) {
            $profile_list = $listing
              ->scan('profile');
          }
          if (isset($profile_list[$profile])) {
            $profile_folders = $this
              ->getComponentNames([
              $profile_list[$profile],
            ]);
            $this->folders = $profile_folders + $this->folders;
          }
        }
      }
    }
    return $this->folders;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ExtensionInstallStorage::$configStorage protected property The active configuration store.
ExtensionInstallStorage::$includeProfile protected property Flag to include the profile in the list of enabled modules.
ExtensionInstallStorage::$installProfile protected property The name of the currently active installation profile.
ExtensionInstallStorage::createCollection public function Creates a collection on the storage. Overrides FileStorage::createCollection
FeaturesInstallStorage::getAllFolders public function Returns a map of all config object names and their folders. Overrides ExtensionInstallStorage::getAllFolders
FeaturesInstallStorage::__construct public function Overrides \Drupal\Core\Config\ExtensionInstallStorage::__construct(). Overrides ExtensionInstallStorage::__construct
FileStorage::$collection protected property The storage collection.
FileStorage::$fileCache protected property The file cache object.
FileStorage::decode public function Decodes configuration data from the storage-specific format. Overrides StorageInterface::decode
FileStorage::encode public function Encodes configuration data into the storage-specific format. Overrides StorageInterface::encode
FileStorage::ensureStorage protected function Check if the directory exists and create it if not.
FileStorage::getAllCollectionNames public function Gets the existing collections. Overrides StorageInterface::getAllCollectionNames
FileStorage::getAllCollectionNamesHelper protected function Helper function for getAllCollectionNames().
FileStorage::getCollectionDirectory protected function Gets the directory for the collection.
FileStorage::getCollectionName public function Gets the name of the current collection the storage is using. Overrides StorageInterface::getCollectionName
FileStorage::getFileExtension public static function Returns the file extension used by the file storage for all configuration files.
FileStorage::getFileSystem private function Returns file system service.
FileStorage::read public function Implements Drupal\Core\Config\StorageInterface::read(). Overrides StorageInterface::read
FileStorage::readMultiple public function Reads configuration data from the storage. Overrides StorageInterface::readMultiple
InstallStorage::$directory protected property The directory to scan in each extension to scan for files. Overrides FileStorage::$directory
InstallStorage::$folders protected property Folder map indexed by configuration name.
InstallStorage::CONFIG_INSTALL_DIRECTORY constant Extension sub-directory containing default configuration for installation.
InstallStorage::CONFIG_OPTIONAL_DIRECTORY constant Extension sub-directory containing optional configuration for installation.
InstallStorage::CONFIG_SCHEMA_DIRECTORY constant Extension sub-directory containing configuration schema.
InstallStorage::delete public function Overrides Drupal\Core\Config\FileStorage::delete(). Overrides FileStorage::delete
InstallStorage::deleteAll public function Overrides Drupal\Core\Config\FileStorage::deleteAll(). Overrides FileStorage::deleteAll
InstallStorage::exists public function Returns whether a configuration object exists. Overrides FileStorage::exists
InstallStorage::getComponentFolder protected function Get folder inside each component that contains the files.
InstallStorage::getComponentNames public function Get all configuration names and folders for a list of modules or themes.
InstallStorage::getCoreFolder protected function Get folder inside Drupal core that contains the files.
InstallStorage::getCoreNames public function Get all configuration names and folders for Drupal core.
InstallStorage::getFilePath public function Overrides Drupal\Core\Config\FileStorage::getFilePath(). Overrides FileStorage::getFilePath
InstallStorage::listAll public function Gets configuration object names starting with a given prefix. Overrides FileStorage::listAll
InstallStorage::rename public function Overrides Drupal\Core\Config\FileStorage::rename(). Overrides FileStorage::rename
InstallStorage::reset public function Resets the static cache.
InstallStorage::write public function Overrides Drupal\Core\Config\FileStorage::write(). Overrides FileStorage::write
StorageInterface::DEFAULT_COLLECTION constant The default collection name.