config.inc 6.55 KB
Newer Older
chx's avatar
chx committed
1 2
<?php

gdd's avatar
gdd committed
3 4
use Drupal\Core\Config\DrupalVerifiedStorageSQL;

gdd's avatar
gdd committed
5 6 7 8 9
/**
 * @file
 * This is the API for configuration storage.
 */

10
/**
11
 * Gets the randomly generated config directory name.
12 13 14 15
 *
 * @return
 *   The directory name.
 */
16
function config_get_config_directory() {
17
  global $config_directory_name;
18

19 20 21 22 23 24 25
  if ($test_prefix = drupal_valid_test_ua()) {
    $path = conf_path() . '/files/simpletest/config_' . $test_prefix;
  }
  else {
    $path = conf_path() . '/files/' . $config_directory_name;
  }
  return $path;
26 27
}

28
/**
29
 * Moves the default config supplied by a module to the live config directory.
30 31 32
 *
 * @param
 *   The name of the module we are installing.
gdd's avatar
gdd committed
33 34 35
 *
 * @todo Make this acknowledge other storage engines rather than having
 *   SQL be hardcoded.
36 37 38 39 40 41
 */
function config_install_default_config($module) {
  $module_config_dir = drupal_get_path('module', $module) . '/config';
  $drupal_config_dir = config_get_config_directory();
  if (is_dir(drupal_get_path('module', $module) . '/config')) {
    $files = glob($module_config_dir . '/' . '*.xml');
42 43
    foreach ($files as $key => $file) {
      // Load config data into the active store and write it out to the
44 45 46 47 48 49 50 51 52
      // file system in the drupal config directory. Note the config name
      // needs to be the same as the file name WITHOUT the extension.
      $parts = explode('/', $file);
      $file = array_pop($parts);
      $config_name = str_replace('.xml', '', $file);

      $verified_storage = new DrupalVerifiedStorageSQL($config_name);
      $verified_storage->write(file_get_contents($module_config_dir . '/' . $file));
    }
53
  }
54 55
}

56
/**
57
 * Retrieves an iterable array which lists the children under a config 'branch'.
gdd's avatar
gdd committed
58 59
 *
 * Given the following configuration files:
60 61
 * - core.entity.node_type.article.xml
 * - core.entity.node_type.page.xml
gdd's avatar
gdd committed
62 63
 *
 * You can pass a prefix 'core.entity.node_type' and get back an array of the
sun's avatar
sun committed
64
 * filenames that match. This allows you to iterate through all files in a
xjm's avatar
xjm committed
65
 * branch.
gdd's avatar
gdd committed
66 67 68
 *
 * @param $prefix
 *   The prefix of the files we are searching for.
69
 *
70
 * @return
gdd's avatar
gdd committed
71
 *   An array of file names under a branch.
72 73
 */
function config_get_signed_file_storage_names_with_prefix($prefix = '') {
74
  $files = glob(config_get_config_directory() . '/' . $prefix . '*.xml');
75
  $clean_name = function ($value) {
76
    return basename($value, '.xml');
77
  };
78
  return array_map($clean_name, $files);
79 80
}

gdd's avatar
gdd committed
81
/**
82
 * Generates a hash of a config file's contents using our encryption key.
sun's avatar
sun committed
83
 *
gdd's avatar
gdd committed
84 85
 * @param $data
 *   The contents of a configuration file.
86
 *
gdd's avatar
gdd committed
87 88 89
 * @return
 *   A hash of the data.
 */
90
function config_sign_data($data) {
91
  // The configuration key is loaded from settings.php and imported into the global namespace
92
  global $config_signature_key;
93

chx's avatar
chx committed
94
  // SHA-512 is both secure and very fast on 64 bit CPUs.
95
  return hash_hmac('sha512', $data, $config_signature_key);
96 97
}

98 99 100 101 102 103 104 105 106
/**
 * @todo
 *
 * @param $prefix
 *   @todo
 *
 * @return
 *   @todo
 */
107 108 109 110
function config_get_verified_storage_names_with_prefix($prefix = '') {
  return DrupalVerifiedStorageSQL::getNamesWithPrefix($prefix);
}

Katherine Senzee's avatar
Katherine Senzee committed
111
/**
112
 * Retrieves a configuration object.
Katherine Senzee's avatar
Katherine Senzee committed
113 114 115 116 117 118 119 120 121 122 123 124
 *
 * This is the main entry point to the configuration API. Calling
 * @code config(book.admin) @endcode will return a configuration object in which
 * the book module can store its administrative settings.
 *
 * @param $name
 *   The name of the configuration object to retrieve. The name corresponds to
 *   an XML configuration file. For @code config(book.admin) @endcode, the
 *   config object returned will contain the contents of book.admin.xml.
 * @param $class
 *   The class name of the config object to be returned. Defaults to
 *   DrupalConfig.
125
 *
Katherine Senzee's avatar
Katherine Senzee committed
126 127 128
 * @return
 *   An instance of the class specified in the $class parameter.
 *
gdd's avatar
gdd committed
129
 * @todo Replace this with an appropriate factory / ability to inject in
xjm's avatar
xjm committed
130
 *   alternate storage engines..
Katherine Senzee's avatar
Katherine Senzee committed
131
 */
gdd's avatar
gdd committed
132
function config($name, $class = 'Drupal\Core\Config\DrupalConfig') {
133
  return new $class(new DrupalVerifiedStorageSQL($name));
134 135 136
}

/**
137
 * Decodes configuration data from its native format to an associative array.
138 139
 *
 * @param $data
140 141
 *   Configuration data.
 *
142 143 144 145 146 147 148
 * @return
 *   An associative array representation of the data.
 */
function config_decode($data) {
  if (empty($data)) {
    return array();
  }
149 150 151 152

  // This is the fastest and easiest way to get from a string of XML to a PHP
  // array since SimpleXML and json_decode()/encode() are native to PHP. Our
  // only other choice would be a custom userspace implementation which would
xjm's avatar
xjm committed
153
  // be a lot less performant and more complex.
154 155
  $xml = new SimpleXMLElement($data);
  $json = json_encode($xml);
156
  return json_decode($json, TRUE);
157 158 159
}

/**
160
 * Standardizes SimpleXML object output into simple arrays for easier use.
gdd's avatar
gdd committed
161 162
 *
 * @param $xmlObject
163
 *   A valid XML string.
164 165
 *
 * @return
166
 *   An array representation of A SimpleXML object.
167
 */
gdd's avatar
gdd committed
168 169 170
function config_xml_to_array($data) {
  $out = array();
  $xmlObject = simplexml_load_string($data);
171

gdd's avatar
gdd committed
172
  if (is_object($xmlObject)) {
173
    $attributes = (array) $xmlObject->attributes();
gdd's avatar
gdd committed
174 175 176 177
    if (isset($attributes['@attributes'])) {
      $out['#attributes'] = $attributes['@attributes'];
    }
  }
178 179
  if (trim((string) $xmlObject)) {
    return trim((string) $xmlObject);
gdd's avatar
gdd committed
180 181 182
  }
  foreach ($xmlObject as $index => $content) {
    if (is_object($content)) {
183
      $out[$index] = config_xml_to_array($content);
gdd's avatar
gdd committed
184 185 186 187
    }
  }

  return $out;
188 189 190
}

/**
191
 * Encodes an array into the native configuration format.
192 193 194
 *
 * @param $data
 *   An associative array or an object
195
 *
196 197
 * @return
 *   A representation of this array or object in the native configuration
sun's avatar
sun committed
198
 *   format.
gdd's avatar
gdd committed
199 200 201
 *
 * @todo The loaded XML can be invalid; throwing plenty of PHP warnings but no
 *   catchable error.
202
 */
gdd's avatar
gdd committed
203
function config_encode($data) {
gdd's avatar
gdd committed
204
  // Convert the supplied array into a SimpleXMLElement.
gdd's avatar
gdd committed
205 206 207
  $xml_object = new SimpleXMLElement("<?xml version=\"1.0\"?><config></config>");
  config_array_to_xml($data, $xml_object);

gdd's avatar
gdd committed
208
  // Pretty print the result.
gdd's avatar
gdd committed
209 210 211 212
  $dom = new DOMDocument('1.0');
  $dom->preserveWhiteSpace = false;
  $dom->formatOutput = true;
  $dom->loadXML($xml_object->asXML());
gdd's avatar
gdd committed
213

gdd's avatar
gdd committed
214 215
  return $dom->saveXML();
}
gdd's avatar
gdd committed
216

gdd's avatar
gdd committed
217
/**
218
 * Encodes an array into XML
gdd's avatar
gdd committed
219 220 221
 *
 * @param $data
 *   An associative array or an object
222
 *
gdd's avatar
gdd committed
223 224
 * @return
 *   A representation of this array or object in the native configuration
sun's avatar
sun committed
225
 *   format.
gdd's avatar
gdd committed
226 227 228 229 230 231 232 233 234 235 236
 */
function config_array_to_xml($array, &$xml_object) {
  foreach ($array as $key => $value) {
    if (is_array($value)) {
      if (!is_numeric($key)){
        $subnode = $xml_object->addChild("$key");
        config_array_to_xml($value, $subnode);
      }
      else {
        config_array_to_xml($value, $xml_object);
      }
Katherine Senzee's avatar
Katherine Senzee committed
237
    }
gdd's avatar
gdd committed
238
    else {
239
      $xml_object->addChild($key, $value);
gdd's avatar
gdd committed
240 241
    }
  }
242
}