InstallStorage.php 5.78 KB
Newer Older
1 2 3 4 5 6 7 8 9
<?php

/**
 * @file
 * Contains Drupal\Core\Config\InstallStorage.
 */

namespace Drupal\Core\Config;

10 11
use Drupal\Core\Extension\ExtensionDiscovery;

12
/**
13
 * Storage used by the Drupal installer.
14
 *
15 16 17 18 19 20 21
 * This storage performs a full filesystem scan to discover all available
 * extensions and reads from all default config directories that exist.
 *
 * This special implementation MUST NOT be used anywhere else than the early
 * installer environment.
 *
 * @see \Drupal\Core\DependencyInjection\InstallServiceProvider
22 23 24
 */
class InstallStorage extends FileStorage {

25 26 27 28 29 30 31
  /**
   * Folder map indexed by configuration name.
   *
   * @var array
   */
  protected $folders;

32
  /**
33 34 35
   * The directory to scan in each extension to scan for files.
   *
   * @var string
36
   */
37 38 39 40 41 42 43 44 45 46 47
  protected $directory;

  /**
   * Constructs an InstallStorage object.
   *
   * @param string $directory
   *   The directory to scan in each extension to scan for files. Defaults to
   *   'config'.
   */
  public function __construct($directory = 'config') {
    $this->directory = $directory;
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
  }

  /**
   * Overrides Drupal\Core\Config\FileStorage::getFilePath().
   *
   * Returns the path to the configuration file.
   *
   * Determines the owner and path to the default configuration file of a
   * requested config object name located in the installation profile, a module,
   * or a theme (in this order).
   *
   * @return string
   *   The path to the configuration file.
   *
   * @todo Improve this when figuring out how we want to handle configuration in
   *   installation profiles. E.g., a config object actually has to be searched
   *   in the profile first (whereas the profile is never the owner), only
   *   afterwards check for a corresponding module or theme.
   */
  public function getFilePath($name) {
68 69 70
    $folders = $this->getAllFolders();
    if (isset($folders[$name])) {
      return $folders[$name] . '/' . $name . '.' . $this->getFileExtension();
71 72 73 74 75 76 77 78
    }
    // If any code in the early installer requests a configuration object that
    // does not exist anywhere as default config, then that must be mistake.
    throw new StorageException(format_string('Missing configuration file: @name', array(
      '@name' => $name,
    )));
  }

79 80 81 82 83 84 85
  /**
   * {@inheritdoc}
   */
  public function exists($name) {
    return array_key_exists($name, $this->getAllFolders());
  }

86 87 88
  /**
   * Overrides Drupal\Core\Config\FileStorage::write().
   *
89
   * @throws \Drupal\Core\Config\StorageException
90 91
   */
  public function write($name, array $data) {
92
    throw new StorageException('Write operation is not allowed.');
93 94 95 96 97
  }

  /**
   * Overrides Drupal\Core\Config\FileStorage::delete().
   *
98
   * @throws \Drupal\Core\Config\StorageException
99 100
   */
  public function delete($name) {
101
    throw new StorageException('Delete operation is not allowed.');
102 103 104 105 106
  }

  /**
   * Overrides Drupal\Core\Config\FileStorage::rename().
   *
107
   * @throws \Drupal\Core\Config\StorageException
108 109
   */
  public function rename($name, $new_name) {
110
    throw new StorageException('Rename operation is not allowed.');
111 112 113 114 115 116
  }

  /**
   * Implements Drupal\Core\Config\StorageInterface::listAll().
   */
  public function listAll($prefix = '') {
117 118 119 120 121 122 123 124 125
    $names = array_keys($this->getAllFolders());
    if (!$prefix) {
      return $names;
    }
    else {
      $return = array();
      foreach ($names as $index => $name) {
        if (strpos($name, $prefix) === 0 ) {
          $return[$index] = $names[$index];
126 127
        }
      }
128
      return $return;
129
    }
130
  }
131

132 133 134 135 136 137 138 139
  /**
   * Returns a map of all config object names and their folders.
   *
   * @return array
   *   An array mapping config object names with directories.
   */
  protected function getAllFolders() {
    if (!isset($this->folders)) {
140
      $this->folders = array();
141
      $this->folders += $this->getComponentNames('core', array('core'));
142 143 144 145 146 147 148
      // @todo Refactor getComponentNames() to use the extension list directly.
      if ($profile = drupal_get_profile()) {
        $this->folders += $this->getComponentNames('profile', array($profile));
      }
      $listing = new ExtensionDiscovery();
      $this->folders += $this->getComponentNames('module', array_keys($listing->scan('module')));
      $this->folders += $this->getComponentNames('theme', array_keys($listing->scan('theme')));
149
    }
150 151
    return $this->folders;
  }
152

153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
  /**
   * Get all configuration names and folders for a list of modules or themes.
   *
   * @param string $type
   *   Type of components: 'module' | 'theme' | 'profile'
   * @param array $list
   *   Array of theme or module names.
   *
   * @return array
   *   Folders indexed by configuration name.
   */
  public function getComponentNames($type, array $list) {
    $extension = '.' . $this->getFileExtension();
    $folders = array();
    foreach ($list as $name) {
      $directory = $this->getComponentFolder($type, $name);
      if (file_exists($directory)) {
170 171 172
        $files = new \GlobIterator(DRUPAL_ROOT . '/' . $directory . '/*' . $extension);
        foreach ($files as $file) {
          $folders[$file->getBasename($extension)] = $directory;
173 174 175
        }
      }
    }
176 177
    return $folders;
  }
178

179 180 181 182 183 184 185 186 187 188 189 190
  /**
   * Get folder inside each component that contains the files.
   *
   * @param string $type
   *   Component type: 'module' | 'theme' | 'profile'
   * @param string $name
   *   Component name.
   *
   * @return string
   *   The configuration folder name for this component.
   */
  protected function getComponentFolder($type, $name) {
191
    return drupal_get_path($type, $name) . '/' . $this->directory;
192
  }
193 194 195 196

  /**
   * Overrides Drupal\Core\Config\FileStorage::deleteAll().
   *
197
   * @throws \Drupal\Core\Config\StorageException
198 199
   */
  public function deleteAll($prefix = '') {
200 201 202 203 204 205 206 207
    throw new StorageException('Delete operation is not allowed.');
  }

  /**
   * Resets the static cache.
   */
  public function reset() {
    $this->folders = NULL;
208 209
  }

210
}